nautobot 2.3.14__py3-none-any.whl → 2.3.15__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 (303) hide show
  1. nautobot/core/settings.py +3 -0
  2. nautobot/core/settings.yaml +8 -0
  3. nautobot/core/templates/inc/media.html +3 -0
  4. nautobot/core/templates/nautobot_config.py.j2 +3 -0
  5. nautobot/core/testing/mixins.py +7 -2
  6. nautobot/core/tests/integration/test_app_home.py +0 -1
  7. nautobot/core/tests/integration/test_app_navbar.py +0 -1
  8. nautobot/core/tests/integration/test_filters.py +0 -2
  9. nautobot/core/tests/integration/test_home.py +0 -1
  10. nautobot/core/tests/integration/test_navbar.py +0 -1
  11. nautobot/core/tests/integration/test_view_authentication.py +1 -0
  12. nautobot/core/tests/test_views.py +29 -0
  13. nautobot/core/urls.py +9 -0
  14. nautobot/extras/forms/mixins.py +1 -1
  15. nautobot/extras/models/customfields.py +12 -11
  16. nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
  17. nautobot/extras/tests/test_forms.py +20 -1
  18. nautobot/ipam/api/views.py +17 -15
  19. nautobot/ipam/tests/test_api.py +334 -1
  20. nautobot/project-static/docs/404.html +2 -2
  21. nautobot/project-static/docs/apps/index.html +2 -2
  22. nautobot/project-static/docs/apps/nautobot-apps.html +2 -2
  23. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
  24. nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
  25. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +2 -2
  26. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +2 -2
  27. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2 -2
  28. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +2 -2
  29. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +2 -2
  30. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +2 -2
  31. nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +2 -2
  32. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +2 -2
  33. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +2 -2
  34. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +2 -2
  35. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2 -2
  36. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2 -2
  37. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +2 -2
  38. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2 -2
  39. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2 -2
  40. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +2 -2
  41. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +2 -2
  42. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +2 -2
  43. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +11 -4
  44. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2 -2
  45. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +2 -2
  46. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2 -2
  47. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2 -2
  48. nautobot/project-static/docs/development/apps/api/configuration-view.html +2 -2
  49. nautobot/project-static/docs/development/apps/api/database-backend-config.html +2 -2
  50. nautobot/project-static/docs/development/apps/api/models/django-admin.html +2 -2
  51. nautobot/project-static/docs/development/apps/api/models/global-search.html +2 -2
  52. nautobot/project-static/docs/development/apps/api/models/graphql.html +2 -2
  53. nautobot/project-static/docs/development/apps/api/models/index.html +2 -2
  54. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +2 -2
  55. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +2 -2
  56. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +2 -2
  57. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +2 -2
  58. nautobot/project-static/docs/development/apps/api/platform-features/index.html +2 -2
  59. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +2 -2
  60. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +2 -2
  61. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +2 -2
  62. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +2 -2
  63. nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +2 -2
  64. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +2 -2
  65. nautobot/project-static/docs/development/apps/api/prometheus.html +2 -2
  66. nautobot/project-static/docs/development/apps/api/setup.html +2 -2
  67. nautobot/project-static/docs/development/apps/api/testing.html +2 -2
  68. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +2 -2
  69. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +2 -2
  70. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +2 -2
  71. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +2 -2
  72. nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +2 -2
  73. nautobot/project-static/docs/development/apps/api/views/base-template.html +2 -2
  74. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +2 -2
  75. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +2 -2
  76. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +2 -2
  77. nautobot/project-static/docs/development/apps/api/views/index.html +2 -2
  78. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +2 -2
  79. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +2 -2
  80. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +2 -2
  81. nautobot/project-static/docs/development/apps/api/views/notes.html +2 -2
  82. nautobot/project-static/docs/development/apps/api/views/rest-api.html +2 -2
  83. nautobot/project-static/docs/development/apps/api/views/urls.html +2 -2
  84. nautobot/project-static/docs/development/apps/index.html +2 -2
  85. nautobot/project-static/docs/development/apps/migration/code-updates.html +2 -2
  86. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +2 -2
  87. nautobot/project-static/docs/development/apps/migration/from-v1.html +2 -2
  88. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +2 -2
  89. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +2 -2
  90. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +2 -2
  91. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +2 -2
  92. nautobot/project-static/docs/development/apps/porting-from-netbox.html +2 -2
  93. nautobot/project-static/docs/development/core/application-registry.html +2 -2
  94. nautobot/project-static/docs/development/core/best-practices.html +2 -2
  95. nautobot/project-static/docs/development/core/bootstrap-ui.html +2 -2
  96. nautobot/project-static/docs/development/core/caching.html +2 -2
  97. nautobot/project-static/docs/development/core/controllers.html +2 -2
  98. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +27 -70
  99. nautobot/project-static/docs/development/core/generic-views.html +2 -2
  100. nautobot/project-static/docs/development/core/getting-started.html +2 -2
  101. nautobot/project-static/docs/development/core/homepage.html +2 -2
  102. nautobot/project-static/docs/development/core/index.html +2 -2
  103. nautobot/project-static/docs/development/core/model-checklist.html +2 -2
  104. nautobot/project-static/docs/development/core/model-features.html +2 -2
  105. nautobot/project-static/docs/development/core/natural-keys.html +2 -2
  106. nautobot/project-static/docs/development/core/navigation-menu.html +2 -2
  107. nautobot/project-static/docs/development/core/release-checklist.html +2 -2
  108. nautobot/project-static/docs/development/core/role-internals.html +2 -2
  109. nautobot/project-static/docs/development/core/settings.html +2 -2
  110. nautobot/project-static/docs/development/core/style-guide.html +2 -2
  111. nautobot/project-static/docs/development/core/templates.html +2 -2
  112. nautobot/project-static/docs/development/core/testing.html +2 -2
  113. nautobot/project-static/docs/development/core/user-preferences.html +2 -2
  114. nautobot/project-static/docs/development/index.html +2 -2
  115. nautobot/project-static/docs/development/jobs/index.html +2 -2
  116. nautobot/project-static/docs/development/jobs/migration/from-v1.html +2 -2
  117. nautobot/project-static/docs/index.html +2 -2
  118. nautobot/project-static/docs/overview/application_stack.html +2 -2
  119. nautobot/project-static/docs/overview/design_philosophy.html +2 -2
  120. nautobot/project-static/docs/release-notes/index.html +2 -2
  121. nautobot/project-static/docs/release-notes/version-1.0.html +2 -2
  122. nautobot/project-static/docs/release-notes/version-1.1.html +2 -2
  123. nautobot/project-static/docs/release-notes/version-1.2.html +2 -2
  124. nautobot/project-static/docs/release-notes/version-1.3.html +2 -2
  125. nautobot/project-static/docs/release-notes/version-1.4.html +2 -2
  126. nautobot/project-static/docs/release-notes/version-1.5.html +2 -2
  127. nautobot/project-static/docs/release-notes/version-1.6.html +2 -2
  128. nautobot/project-static/docs/release-notes/version-2.0.html +2 -2
  129. nautobot/project-static/docs/release-notes/version-2.1.html +2 -2
  130. nautobot/project-static/docs/release-notes/version-2.2.html +2 -2
  131. nautobot/project-static/docs/release-notes/version-2.3.html +400 -231
  132. nautobot/project-static/docs/requirements.txt +2 -2
  133. nautobot/project-static/docs/search/search_index.json +1 -1
  134. nautobot/project-static/docs/sitemap.xml +270 -270
  135. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  136. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +2 -2
  137. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +2 -2
  138. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +2 -2
  139. nautobot/project-static/docs/user-guide/administration/configuration/index.html +2 -2
  140. nautobot/project-static/docs/user-guide/administration/configuration/redis.html +2 -2
  141. nautobot/project-static/docs/user-guide/administration/configuration/settings.html +29 -2
  142. nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +2 -2
  143. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +2 -2
  144. nautobot/project-static/docs/user-guide/administration/guides/docker.html +2 -2
  145. nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +2 -2
  146. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +2 -2
  147. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +2 -2
  148. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +2 -2
  149. nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +2 -2
  150. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +2 -2
  151. nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +2 -2
  152. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +2 -2
  153. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +2 -2
  154. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +2 -2
  155. nautobot/project-static/docs/user-guide/administration/installation/index.html +2 -2
  156. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +2 -2
  157. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +2 -2
  158. nautobot/project-static/docs/user-guide/administration/installation/services.html +2 -2
  159. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +2 -2
  160. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +2 -2
  161. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +2 -2
  162. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +2 -2
  163. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +2 -2
  164. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +2 -2
  165. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +2 -2
  166. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +2 -2
  167. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +2 -2
  168. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +2 -2
  169. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +2 -2
  170. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +2 -2
  171. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -2
  172. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +2 -2
  173. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +2 -2
  174. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +2 -2
  175. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +2 -2
  176. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +2 -2
  177. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +2 -2
  178. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +2 -2
  179. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +2 -2
  180. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +2 -2
  181. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +2 -2
  182. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +2 -2
  183. nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +2 -2
  184. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +2 -2
  185. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +2 -2
  186. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +2 -2
  187. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +2 -2
  188. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +2 -2
  189. nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +2 -2
  190. nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +2 -2
  191. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +2 -2
  192. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +2 -2
  193. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +2 -2
  194. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +2 -2
  195. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +2 -2
  196. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +2 -2
  197. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +2 -2
  198. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +2 -2
  199. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +2 -2
  200. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +2 -2
  201. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +2 -2
  202. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +2 -2
  203. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +2 -2
  204. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +2 -2
  205. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +2 -2
  206. nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +2 -2
  207. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +2 -2
  208. nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +2 -2
  209. nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +2 -2
  210. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +2 -2
  211. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +2 -2
  212. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +2 -2
  213. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +2 -2
  214. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +2 -2
  215. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +2 -2
  216. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +2 -2
  217. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +2 -2
  218. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +2 -2
  219. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +2 -2
  220. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +2 -2
  221. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +2 -2
  222. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +2 -2
  223. nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +2 -2
  224. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +2 -2
  225. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +2 -2
  226. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +2 -2
  227. nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +2 -2
  228. nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +2 -2
  229. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +2 -2
  230. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +2 -2
  231. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +2 -2
  232. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +2 -2
  233. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +2 -2
  234. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +2 -2
  235. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +2 -2
  236. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +2 -2
  237. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +2 -2
  238. nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +2 -2
  239. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +2 -2
  240. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +2 -2
  241. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +2 -2
  242. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +2 -2
  243. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +2 -2
  244. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +2 -2
  245. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +2 -2
  246. nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +2 -2
  247. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +2 -2
  248. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +2 -2
  249. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +2 -2
  250. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +2 -2
  251. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +2 -2
  252. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +2 -2
  253. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +2 -2
  254. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +2 -2
  255. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +2 -2
  256. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +2 -2
  257. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +2 -2
  258. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +2 -2
  259. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +2 -2
  260. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +2 -2
  261. nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +2 -2
  262. nautobot/project-static/docs/user-guide/index.html +2 -2
  263. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +2 -2
  264. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +2 -2
  265. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +2 -2
  266. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +2 -2
  267. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +2 -2
  268. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +2 -2
  269. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +2 -2
  270. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +2 -2
  271. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +2 -2
  272. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +2 -2
  273. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +2 -2
  274. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +2 -2
  275. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +2 -2
  276. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +2 -2
  277. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +2 -2
  278. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +2 -2
  279. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +2 -2
  280. nautobot/project-static/docs/user-guide/platform-functionality/note.html +2 -2
  281. nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +2 -2
  282. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +2 -2
  283. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +2 -2
  284. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +2 -2
  285. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +2 -2
  286. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +2 -2
  287. nautobot/project-static/docs/user-guide/platform-functionality/role.html +2 -2
  288. nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +2 -2
  289. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +2 -2
  290. nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +2 -2
  291. nautobot/project-static/docs/user-guide/platform-functionality/status.html +2 -2
  292. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +2 -2
  293. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +2 -2
  294. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +2 -2
  295. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +2 -2
  296. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +2 -2
  297. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/METADATA +5 -4
  298. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/RECORD +302 -303
  299. nautobot/core/fixtures/user-data.json +0 -59
  300. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/LICENSE.txt +0 -0
  301. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/NOTICE +0 -0
  302. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/WHEEL +0 -0
  303. {nautobot-2.3.14.dist-info → nautobot-2.3.15.dist-info}/entry_points.txt +0 -0
nautobot/core/settings.py CHANGED
@@ -173,6 +173,9 @@ PLUGINS_CONFIG = {}
173
173
  if "NAUTOBOT_PREFER_IPV4" in os.environ and os.environ["NAUTOBOT_PREFER_IPV4"] != "":
174
174
  PREFER_IPV4 = is_truthy(os.environ["NAUTOBOT_PREFER_IPV4"])
175
175
 
176
+ # Publish a simple "no-index" robots.txt for Nautobot?
177
+ PUBLISH_ROBOTS_TXT = is_truthy(os.getenv("NAUTOBOT_PUBLISH_ROBOTS_TXT", "True"))
178
+
176
179
  # Default height and width in pixels of a single rack unit in rendered rack elevations. Defaults are 22 and 220
177
180
  if (
178
181
  "NAUTOBOT_RACK_ELEVATION_DEFAULT_UNIT_HEIGHT" in os.environ
@@ -1473,6 +1473,14 @@ properties:
1473
1473
  environment_variable: "NAUTOBOT_PREFER_IPV4"
1474
1474
  is_constance_config: true
1475
1475
  type: "boolean"
1476
+ PUBLISH_ROBOTS_TXT:
1477
+ default: true
1478
+ description: >-
1479
+ Setting this to true causes Nautobot to publish a `robots.txt` that discourages indexing by web crawlers.
1480
+ Irrelevant if deployed behind a firewall.
1481
+ environment_variable: "NAUTOBOT_PUBLISH_ROBOTS_TXT"
1482
+ type: "boolean"
1483
+ version_added: "2.3.15"
1476
1484
  RACK_ELEVATION_DEFAULT_UNIT_HEIGHT:
1477
1485
  default: 22
1478
1486
  description: >-
@@ -47,3 +47,6 @@
47
47
  <meta name="theme-color" content="#ffffff">
48
48
  <meta charset="UTF-8">
49
49
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
50
+ {% if settings.PUBLISH_ROBOTS_TXT %}
51
+ <meta name="robots" content="noindex, nofollow">
52
+ {% endif %}
@@ -490,6 +490,9 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
490
490
  # if "NAUTOBOT_PREFER_IPV4" in os.environ and os.environ["NAUTOBOT_PREFER_IPV4"] != "":
491
491
  # PREFER_IPV4 = is_truthy(os.environ["NAUTOBOT_PREFER_IPV4"])
492
492
 
493
+ # Publish a simple "no-index" robots.txt for Nautobot?
494
+ # PUBLISH_ROBOTS_TXT = is_truthy(os.getenv("NAUTOBOT_PUBLISH_ROBOTS_TXT", "True"))
495
+
493
496
  # Default height and width in pixels of a single rack unit in rendered rack elevations. Defaults are 22 and 230
494
497
  #
495
498
  # if (
@@ -144,13 +144,18 @@ class NautobotTestCaseMixin:
144
144
  # Permissions management
145
145
  #
146
146
 
147
- def add_permissions(self, *names):
147
+ def add_permissions(self, *names, **kwargs):
148
148
  """
149
149
  Assign a set of permissions to the test user. Accepts permission names in the form <app>.<action>_<model>.
150
+ Additional keyword arguments will be passed to the ObjectPermission constructor to allow creating more detailed permissions.
151
+
152
+ Examples:
153
+ >>> add_permissions("ipam.add_vlangroup", "ipam.view_vlangroup")
154
+ >>> add_permissions("ipam.add_vlangroup", "ipam.view_vlangroup", constraints={"pk": "uuid-1234"})
150
155
  """
151
156
  for name in names:
152
157
  ct, action = permissions.resolve_permission_ct(name)
153
- obj_perm = users_models.ObjectPermission(name=name, actions=[action])
158
+ obj_perm = users_models.ObjectPermission(name=name, actions=[action], **kwargs)
154
159
  obj_perm.save()
155
160
  obj_perm.users.add(self.user)
156
161
  obj_perm.object_types.add(ct)
@@ -9,7 +9,6 @@ from example_app.models import ExampleModel
9
9
  class AppHomeTestCase(SeleniumTestCase):
10
10
  """Integration test the Example App homepage extensions."""
11
11
 
12
- fixtures = ["user-data.json"] # bob/bob
13
12
  layout = {
14
13
  "Organization": {
15
14
  "Locations": {"model": Location, "permission": "dcim.view_location"},
@@ -5,7 +5,6 @@ from nautobot.core.testing.integration import SeleniumTestCase
5
5
  class AppNavBarTestCase(SeleniumTestCase):
6
6
  """Integration test the navigation menu."""
7
7
 
8
- fixtures = ["user-data.json"]
9
8
  navbar = {
10
9
  "Circuits": {
11
10
  "Circuits": {
@@ -11,8 +11,6 @@ from nautobot.extras.models import CustomField, CustomFieldChoice, Status
11
11
  class ListViewFilterTestCase(SeleniumTestCase):
12
12
  """Integration test for the list view filter ui."""
13
13
 
14
- fixtures = ["user-data.json"]
15
-
16
14
  def setUp(self):
17
15
  super().setUp()
18
16
  self.login(self.user.username, self.password)
@@ -7,7 +7,6 @@ from nautobot.tenancy.models import Tenant
7
7
  class HomeTestCase(SeleniumTestCase):
8
8
  """Integration tests against the home page."""
9
9
 
10
- fixtures = ["user-data.json"] # bob/bob
11
10
  layout = {
12
11
  "Organization": {
13
12
  "Locations": {"model": Location, "permission": "dcim.view_location"},
@@ -4,7 +4,6 @@ from nautobot.core.testing.integration import SeleniumTestCase
4
4
  class NavBarTestCase(SeleniumTestCase):
5
5
  """Integration test the navigation menu."""
6
6
 
7
- fixtures = ["user-data.json"]
8
7
  navbar = {
9
8
  "Organization": {
10
9
  "Locations": {
@@ -31,6 +31,7 @@ class AuthenticationEnforcedTestCase(TestCase):
31
31
  "/health/",
32
32
  "/login/",
33
33
  "/media-failure/",
34
+ "/robots.txt",
34
35
  "/template.css",
35
36
  ]:
36
37
  self.assertHttpStatus(response, 200, msg=url)
@@ -594,3 +594,32 @@ class ExampleViewWithCustomPermissionsTest(TestCase):
594
594
  self.user.save()
595
595
  response = self.client.get(url)
596
596
  self.assertBodyContains(response, "You are viewing a table of example models")
597
+
598
+
599
+ class SearchRobotsTestCase(TestCase):
600
+ def test_robots_disallowed(self):
601
+ """
602
+ Test that the robots.txt file is accessible to all users and defaults to disallowing all bots.
603
+ """
604
+ url = reverse("robots_txt")
605
+ response = self.client.get(url)
606
+ self.assertHttpStatus(response, 200)
607
+ self.assertBodyContains(response, "User-Agent: *")
608
+ self.assertBodyContains(response, "Disallow: /")
609
+
610
+ url = reverse("home")
611
+ response = self.client.get(url)
612
+ self.assertContains(response, '<meta name="robots" content="noindex, nofollow">', html=True)
613
+
614
+ @override_settings(PUBLISH_ROBOTS_TXT=False)
615
+ def test_robots_allowed(self):
616
+ """
617
+ Test that the robots.txt file is not published if PUBLISH_ROBOTS_TXT is set to False.
618
+ """
619
+ url = reverse("robots_txt")
620
+ response = self.client.get(url)
621
+ self.assertHttpStatus(response, 404)
622
+
623
+ url = reverse("home")
624
+ response = self.client.get(url)
625
+ self.assertNotContains(response, '<meta name="robots" content="noindex, nofollow">', html=True)
nautobot/core/urls.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from django.conf import settings
2
+ from django.http import HttpResponse, HttpResponseNotFound
2
3
  from django.urls import include, path
3
4
  from django.views.generic import TemplateView
4
5
  from django.views.static import serve
@@ -72,6 +73,14 @@ urlpatterns = [
72
73
  path(
73
74
  "template.css", TemplateView.as_view(template_name="template.css", content_type="text/css"), name="template_css"
74
75
  ),
76
+ # The response is conditional as opposed to wrapping the path() call in an if statement to be able to test the setting with current test setup
77
+ path(
78
+ "robots.txt",
79
+ lambda x: HttpResponse("User-Agent: *\nDisallow: /", content_type="text/plain")
80
+ if settings.PUBLISH_ROBOTS_TXT
81
+ else HttpResponseNotFound(),
82
+ name="robots_txt",
83
+ ),
75
84
  ]
76
85
 
77
86
 
@@ -837,7 +837,7 @@ class StatusModelFilterFormMixin(forms.Form):
837
837
  self.order_fields(self.field_order) # Reorder fields again
838
838
 
839
839
 
840
- class TagsBulkEditFormMixin(forms.Form):
840
+ class TagsBulkEditFormMixin(BulkEditForm):
841
841
  def __init__(self, *args, **kwargs):
842
842
  super().__init__(*args, **kwargs)
843
843
 
@@ -578,7 +578,13 @@ class CustomField(
578
578
  )
579
579
 
580
580
  def to_form_field(
581
- self, set_initial=True, enforce_required=True, for_csv_import=False, simple_json_filter=False, label=None
581
+ self,
582
+ set_initial=True,
583
+ enforce_required=True,
584
+ for_csv_import=False,
585
+ simple_json_filter=False,
586
+ label=None,
587
+ for_filter_form=False,
582
588
  ):
583
589
  """
584
590
  Return a form field suitable for setting a CustomField's value for an object.
@@ -590,6 +596,7 @@ class CustomField(
590
596
  this is *not* used for CSV imports since 2.0, but it *is* used for JSON/YAML import of DeviceTypes.
591
597
  simple_json_filter: Return a TextInput widget for JSON filtering instead of the default TextArea widget.
592
598
  label: Set the input label manually (if required); otherwise, defaults to field's __str__() implementation.
599
+ for_filter_form: If True return the relevant form field for filter form
593
600
  """
594
601
  initial = self.default if set_initial else None
595
602
  required = self.required if enforce_required else False
@@ -676,7 +683,7 @@ class CustomField(
676
683
  default_choice = self.custom_field_choices.filter(value=self.default).first()
677
684
 
678
685
  # Set the initial value to the first available choice (if any)
679
- if self.type == CustomFieldTypeChoices.TYPE_SELECT:
686
+ if self.type == CustomFieldTypeChoices.TYPE_SELECT and not for_filter_form:
680
687
  if not required or default_choice is None:
681
688
  choices = add_blank_choice(choices)
682
689
  field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
@@ -704,16 +711,10 @@ class CustomField(
704
711
 
705
712
  def to_filter_form_field(self, lookup_expr="exact", *args, **kwargs):
706
713
  """Return a filter form field suitable for filtering a CustomField's value for an object."""
707
- form_field = self.to_form_field(*args, **kwargs)
708
- # We would handle type selection differently because:
709
- # 1. We'd need to use StaticSelect2Multiple for lookup_type 'exact' because self.type `select` uses StaticSelect2 by default.
710
- # 2. Remove the blank choice since StaticSelect2Multiple is always blank and interprets the blank choice as an extra option.
711
- # 3. If lookup_type is not the same as exact, use MultiValueCharInput
714
+ form_field = self.to_form_field(*args, **kwargs, for_filter_form=True)
715
+ # We would handle type selection differently because: If lookup_type is not the same as exact, use MultiValueCharInput
712
716
  if self.type == CustomFieldTypeChoices.TYPE_SELECT:
713
- if lookup_expr in ["exact", "contains"]:
714
- choices = form_field.choices[1:]
715
- form_field.widget = StaticSelect2Multiple(choices=choices)
716
- else:
717
+ if lookup_expr not in ["exact", "contains"]:
717
718
  form_field.widget = MultiValueCharInput()
718
719
  return form_field
719
720
 
@@ -4,8 +4,6 @@ from nautobot.core.testing.integration import SeleniumTestCase
4
4
  class PluginBannerTestCase(SeleniumTestCase):
5
5
  """Integration test for rendering of plugin-injected banner content."""
6
6
 
7
- fixtures = ("user-data",)
8
-
9
7
  def test_banner_not_rendered(self):
10
8
  """As implemented, plugin banner does not render if the user is not logged in.
11
9
 
@@ -4,12 +4,13 @@ import warnings
4
4
  from django.contrib.auth import get_user_model
5
5
  from django.contrib.contenttypes.models import ContentType
6
6
  from django.db.models import Q
7
+ from django.forms import ChoiceField, MultipleChoiceField
7
8
  from django.test import override_settings, TestCase
8
9
 
9
10
  from nautobot.dcim.forms import DeviceForm, LocationBulkEditForm, LocationForm
10
11
  import nautobot.dcim.models as dcim_models
11
12
  from nautobot.dcim.models import Device, Location, LocationType
12
- from nautobot.extras.choices import RelationshipTypeChoices
13
+ from nautobot.extras.choices import CustomFieldTypeChoices, RelationshipTypeChoices
13
14
  from nautobot.extras.forms import (
14
15
  ConfigContextFilterForm,
15
16
  ConfigContextForm,
@@ -25,6 +26,7 @@ from nautobot.extras.forms import (
25
26
  WebhookForm,
26
27
  )
27
28
  from nautobot.extras.models import (
29
+ CustomField,
28
30
  Job,
29
31
  JobButton,
30
32
  JobHook,
@@ -1217,3 +1219,20 @@ class CustomFieldModelFormMixinTestCase(TestCase):
1217
1219
 
1218
1220
  custom_field_form = TestForm()
1219
1221
  self.assertIn("_custom_field_data", custom_field_form.fields)
1222
+
1223
+
1224
+ class CustomFieldTestCase(TestCase):
1225
+ def test_to_form_field_type_select(self):
1226
+ """Verify that `to_form_field` and `to_filter_form_field` return the correct field types for a select-type CustomField."""
1227
+ custom_field = CustomField.objects.create(
1228
+ type=CustomFieldTypeChoices.TYPE_SELECT,
1229
+ label="Custom Field Select",
1230
+ )
1231
+ form = custom_field.to_filter_form_field()
1232
+ self.assertIsInstance(form, MultipleChoiceField)
1233
+
1234
+ form = custom_field.to_form_field(for_filter_form=True)
1235
+ self.assertIsInstance(form, MultipleChoiceField)
1236
+
1237
+ form = custom_field.to_form_field(for_filter_form=False)
1238
+ self.assertIsInstance(form, ChoiceField)
@@ -227,7 +227,8 @@ class PrefixViewSet(NautobotModelViewSet):
227
227
 
228
228
  # Create the new Prefix(es)
229
229
  serializer.is_valid(raise_exception=True)
230
- serializer.save()
230
+ self.perform_create(serializer)
231
+
231
232
  return Response(serializer.data, status=status.HTTP_201_CREATED)
232
233
 
233
234
  else:
@@ -318,7 +319,8 @@ class PrefixViewSet(NautobotModelViewSet):
318
319
 
319
320
  # Create the new IP address(es)
320
321
  serializer.is_valid(raise_exception=True)
321
- serializer.save()
322
+ self.perform_create(serializer)
323
+
322
324
  return Response(serializer.data, status=status.HTTP_201_CREATED)
323
325
 
324
326
  # Determine the maximum number of IPs to return
@@ -396,21 +398,20 @@ class VLANGroupViewSet(NautobotModelViewSet):
396
398
  serializer_class = serializers.VLANGroupSerializer
397
399
  filterset_class = filters.VLANGroupFilterSet
398
400
 
399
- def restrict_queryset(self, request, *args, **kwargs):
400
- """
401
- Apply "view" permissions on the POST /available-vlans/ endpoint, otherwise as ModelViewSetMixin.
402
- """
403
- if request.user.is_authenticated and self.action == "available_vlans":
404
- self.queryset = self.queryset.restrict(request.user, "view")
405
- else:
406
- super().restrict_queryset(request, *args, **kwargs)
401
+ @staticmethod
402
+ def vlan_group_queryset():
403
+ return (
404
+ VLANGroup.objects.select_related("location")
405
+ .prefetch_related("tags")
406
+ .annotate(vlan_count=count_related(VLAN, "vlan_group"))
407
+ )
407
408
 
408
409
  class AvailableVLANPermissions(TokenPermissions):
409
- """As nautobot.core.api.authentication.TokenPermissions, but enforcing add_vlan permission."""
410
+ """As nautobot.core.api.authentication.TokenPermissions, but enforcing `add_vlan` and `view_vlan` permission."""
410
411
 
411
412
  perms_map = {
412
- "GET": ["ipam.view_vlangroup"],
413
- "POST": ["ipam.view_vlangroup", "ipam.add_vlan"],
413
+ "GET": ["ipam.view_vlangroup", "ipam.view_vlan"],
414
+ "POST": ["ipam.view_vlangroup", "ipam.view_vlan", "ipam.add_vlan"],
414
415
  }
415
416
 
416
417
  @extend_schema(methods=["get"], responses={200: ListSerializer(child=IntegerField())})
@@ -426,6 +427,7 @@ class VLANGroupViewSet(NautobotModelViewSet):
426
427
  methods=["get", "post"],
427
428
  permission_classes=[AvailableVLANPermissions],
428
429
  filterset_class=None,
430
+ queryset=VLAN.objects.all(),
429
431
  )
430
432
  def available_vlans(self, request, pk=None):
431
433
  """
@@ -433,7 +435,7 @@ class VLANGroupViewSet(NautobotModelViewSet):
433
435
  By default, the number of VIDs returned will be equivalent to PAGINATE_COUNT.
434
436
  An arbitrary limit (up to MAX_PAGE_SIZE, if set) may be passed, however results will not be paginated.
435
437
  """
436
- vlan_group = get_object_or_404(self.queryset, pk=pk)
438
+ vlan_group = get_object_or_404(self.vlan_group_queryset().restrict(user=request.user), pk=pk)
437
439
 
438
440
  if request.method == "POST":
439
441
  with cache.lock(
@@ -509,7 +511,7 @@ class VLANGroupViewSet(NautobotModelViewSet):
509
511
 
510
512
  # Create the new VLANs
511
513
  serializer.is_valid(raise_exception=True)
512
- serializer.save()
514
+ self.perform_create(serializer)
513
515
 
514
516
  data = serializer.data
515
517