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

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

Potentially problematic release.


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

Files changed (812) hide show
  1. nautobot/circuits/navigation.py +0 -25
  2. nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -9
  3. nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
  4. nautobot/circuits/tests/test_api.py +79 -2
  5. nautobot/circuits/tests/test_filters.py +1 -0
  6. nautobot/core/api/serializers.py +15 -5
  7. nautobot/core/api/views.py +18 -19
  8. nautobot/core/choices.py +1 -1
  9. nautobot/core/filters.py +12 -4
  10. nautobot/core/jobs/__init__.py +125 -3
  11. nautobot/core/management/commands/generate_test_data.py +6 -1
  12. nautobot/core/middleware.py +12 -4
  13. nautobot/core/models/fields.py +12 -2
  14. nautobot/core/settings.py +9 -8
  15. nautobot/core/tables.py +26 -31
  16. nautobot/core/templates/base_django.html +2 -2
  17. nautobot/core/templates/buttons/export.html +57 -30
  18. nautobot/core/templates/generic/object_list.html +2 -2
  19. nautobot/core/templates/generic/object_retrieve.html +8 -1
  20. nautobot/core/templates/home.html +5 -5
  21. nautobot/core/templates/inc/created_updated.html +2 -2
  22. nautobot/core/templates/inc/footer.html +2 -2
  23. nautobot/core/templates/inc/javascript.html +0 -10
  24. nautobot/core/templates/inc/media.html +2 -0
  25. nautobot/core/templates/inc/nav_menu.html +66 -68
  26. nautobot/core/templates/inc/object_details_advanced_panel.html +19 -0
  27. nautobot/core/templates/nautobot_config.py.j2 +10 -4
  28. nautobot/core/templates/panel_table.html +1 -1
  29. nautobot/core/templates/template.css +89 -0
  30. nautobot/core/templates/utilities/templatetags/table_config_form.html +1 -0
  31. nautobot/core/templatetags/buttons.py +7 -2
  32. nautobot/core/templatetags/helpers.py +9 -9
  33. nautobot/core/testing/views.py +34 -4
  34. nautobot/core/tests/integration/test_home.py +1 -43
  35. nautobot/core/tests/integration/test_navbar.py +10 -64
  36. nautobot/core/tests/integration/test_plugin_home.py +4 -5
  37. nautobot/core/tests/integration/test_plugin_navbar.py +20 -16
  38. nautobot/core/tests/integration/test_theme.py +4 -0
  39. nautobot/core/tests/test_api.py +14 -66
  40. nautobot/core/tests/test_filters.py +127 -0
  41. nautobot/core/tests/test_forms.py +4 -4
  42. nautobot/core/tests/test_graphql.py +165 -2
  43. nautobot/core/tests/test_jobs.py +112 -0
  44. nautobot/core/tests/test_openapi.py +6 -0
  45. nautobot/core/tests/test_utils.py +23 -20
  46. nautobot/core/tests/test_views.py +11 -85
  47. nautobot/core/urls.py +6 -1
  48. nautobot/core/utils/data.py +5 -1
  49. nautobot/core/utils/filtering.py +6 -4
  50. nautobot/core/utils/lookup.py +28 -0
  51. nautobot/core/utils/requests.py +2 -3
  52. nautobot/core/views/__init__.py +3 -4
  53. nautobot/core/views/generic.py +15 -11
  54. nautobot/core/views/mixins.py +9 -8
  55. nautobot/core/views/renderers.py +5 -0
  56. nautobot/core/views/utils.py +23 -24
  57. nautobot/dcim/api/serializers.py +8 -4
  58. nautobot/dcim/models/device_components.py +1 -0
  59. nautobot/dcim/models/devices.py +7 -6
  60. nautobot/dcim/navigation.py +10 -165
  61. nautobot/dcim/templates/dcim/location.html +1 -1
  62. nautobot/dcim/tests/features/locations.feature +143 -0
  63. nautobot/dcim/tests/test_api.py +8 -1
  64. nautobot/dcim/tests/test_filters.py +11 -3
  65. nautobot/dcim/views.py +5 -6
  66. nautobot/extras/admin.py +1 -1
  67. nautobot/extras/api/serializers.py +33 -0
  68. nautobot/extras/api/urls.py +6 -0
  69. nautobot/extras/api/views.py +45 -6
  70. nautobot/extras/context_managers.py +34 -8
  71. nautobot/extras/factory.py +28 -2
  72. nautobot/extras/filters/__init__.py +52 -0
  73. nautobot/extras/filters/mixins.py +4 -29
  74. nautobot/extras/forms/forms.py +43 -0
  75. nautobot/extras/jobs.py +39 -17
  76. nautobot/extras/migrations/0100_fileproxy_job_result.py +32 -0
  77. nautobot/extras/migrations/0101_externalintegration.py +61 -0
  78. nautobot/extras/migrations/0102_set_null_objectchange_contenttype.py +32 -0
  79. nautobot/extras/models/__init__.py +2 -0
  80. nautobot/extras/models/change_logging.py +2 -2
  81. nautobot/extras/models/customfields.py +2 -2
  82. nautobot/extras/models/models.py +101 -18
  83. nautobot/extras/models/relationships.py +13 -8
  84. nautobot/extras/navigation.py +17 -29
  85. nautobot/extras/signals.py +80 -59
  86. nautobot/extras/tables.py +28 -2
  87. nautobot/extras/templates/extras/externalintegration_retrieve.html +37 -0
  88. nautobot/extras/templates/extras/inc/jobresult.html +24 -0
  89. nautobot/extras/templates/extras/jobresult.html +24 -0
  90. nautobot/extras/templatetags/computed_fields.py +6 -13
  91. nautobot/extras/templatetags/custom_links.py +19 -12
  92. nautobot/extras/templatetags/job_buttons.py +34 -19
  93. nautobot/extras/templatetags/plugins.py +1 -1
  94. nautobot/extras/test_jobs/file_output.py +16 -0
  95. nautobot/extras/tests/test_api.py +92 -0
  96. nautobot/extras/tests/test_context_managers.py +94 -4
  97. nautobot/extras/tests/test_customfields.py +1 -1
  98. nautobot/extras/tests/test_filters.py +64 -2
  99. nautobot/extras/tests/test_jobs.py +75 -22
  100. nautobot/extras/tests/test_models.py +34 -0
  101. nautobot/extras/tests/test_relationships.py +2 -2
  102. nautobot/extras/tests/test_views.py +204 -4
  103. nautobot/extras/tests/test_webhooks.py +61 -25
  104. nautobot/extras/urls.py +1 -0
  105. nautobot/extras/views.py +27 -13
  106. nautobot/extras/webhooks.py +16 -25
  107. nautobot/ipam/fields.py +5 -0
  108. nautobot/ipam/forms.py +16 -0
  109. nautobot/ipam/models.py +13 -2
  110. nautobot/ipam/navigation.py +2 -59
  111. nautobot/ipam/tables.py +1 -1
  112. nautobot/ipam/templates/ipam/ipaddress.html +0 -9
  113. nautobot/ipam/templates/ipam/prefix.html +0 -9
  114. nautobot/ipam/tests/features/prefixes.feature +134 -0
  115. nautobot/ipam/tests/test_filters.py +5 -10
  116. nautobot/ipam/tests/test_models.py +7 -0
  117. nautobot/ipam/tests/test_views.py +8 -1
  118. nautobot/ipam/views.py +99 -58
  119. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +191 -191
  120. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
  121. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
  122. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
  123. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +874 -881
  124. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
  125. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
  126. nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
  127. nautobot/project-static/css/base.css +138 -99
  128. nautobot/project-static/css/dark.css +65 -6
  129. nautobot/project-static/docs/404.html +45 -17
  130. nautobot/project-static/docs/apps/index.html +45 -17
  131. nautobot/project-static/docs/apps/nautobot-apps.html +45 -17
  132. nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +45 -17
  133. nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +45 -17
  134. nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1598 -1458
  135. nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +229 -152
  136. nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +46 -18
  137. nautobot/project-static/docs/code-reference/nautobot/apps/config.html +45 -17
  138. nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +45 -17
  139. nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +45 -17
  140. nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +45 -17
  141. nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +354 -433
  142. nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +67 -39
  143. nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +45 -17
  144. nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2083 -2234
  145. nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1389 -1247
  146. nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +45 -17
  147. nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +45 -17
  148. nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +129 -111
  149. nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3601 -3457
  150. nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +45 -17
  151. nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +45 -17
  152. nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +320 -284
  153. nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3863 -3801
  154. nautobot/project-static/docs/development/apps/api/configuration-view.html +45 -17
  155. nautobot/project-static/docs/development/apps/api/database-backend-config.html +45 -17
  156. nautobot/project-static/docs/development/apps/api/models/django-admin.html +45 -17
  157. nautobot/project-static/docs/development/apps/api/models/global-search.html +45 -17
  158. nautobot/project-static/docs/development/apps/api/models/graphql.html +45 -17
  159. nautobot/project-static/docs/development/apps/api/models/index.html +45 -17
  160. nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +45 -17
  161. nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +45 -17
  162. nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +45 -17
  163. nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +45 -17
  164. nautobot/project-static/docs/development/apps/api/platform-features/index.html +45 -17
  165. nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +45 -17
  166. nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +45 -17
  167. nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +45 -17
  168. nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +45 -17
  169. nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +45 -17
  170. nautobot/project-static/docs/development/apps/api/prometheus.html +45 -17
  171. nautobot/project-static/docs/development/apps/api/setup.html +45 -17
  172. nautobot/project-static/docs/development/apps/api/testing.html +45 -17
  173. nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +45 -17
  174. nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +45 -17
  175. nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +45 -17
  176. nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +45 -17
  177. nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +45 -17
  178. nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +45 -17
  179. nautobot/project-static/docs/development/apps/api/views/base-template.html +45 -17
  180. nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +45 -17
  181. nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +45 -17
  182. nautobot/project-static/docs/development/apps/api/views/help-documentation.html +45 -17
  183. nautobot/project-static/docs/development/apps/api/views/index.html +45 -17
  184. nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +45 -17
  185. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +45 -17
  186. nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +45 -17
  187. nautobot/project-static/docs/development/apps/api/views/notes.html +45 -17
  188. nautobot/project-static/docs/development/apps/api/views/rest-api.html +45 -17
  189. nautobot/project-static/docs/development/apps/api/views/urls.html +45 -17
  190. nautobot/project-static/docs/development/apps/api/views/view-overrides.html +45 -17
  191. nautobot/project-static/docs/development/apps/index.html +45 -17
  192. nautobot/project-static/docs/development/apps/migration/code-updates.html +45 -17
  193. nautobot/project-static/docs/development/apps/migration/dependency-updates.html +45 -17
  194. nautobot/project-static/docs/development/apps/migration/from-v1.html +45 -17
  195. nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +45 -17
  196. nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +45 -17
  197. nautobot/project-static/docs/development/apps/migration/model-updates/global.html +45 -17
  198. nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +45 -17
  199. nautobot/project-static/docs/development/apps/porting-from-netbox.html +45 -17
  200. nautobot/project-static/docs/development/core/application-registry.html +45 -17
  201. nautobot/project-static/docs/development/core/best-practices.html +45 -17
  202. nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +45 -17
  203. nautobot/project-static/docs/development/core/extending-models.html +45 -17
  204. nautobot/project-static/docs/development/core/generic-views.html +45 -17
  205. nautobot/project-static/docs/development/core/getting-started.html +45 -17
  206. nautobot/project-static/docs/development/core/homepage.html +45 -17
  207. nautobot/project-static/docs/development/core/index.html +45 -17
  208. nautobot/project-static/docs/development/core/model-features.html +45 -17
  209. nautobot/project-static/docs/development/core/natural-keys.html +45 -17
  210. nautobot/project-static/docs/development/core/navigation-menu.html +45 -22
  211. nautobot/project-static/docs/development/core/react-ui.html +45 -17
  212. nautobot/project-static/docs/development/core/release-checklist.html +46 -18
  213. nautobot/project-static/docs/development/core/role-internals.html +45 -17
  214. nautobot/project-static/docs/development/core/style-guide.html +45 -17
  215. nautobot/project-static/docs/development/core/templates.html +45 -17
  216. nautobot/project-static/docs/development/core/testing.html +45 -17
  217. nautobot/project-static/docs/development/core/user-preferences.html +45 -17
  218. nautobot/project-static/docs/development/index.html +45 -17
  219. nautobot/project-static/docs/development/jobs/index.html +281 -235
  220. nautobot/project-static/docs/development/jobs/migration/from-v1.html +45 -17
  221. nautobot/project-static/docs/index.html +45 -17
  222. nautobot/project-static/docs/media/nautobot_application_stack_low_level.png +0 -0
  223. nautobot/project-static/docs/media/nautobot_application_stack_low_level.txt +1 -0
  224. nautobot/project-static/docs/objects.inv +0 -0
  225. nautobot/project-static/docs/release-notes/index.html +48 -20
  226. nautobot/project-static/docs/release-notes/version-1.0.html +45 -17
  227. nautobot/project-static/docs/release-notes/version-1.1.html +45 -17
  228. nautobot/project-static/docs/release-notes/version-1.2.html +45 -17
  229. nautobot/project-static/docs/release-notes/version-1.3.html +45 -17
  230. nautobot/project-static/docs/release-notes/version-1.4.html +45 -17
  231. nautobot/project-static/docs/release-notes/version-1.5.html +45 -17
  232. nautobot/project-static/docs/release-notes/version-1.6.html +46 -18
  233. nautobot/project-static/docs/release-notes/version-2.0.html +372 -199
  234. nautobot/project-static/docs/release-notes/version-2.1.html +5724 -0
  235. nautobot/project-static/docs/requirements.txt +1 -1
  236. nautobot/project-static/docs/search/search_index.json +1 -1
  237. nautobot/project-static/docs/sitemap.xml +247 -237
  238. nautobot/project-static/docs/sitemap.xml.gz +0 -0
  239. nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +45 -17
  240. nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +45 -17
  241. nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +45 -17
  242. nautobot/project-static/docs/user-guide/administration/configuration/index.html +45 -17
  243. nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +45 -17
  244. nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +110 -44
  245. nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +45 -17
  246. nautobot/project-static/docs/user-guide/administration/guides/caching.html +48 -20
  247. nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +45 -17
  248. nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +45 -17
  249. nautobot/project-static/docs/user-guide/administration/guides/permissions.html +45 -17
  250. nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +45 -17
  251. nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +45 -17
  252. nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +49 -20
  253. nautobot/project-static/docs/user-guide/administration/installation/app-install.html +45 -17
  254. nautobot/project-static/docs/user-guide/administration/installation/docker.html +45 -17
  255. nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +45 -17
  256. nautobot/project-static/docs/user-guide/administration/installation/http-server.html +45 -17
  257. nautobot/project-static/docs/user-guide/administration/installation/index.html +45 -17
  258. nautobot/project-static/docs/user-guide/administration/installation/install_system.html +45 -17
  259. nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +45 -17
  260. nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +45 -17
  261. nautobot/project-static/docs/user-guide/administration/installation/services.html +45 -17
  262. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +45 -17
  263. nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +45 -17
  264. nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +45 -17
  265. nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +45 -17
  266. nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +45 -17
  267. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +45 -17
  268. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +45 -17
  269. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +45 -17
  270. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +45 -17
  271. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +45 -17
  272. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +45 -17
  273. nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +45 -17
  274. nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +45 -17
  275. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +45 -17
  276. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +45 -17
  277. nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +45 -17
  278. nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +45 -17
  279. nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +45 -17
  280. nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +45 -17
  281. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +45 -17
  282. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +45 -17
  283. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +45 -17
  284. nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +45 -17
  285. nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +45 -17
  286. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +45 -17
  287. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +45 -17
  288. nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +45 -17
  289. nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +45 -17
  290. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +45 -17
  291. nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +45 -17
  292. nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +45 -17
  293. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +45 -17
  294. nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +45 -17
  295. nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +45 -17
  296. nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +45 -17
  297. nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +45 -17
  298. nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +45 -17
  299. nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +45 -17
  300. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +45 -17
  301. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +45 -17
  302. nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +45 -17
  303. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +45 -17
  304. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +45 -17
  305. nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +45 -17
  306. nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +45 -17
  307. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +45 -17
  308. nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +45 -17
  309. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +45 -17
  310. nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +45 -17
  311. nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +45 -17
  312. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +45 -17
  313. nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +45 -17
  314. nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +45 -17
  315. nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +45 -17
  316. nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +45 -17
  317. nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +45 -17
  318. nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +45 -17
  319. nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +45 -17
  320. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +45 -17
  321. nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +45 -17
  322. nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +45 -17
  323. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +45 -17
  324. nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +45 -17
  325. nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +45 -17
  326. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +45 -17
  327. nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +45 -17
  328. nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +45 -17
  329. nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +45 -17
  330. nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +45 -17
  331. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +45 -17
  332. nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +45 -17
  333. nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +45 -17
  334. nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +45 -17
  335. nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +45 -17
  336. nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +45 -17
  337. nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +45 -17
  338. nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +45 -17
  339. nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +45 -17
  340. nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +45 -17
  341. nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -17
  342. nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +45 -17
  343. nautobot/project-static/docs/user-guide/feature-guides/relationships.html +45 -17
  344. nautobot/project-static/docs/user-guide/index.html +45 -17
  345. nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +111 -17
  346. nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +45 -17
  347. nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +45 -17
  348. nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +45 -17
  349. nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +45 -17
  350. nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +48 -20
  351. nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +5359 -0
  352. nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +48 -20
  353. nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +45 -17
  354. nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +45 -17
  355. nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +45 -17
  356. nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +45 -17
  357. nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +45 -17
  358. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +45 -17
  359. nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +45 -17
  360. nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +45 -17
  361. nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +45 -17
  362. nautobot/project-static/docs/user-guide/platform-functionality/note.html +45 -17
  363. nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +45 -17
  364. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +45 -17
  365. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +114 -45
  366. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +45 -17
  367. nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +45 -17
  368. nautobot/project-static/docs/user-guide/platform-functionality/role.html +45 -17
  369. nautobot/project-static/docs/user-guide/platform-functionality/secret.html +45 -17
  370. nautobot/project-static/docs/user-guide/platform-functionality/status.html +45 -17
  371. nautobot/project-static/docs/user-guide/platform-functionality/tag.html +45 -17
  372. nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +45 -17
  373. nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +45 -17
  374. nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +45 -17
  375. nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +45 -17
  376. nautobot/project-static/fonts/UFL.txt +96 -0
  377. nautobot/project-static/fonts/Ubuntu-Bold.woff2 +0 -0
  378. nautobot/project-static/fonts/Ubuntu-BoldItalic.woff2 +0 -0
  379. nautobot/project-static/fonts/Ubuntu-Italic.woff2 +0 -0
  380. nautobot/project-static/fonts/Ubuntu-Medium.woff2 +0 -0
  381. nautobot/project-static/fonts/Ubuntu-MediumItalic.woff2 +0 -0
  382. nautobot/project-static/fonts/Ubuntu-Regular.woff2 +0 -0
  383. nautobot/project-static/fonts/UbuntuMono-Bold.woff2 +0 -0
  384. nautobot/project-static/fonts/UbuntuMono-BoldItalic.woff2 +0 -0
  385. nautobot/project-static/fonts/UbuntuMono-Italic.woff2 +0 -0
  386. nautobot/project-static/fonts/UbuntuMono-Regular.woff2 +0 -0
  387. nautobot/project-static/img/dark-theme.png +0 -0
  388. nautobot/project-static/img/light-theme.png +0 -0
  389. nautobot/project-static/img/nautobot_chevron.svg +5 -0
  390. nautobot/project-static/img/nautobot_chevron_header.svg +5 -0
  391. nautobot/project-static/img/system-theme.png +0 -0
  392. nautobot/tenancy/navigation.py +0 -13
  393. nautobot/ui/package-lock.json +2 -2
  394. nautobot/ui/package.json +1 -1
  395. nautobot/users/admin.py +44 -0
  396. nautobot/users/migrations/0007_alter_objectpermission_object_types.py +33 -0
  397. nautobot/users/models.py +3 -2
  398. nautobot/virtualization/navigation.py +1 -33
  399. nautobot/virtualization/tests/test_api.py +1 -1
  400. nautobot/virtualization/tests/test_filters.py +1 -1
  401. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/METADATA +2 -2
  402. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/RECORD +405 -786
  403. CHANGELOG.md +0 -3
  404. CONTRIBUTING.md +0 -3
  405. NOTICE +0 -8
  406. nautobot/docs/apps/index.md +0 -22
  407. nautobot/docs/apps/nautobot-apps.md +0 -10
  408. nautobot/docs/assets/app-icons/icon-ChatOps.png +0 -0
  409. nautobot/docs/assets/app-icons/icon-DataValidationEngine.png +0 -0
  410. nautobot/docs/assets/app-icons/icon-DeviceLifecycle.png +0 -0
  411. nautobot/docs/assets/app-icons/icon-DeviceOnboarding.png +0 -0
  412. nautobot/docs/assets/app-icons/icon-FirewallModels.png +0 -0
  413. nautobot/docs/assets/app-icons/icon-GoldenConfiguration.png +0 -0
  414. nautobot/docs/assets/app-icons/icon-NautobotPluginNornir.png +0 -0
  415. nautobot/docs/assets/app-icons/icon-SSoT.png +0 -0
  416. nautobot/docs/assets/extra.css +0 -139
  417. nautobot/docs/assets/favicon.ico +0 -0
  418. nautobot/docs/assets/nautobot_logo.png +0 -0
  419. nautobot/docs/assets/nautobot_logo.svg +0 -131
  420. nautobot/docs/assets/networktocode_bw.png +0 -0
  421. nautobot/docs/assets/overrides/partials/copyright.html +0 -20
  422. nautobot/docs/development/apps/api/configuration-view.md +0 -35
  423. nautobot/docs/development/apps/api/database-backend-config.md +0 -26
  424. nautobot/docs/development/apps/api/models/django-admin.md +0 -20
  425. nautobot/docs/development/apps/api/models/global-search.md +0 -11
  426. nautobot/docs/development/apps/api/models/graphql.md +0 -97
  427. nautobot/docs/development/apps/api/models/index.md +0 -81
  428. nautobot/docs/development/apps/api/nautobot-app-config.md +0 -84
  429. nautobot/docs/development/apps/api/platform-features/custom-validators.md +0 -30
  430. nautobot/docs/development/apps/api/platform-features/filter-extensions.md +0 -49
  431. nautobot/docs/development/apps/api/platform-features/git-repository-content.md +0 -62
  432. nautobot/docs/development/apps/api/platform-features/index.md +0 -1
  433. nautobot/docs/development/apps/api/platform-features/jinja2-filters.md +0 -28
  434. nautobot/docs/development/apps/api/platform-features/jobs.md +0 -29
  435. nautobot/docs/development/apps/api/platform-features/populating-extensibility-features.md +0 -58
  436. nautobot/docs/development/apps/api/platform-features/secrets-providers.md +0 -64
  437. nautobot/docs/development/apps/api/platform-features/uniquely-identify-objects.md +0 -63
  438. nautobot/docs/development/apps/api/prometheus.md +0 -25
  439. nautobot/docs/development/apps/api/setup.md +0 -132
  440. nautobot/docs/development/apps/api/testing.md +0 -55
  441. nautobot/docs/development/apps/api/ui-extensions/banners.md +0 -26
  442. nautobot/docs/development/apps/api/ui-extensions/home-page.md +0 -9
  443. nautobot/docs/development/apps/api/ui-extensions/index.md +0 -1
  444. nautobot/docs/development/apps/api/ui-extensions/navigation.md +0 -15
  445. nautobot/docs/development/apps/api/ui-extensions/object-detail-views.md +0 -74
  446. nautobot/docs/development/apps/api/ui-extensions/tabs.md +0 -52
  447. nautobot/docs/development/apps/api/views/base-template.md +0 -38
  448. nautobot/docs/development/apps/api/views/core-view-overrides.md +0 -26
  449. nautobot/docs/development/apps/api/views/django-generic-views.md +0 -23
  450. nautobot/docs/development/apps/api/views/help-documentation.md +0 -16
  451. nautobot/docs/development/apps/api/views/index.md +0 -3
  452. nautobot/docs/development/apps/api/views/nautobot-generic-views.md +0 -35
  453. nautobot/docs/development/apps/api/views/nautobotuiviewset.md +0 -147
  454. nautobot/docs/development/apps/api/views/nautobotuiviewsetrouter.md +0 -41
  455. nautobot/docs/development/apps/api/views/notes.md +0 -25
  456. nautobot/docs/development/apps/api/views/rest-api.md +0 -64
  457. nautobot/docs/development/apps/api/views/urls.md +0 -26
  458. nautobot/docs/development/apps/api/views/view-overrides.md +0 -50
  459. nautobot/docs/development/apps/index.md +0 -75
  460. nautobot/docs/development/apps/migration/code-updates.md +0 -160
  461. nautobot/docs/development/apps/migration/dependency-updates.md +0 -13
  462. nautobot/docs/development/apps/migration/from-v1.md +0 -56
  463. nautobot/docs/development/apps/migration/model-updates/dcim.md +0 -285
  464. nautobot/docs/development/apps/migration/model-updates/extras.md +0 -30
  465. nautobot/docs/development/apps/migration/model-updates/global.md +0 -5
  466. nautobot/docs/development/apps/migration/model-updates/ipam.md +0 -22
  467. nautobot/docs/development/apps/porting-from-netbox.md +0 -23
  468. nautobot/docs/development/core/application-registry.md +0 -216
  469. nautobot/docs/development/core/best-practices.md +0 -469
  470. nautobot/docs/development/core/docker-compose-advanced-use-cases.md +0 -228
  471. nautobot/docs/development/core/extending-models.md +0 -93
  472. nautobot/docs/development/core/generic-views.md +0 -65
  473. nautobot/docs/development/core/getting-started.md +0 -859
  474. nautobot/docs/development/core/homepage.md +0 -63
  475. nautobot/docs/development/core/index.md +0 -334
  476. nautobot/docs/development/core/model-features.md +0 -44
  477. nautobot/docs/development/core/natural-keys.md +0 -121
  478. nautobot/docs/development/core/navigation-menu.md +0 -142
  479. nautobot/docs/development/core/react-ui.md +0 -137
  480. nautobot/docs/development/core/release-checklist.md +0 -312
  481. nautobot/docs/development/core/role-internals.md +0 -28
  482. nautobot/docs/development/core/style-guide.md +0 -200
  483. nautobot/docs/development/core/templates.md +0 -101
  484. nautobot/docs/development/core/testing.md +0 -238
  485. nautobot/docs/development/core/user-preferences.md +0 -11
  486. nautobot/docs/development/index.md +0 -1
  487. nautobot/docs/development/jobs/index.md +0 -835
  488. nautobot/docs/development/jobs/migration/from-v1.md +0 -160
  489. nautobot/docs/generate_code_reference_pages.py +0 -20
  490. nautobot/docs/img/edge_dev_circuit_relationship.png +0 -0
  491. nautobot/docs/img/leaf_dev_no_circuit_relationship.png +0 -0
  492. nautobot/docs/img/relationship_w_json_filter.png +0 -0
  493. nautobot/docs/index.md +0 -105
  494. nautobot/docs/media/admin_ui_run_permission.png +0 -0
  495. nautobot/docs/media/development/homepage_changelog_panel.png +0 -0
  496. nautobot/docs/media/development/homepage_dcim_panel.png +0 -0
  497. nautobot/docs/media/development/index_bug_wf.jpg +0 -0
  498. nautobot/docs/media/development/index_feature_request_wf.jpg +0 -0
  499. nautobot/docs/media/development/index_release_cadence.drawio +0 -90
  500. nautobot/docs/media/development/index_release_cadence.jpg +0 -0
  501. nautobot/docs/media/installation/nautobot_ui_admin.png +0 -0
  502. nautobot/docs/media/installation/nautobot_ui_guest.png +0 -0
  503. nautobot/docs/media/models/dcim_cable_trace.png +0 -0
  504. nautobot/docs/media/models/dcim_cable_trace_circuit.png +0 -0
  505. nautobot/docs/media/models/dynamicgroup_filtering_01.png +0 -0
  506. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
  507. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
  508. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
  509. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
  510. nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
  511. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
  512. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
  513. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
  514. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
  515. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
  516. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
  517. nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
  518. nautobot/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
  519. nautobot/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
  520. nautobot/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
  521. nautobot/docs/media/models/jobbutton_form.png +0 -0
  522. nautobot/docs/media/models/site_jobbuttons.png +0 -0
  523. nautobot/docs/media/nautobot_application_stack_high_level.drawio +0 -1
  524. nautobot/docs/media/nautobot_application_stack_high_level.png +0 -0
  525. nautobot/docs/media/nautobot_application_stack_low_level.drawio +0 -1
  526. nautobot/docs/media/nautobot_application_stack_low_level.png +0 -0
  527. nautobot/docs/media/nautobot_chatops.gif +0 -0
  528. nautobot/docs/media/nautobot_config_context.gif +0 -0
  529. nautobot/docs/media/nautobot_golden_config.gif +0 -0
  530. nautobot/docs/media/nautobot_graphql.gif +0 -0
  531. nautobot/docs/media/nautobot_mainpage.gif +0 -0
  532. nautobot/docs/media/nautobot_prefix_hierarchy.gif +0 -0
  533. nautobot/docs/media/plugins/plugin_admin_config.png +0 -0
  534. nautobot/docs/media/plugins/plugin_admin_ui.png +0 -0
  535. nautobot/docs/media/plugins/plugin_rest_api_endpoint.png +0 -0
  536. nautobot/docs/media/power_distribution.png +0 -0
  537. nautobot/docs/media/ss_config_contexts.png +0 -0
  538. nautobot/docs/media/ss_graphiql.png +0 -0
  539. nautobot/docs/media/ss_main_page.png +0 -0
  540. nautobot/docs/media/ss_plugin_chatops.png +0 -0
  541. nautobot/docs/media/ss_plugin_golden_config.png +0 -0
  542. nautobot/docs/media/ss_prefix_hierarchy.png +0 -0
  543. nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-1.png +0 -0
  544. nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-2.png +0 -0
  545. nautobot/docs/media/user-guide/administration/upgrading/from-v1/ipam/tenant-affinity.png +0 -0
  546. nautobot/docs/nautobot_logo.png +0 -0
  547. nautobot/docs/nautobot_logo.svg +0 -131
  548. nautobot/docs/release-notes/index.md +0 -3
  549. nautobot/docs/release-notes/version-1.0.md +0 -530
  550. nautobot/docs/release-notes/version-1.1.md +0 -337
  551. nautobot/docs/release-notes/version-1.2.md +0 -509
  552. nautobot/docs/release-notes/version-1.3.md +0 -554
  553. nautobot/docs/release-notes/version-1.4.md +0 -677
  554. nautobot/docs/release-notes/version-1.5.md +0 -840
  555. nautobot/docs/release-notes/version-1.6.md +0 -290
  556. nautobot/docs/release-notes/version-2.0.md +0 -1359
  557. nautobot/docs/requirements.txt +0 -12
  558. nautobot/docs/user-guide/administration/configuration/authentication/ldap.md +0 -286
  559. nautobot/docs/user-guide/administration/configuration/authentication/remote.md +0 -46
  560. nautobot/docs/user-guide/administration/configuration/authentication/sso.md +0 -528
  561. nautobot/docs/user-guide/administration/configuration/index.md +0 -190
  562. nautobot/docs/user-guide/administration/configuration/node-configuration.md +0 -31
  563. nautobot/docs/user-guide/administration/configuration/optional-settings.md +0 -1302
  564. nautobot/docs/user-guide/administration/configuration/required-settings.md +0 -244
  565. nautobot/docs/user-guide/administration/guides/caching.md +0 -108
  566. nautobot/docs/user-guide/administration/guides/celery-queues.md +0 -42
  567. nautobot/docs/user-guide/administration/guides/healthcheck.md +0 -11
  568. nautobot/docs/user-guide/administration/guides/permissions.md +0 -98
  569. nautobot/docs/user-guide/administration/guides/prometheus-metrics.md +0 -55
  570. nautobot/docs/user-guide/administration/guides/replicating-nautobot.md +0 -70
  571. nautobot/docs/user-guide/administration/guides/s3-django-storage.md +0 -145
  572. nautobot/docs/user-guide/administration/installation/app-install.md +0 -94
  573. nautobot/docs/user-guide/administration/installation/docker.md +0 -286
  574. nautobot/docs/user-guide/administration/installation/external-authentication.md +0 -9
  575. nautobot/docs/user-guide/administration/installation/http-server.md +0 -279
  576. nautobot/docs/user-guide/administration/installation/index.md +0 -101
  577. nautobot/docs/user-guide/administration/installation/install_system.md +0 -493
  578. nautobot/docs/user-guide/administration/installation/nautobot.md +0 -367
  579. nautobot/docs/user-guide/administration/installation/selinux-troubleshooting.md +0 -194
  580. nautobot/docs/user-guide/administration/installation/services.md +0 -340
  581. nautobot/docs/user-guide/administration/migration/migrating-from-netbox.md +0 -336
  582. nautobot/docs/user-guide/administration/migration/migrating-from-postgresql.md +0 -122
  583. nautobot/docs/user-guide/administration/tools/nautobot-server.md +0 -858
  584. nautobot/docs/user-guide/administration/tools/nautobot-shell.md +0 -263
  585. nautobot/docs/user-guide/administration/upgrading/database-backup.md +0 -11
  586. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.md +0 -55
  587. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.md +0 -73
  588. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.md +0 -211
  589. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/index.md +0 -16
  590. nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.md +0 -157
  591. nautobot/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.md +0 -153
  592. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-behavior-changes.yaml +0 -82
  593. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-removed-fields.yaml +0 -175
  594. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-renamed-fields.yaml +0 -124
  595. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-location-changes.yaml +0 -241
  596. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-removals.yaml +0 -57
  597. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-renames.yaml +0 -5
  598. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-behavior-changes.yaml +0 -76
  599. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-removed-fields.yaml +0 -202
  600. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-renamed-fields.yaml +0 -343
  601. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-corrected-fields.yaml +0 -31
  602. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-enhanced-fields.yaml +0 -244
  603. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-removed-fields.yaml +0 -595
  604. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-renamed-fields.yaml +0 -253
  605. nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-logging-renamed-loggers.yaml +0 -23
  606. nautobot/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.md +0 -574
  607. nautobot/docs/user-guide/administration/upgrading/upgrading.md +0 -127
  608. nautobot/docs/user-guide/core-data-model/circuits/circuit.md +0 -19
  609. nautobot/docs/user-guide/core-data-model/circuits/circuittermination.md +0 -10
  610. nautobot/docs/user-guide/core-data-model/circuits/circuittype.md +0 -8
  611. nautobot/docs/user-guide/core-data-model/circuits/provider.md +0 -5
  612. nautobot/docs/user-guide/core-data-model/circuits/providernetwork.md +0 -7
  613. nautobot/docs/user-guide/core-data-model/dcim/cable.md +0 -43
  614. nautobot/docs/user-guide/core-data-model/dcim/consoleport.md +0 -8
  615. nautobot/docs/user-guide/core-data-model/dcim/consoleporttemplate.md +0 -6
  616. nautobot/docs/user-guide/core-data-model/dcim/consoleserverport.md +0 -8
  617. nautobot/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.md +0 -6
  618. nautobot/docs/user-guide/core-data-model/dcim/device.md +0 -29
  619. nautobot/docs/user-guide/core-data-model/dcim/devicebay.md +0 -11
  620. nautobot/docs/user-guide/core-data-model/dcim/devicebaytemplate.md +0 -6
  621. nautobot/docs/user-guide/core-data-model/dcim/deviceredundancygroup.md +0 -279
  622. nautobot/docs/user-guide/core-data-model/dcim/devicetype.md +0 -44
  623. nautobot/docs/user-guide/core-data-model/dcim/frontport.md +0 -6
  624. nautobot/docs/user-guide/core-data-model/dcim/frontporttemplate.md +0 -6
  625. nautobot/docs/user-guide/core-data-model/dcim/interface.md +0 -34
  626. nautobot/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.md +0 -24
  627. nautobot/docs/user-guide/core-data-model/dcim/interfacetemplate.md +0 -6
  628. nautobot/docs/user-guide/core-data-model/dcim/inventoryitem.md +0 -10
  629. nautobot/docs/user-guide/core-data-model/dcim/location.md +0 -15
  630. nautobot/docs/user-guide/core-data-model/dcim/locationtype.md +0 -43
  631. nautobot/docs/user-guide/core-data-model/dcim/manufacturer.md +0 -3
  632. nautobot/docs/user-guide/core-data-model/dcim/platform.md +0 -19
  633. nautobot/docs/user-guide/core-data-model/dcim/powerfeed.md +0 -25
  634. nautobot/docs/user-guide/core-data-model/dcim/poweroutlet.md +0 -14
  635. nautobot/docs/user-guide/core-data-model/dcim/poweroutlettemplate.md +0 -6
  636. nautobot/docs/user-guide/core-data-model/dcim/powerpanel.md +0 -12
  637. nautobot/docs/user-guide/core-data-model/dcim/powerport.md +0 -15
  638. nautobot/docs/user-guide/core-data-model/dcim/powerporttemplate.md +0 -6
  639. nautobot/docs/user-guide/core-data-model/dcim/rack.md +0 -41
  640. nautobot/docs/user-guide/core-data-model/dcim/rackgroup.md +0 -7
  641. nautobot/docs/user-guide/core-data-model/dcim/rackreservation.md +0 -3
  642. nautobot/docs/user-guide/core-data-model/dcim/rearport.md +0 -9
  643. nautobot/docs/user-guide/core-data-model/dcim/rearporttemplate.md +0 -6
  644. nautobot/docs/user-guide/core-data-model/dcim/virtualchassis.md +0 -8
  645. nautobot/docs/user-guide/core-data-model/extras/configcontext.md +0 -78
  646. nautobot/docs/user-guide/core-data-model/extras/configcontextschema.md +0 -73
  647. nautobot/docs/user-guide/core-data-model/ipam/ipaddress.md +0 -69
  648. nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +0 -1
  649. nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
  650. nautobot/docs/user-guide/core-data-model/ipam/namespace.md +0 -18
  651. nautobot/docs/user-guide/core-data-model/ipam/prefix.md +0 -65
  652. nautobot/docs/user-guide/core-data-model/ipam/rir.md +0 -10
  653. nautobot/docs/user-guide/core-data-model/ipam/routetarget.md +0 -5
  654. nautobot/docs/user-guide/core-data-model/ipam/service.md +0 -8
  655. nautobot/docs/user-guide/core-data-model/ipam/vlan.md +0 -17
  656. nautobot/docs/user-guide/core-data-model/ipam/vlangroup.md +0 -5
  657. nautobot/docs/user-guide/core-data-model/ipam/vrf.md +0 -15
  658. nautobot/docs/user-guide/core-data-model/tenancy/tenant.md +0 -20
  659. nautobot/docs/user-guide/core-data-model/tenancy/tenantgroup.md +0 -5
  660. nautobot/docs/user-guide/core-data-model/virtualization/cluster.md +0 -5
  661. nautobot/docs/user-guide/core-data-model/virtualization/clustergroup.md +0 -3
  662. nautobot/docs/user-guide/core-data-model/virtualization/clustertype.md +0 -3
  663. nautobot/docs/user-guide/core-data-model/virtualization/virtualmachine.md +0 -17
  664. nautobot/docs/user-guide/core-data-model/virtualization/vminterface.md +0 -19
  665. nautobot/docs/user-guide/feature-guides/custom-fields.md +0 -350
  666. nautobot/docs/user-guide/feature-guides/getting-started/creating-devices.md +0 -130
  667. nautobot/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.md +0 -113
  668. nautobot/docs/user-guide/feature-guides/getting-started/index.md +0 -29
  669. nautobot/docs/user-guide/feature-guides/getting-started/interfaces.md +0 -100
  670. nautobot/docs/user-guide/feature-guides/getting-started/ipam.md +0 -104
  671. nautobot/docs/user-guide/feature-guides/getting-started/platforms.md +0 -78
  672. nautobot/docs/user-guide/feature-guides/getting-started/search-bar.md +0 -40
  673. nautobot/docs/user-guide/feature-guides/getting-started/tenants.md +0 -40
  674. nautobot/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.md +0 -87
  675. nautobot/docs/user-guide/feature-guides/git-data-source.md +0 -307
  676. nautobot/docs/user-guide/feature-guides/graphql.md +0 -342
  677. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
  678. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
  679. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
  680. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
  681. nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
  682. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
  683. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
  684. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
  685. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
  686. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
  687. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
  688. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
  689. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
  690. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
  691. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
  692. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
  693. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
  694. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
  695. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
  696. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
  697. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
  698. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
  699. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
  700. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
  701. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
  702. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
  703. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
  704. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
  705. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
  706. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
  707. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
  708. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
  709. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
  710. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
  711. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
  712. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
  713. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
  714. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
  715. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
  716. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
  717. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
  718. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
  719. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
  720. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
  721. nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
  722. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
  723. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
  724. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
  725. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
  726. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
  727. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
  728. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
  729. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
  730. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
  731. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
  732. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
  733. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
  734. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
  735. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
  736. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
  737. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
  738. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
  739. nautobot/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
  740. nautobot/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
  741. nautobot/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
  742. nautobot/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
  743. nautobot/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
  744. nautobot/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
  745. nautobot/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
  746. nautobot/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
  747. nautobot/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
  748. nautobot/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
  749. nautobot/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
  750. nautobot/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
  751. nautobot/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
  752. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
  753. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
  754. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
  755. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
  756. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
  757. nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
  758. nautobot/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
  759. nautobot/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
  760. nautobot/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
  761. nautobot/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
  762. nautobot/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
  763. nautobot/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
  764. nautobot/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
  765. nautobot/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
  766. nautobot/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
  767. nautobot/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
  768. nautobot/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
  769. nautobot/docs/user-guide/feature-guides/ip-address-merge-tool.md +0 -63
  770. nautobot/docs/user-guide/feature-guides/relationships.md +0 -125
  771. nautobot/docs/user-guide/index.md +0 -1
  772. nautobot/docs/user-guide/platform-functionality/change-logging.md +0 -21
  773. nautobot/docs/user-guide/platform-functionality/computedfield.md +0 -89
  774. nautobot/docs/user-guide/platform-functionality/customfield.md +0 -123
  775. nautobot/docs/user-guide/platform-functionality/customlink.md +0 -59
  776. nautobot/docs/user-guide/platform-functionality/dynamicgroup.md +0 -660
  777. nautobot/docs/user-guide/platform-functionality/exporttemplate.md +0 -55
  778. nautobot/docs/user-guide/platform-functionality/gitrepository.md +0 -353
  779. nautobot/docs/user-guide/platform-functionality/graphql.md +0 -259
  780. nautobot/docs/user-guide/platform-functionality/graphqlquery.md +0 -28
  781. nautobot/docs/user-guide/platform-functionality/imageattachment.md +0 -10
  782. nautobot/docs/user-guide/platform-functionality/jobs/index.md +0 -193
  783. nautobot/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.md +0 -78
  784. nautobot/docs/user-guide/platform-functionality/jobs/jobbutton.md +0 -79
  785. nautobot/docs/user-guide/platform-functionality/jobs/jobhook.md +0 -15
  786. nautobot/docs/user-guide/platform-functionality/jobs/models.md +0 -65
  787. nautobot/docs/user-guide/platform-functionality/napalm.md +0 -85
  788. nautobot/docs/user-guide/platform-functionality/note.md +0 -7
  789. nautobot/docs/user-guide/platform-functionality/relationship.md +0 -158
  790. nautobot/docs/user-guide/platform-functionality/rest-api/authentication.md +0 -67
  791. nautobot/docs/user-guide/platform-functionality/rest-api/filtering.md +0 -142
  792. nautobot/docs/user-guide/platform-functionality/rest-api/overview.md +0 -1045
  793. nautobot/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.md +0 -9
  794. nautobot/docs/user-guide/platform-functionality/role.md +0 -17
  795. nautobot/docs/user-guide/platform-functionality/secret.md +0 -136
  796. nautobot/docs/user-guide/platform-functionality/status.md +0 -92
  797. nautobot/docs/user-guide/platform-functionality/tag.md +0 -62
  798. nautobot/docs/user-guide/platform-functionality/template-filters.md +0 -306
  799. nautobot/docs/user-guide/platform-functionality/users/objectpermission.md +0 -56
  800. nautobot/docs/user-guide/platform-functionality/users/token.md +0 -21
  801. nautobot/docs/user-guide/platform-functionality/webhook.md +0 -137
  802. nautobot/project-static/docs/media/nautobot_application_stack_low_level.drawio +0 -1
  803. nautobot/project-static/docs/media/nautobot_chatops.gif +0 -0
  804. nautobot/project-static/docs/media/nautobot_config_context.gif +0 -0
  805. nautobot/project-static/docs/media/nautobot_golden_config.gif +0 -0
  806. nautobot/project-static/docs/media/nautobot_graphql.gif +0 -0
  807. nautobot/project-static/docs/media/nautobot_mainpage.gif +0 -0
  808. nautobot/project-static/docs/media/nautobot_prefix_hierarchy.gif +0 -0
  809. nautobot-2.0.4.dist-info/LICENSE.txt +0 -177
  810. /LICENSE.txt → /nautobot-2.1.0b1.dist-info/LICENSE.txt +0 -0
  811. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/WHEEL +0 -0
  812. {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,3 @@
1
- from copy import deepcopy
2
1
  import csv
3
2
  from io import BytesIO, StringIO
4
3
  import json
@@ -6,6 +5,7 @@ from unittest import skip
6
5
 
7
6
  from django.contrib.contenttypes.models import ContentType
8
7
  from django.conf import settings
8
+ from django.contrib.auth import get_user_model
9
9
  from django.test import RequestFactory, override_settings, TestCase
10
10
  from django.urls import reverse
11
11
 
@@ -29,6 +29,9 @@ from nautobot.ipam import models as ipam_models
29
29
  from nautobot.ipam.api import serializers as ipam_serializers
30
30
 
31
31
 
32
+ User = get_user_model()
33
+
34
+
32
35
  class AppTest(testing.APITestCase):
33
36
  def test_root(self):
34
37
  url = reverse("api-root")
@@ -73,6 +76,9 @@ class APIDocsTestCase(TestCase):
73
76
  self.cf_text.save()
74
77
 
75
78
  def test_api_docs(self):
79
+ user = User.objects.create_user(username="nautobotuser")
80
+ self.client.force_login(user)
81
+
76
82
  url = reverse("api_docs")
77
83
  response = self.client.get(url)
78
84
  self.assertEqual(response.status_code, 200)
@@ -183,17 +189,6 @@ class APIVersioningTestCase(testing.APITestCase):
183
189
  Testing our custom API versioning, NautobotAPIVersioning.
184
190
  """
185
191
 
186
- OVERRIDE_REST_FRAMEWORK = deepcopy(settings.REST_FRAMEWORK)
187
- # For Nautobot 2.0, the default/only supported API version is 2.0, which limits our ability to test with multiple
188
- # or min/max versions. For test purposes we force there to be some extra versions available.
189
- EXTRA_ALLOWED_VERSIONS = [
190
- f"{settings.VERSION_MAJOR - 1}.99",
191
- *settings.REST_FRAMEWORK["ALLOWED_VERSIONS"],
192
- f"{settings.VERSION_MAJOR}.{settings.VERSION_MINOR + 1}",
193
- ]
194
- OVERRIDE_REST_FRAMEWORK["ALLOWED_VERSIONS"] = EXTRA_ALLOWED_VERSIONS
195
- OVERRIDE_REST_FRAMEWORK["DEFAULT_VERSION"] = EXTRA_ALLOWED_VERSIONS[-1]
196
-
197
192
  def test_default_version(self):
198
193
  """Test that a request with no specific API version gets the default version, which is the current version."""
199
194
  url = reverse("api-root")
@@ -203,13 +198,6 @@ class APIVersioningTestCase(testing.APITestCase):
203
198
  self.assertEqual(response["API-Version"], api_settings.DEFAULT_VERSION)
204
199
  self.assertEqual(response["API-Version"], f"{settings.VERSION_MAJOR}.{settings.VERSION_MINOR}")
205
200
 
206
- with override_settings(REST_FRAMEWORK=self.OVERRIDE_REST_FRAMEWORK):
207
- response = self.client.get(url, **self.header)
208
- self.assertHttpStatus(response, 200)
209
- self.assertIn("API-Version", response)
210
- self.assertEqual(response["API-Version"], self.OVERRIDE_REST_FRAMEWORK["DEFAULT_VERSION"])
211
- self.assertEqual(response["API-Version"], f"{settings.VERSION_MAJOR}.{settings.VERSION_MINOR + 1}")
212
-
213
201
  def test_allowed_versions(self):
214
202
  """Test that all expected versions are supported."""
215
203
  for minor_version in range(0, settings.VERSION_MINOR + 1):
@@ -237,7 +225,7 @@ class APIVersioningTestCase(testing.APITestCase):
237
225
  self.assertEqual(response["API-Version"], default_version)
238
226
 
239
227
  max_version = api_settings.ALLOWED_VERSIONS[-1]
240
- self.set_api_version(min_version)
228
+ self.set_api_version(max_version)
241
229
  response = self.client.get(url, **self.header)
242
230
  self.assertHttpStatus(response, 200)
243
231
  self.assertIn("API-Version", response)
@@ -250,29 +238,6 @@ class APIVersioningTestCase(testing.APITestCase):
250
238
  for version in api_settings.ALLOWED_VERSIONS:
251
239
  self.assertIn(version, response.data["detail"])
252
240
 
253
- # Also test with explicitly added additional allowed versions
254
- with override_settings(REST_FRAMEWORK=self.OVERRIDE_REST_FRAMEWORK):
255
- min_version = self.EXTRA_ALLOWED_VERSIONS[0]
256
- self.set_api_version(min_version)
257
- response = self.client.get(url, **self.header)
258
- self.assertHttpStatus(response, 200)
259
- self.assertIn("API-Version", response)
260
- self.assertEqual(response["API-Version"], min_version)
261
-
262
- max_version = self.EXTRA_ALLOWED_VERSIONS[-1]
263
- self.set_api_version(max_version)
264
- response = self.client.get(url, **self.header)
265
- self.assertHttpStatus(response, 200)
266
- self.assertIn("API-Version", response)
267
- self.assertEqual(response["API-Version"], max_version)
268
-
269
- invalid_version = "0.0"
270
- self.set_api_version(invalid_version)
271
- response = self.client.get(url, **self.header)
272
- self.assertHttpStatus(response, 406) # Not Acceptable
273
- for version in self.EXTRA_ALLOWED_VERSIONS:
274
- self.assertIn(version, response.data["detail"])
275
-
276
241
  def test_query_version(self):
277
242
  """Test that the API version can be specified via a query parameter."""
278
243
  url = reverse("api-root")
@@ -301,33 +266,12 @@ class APIVersioningTestCase(testing.APITestCase):
301
266
  for version in api_settings.ALLOWED_VERSIONS:
302
267
  self.assertIn(version, response.data["detail"])
303
268
 
304
- # Also test with explicitly added additional allowed versions
305
- with override_settings(REST_FRAMEWORK=self.OVERRIDE_REST_FRAMEWORK):
306
- min_version = self.EXTRA_ALLOWED_VERSIONS[0]
307
- response = self.client.get(f"{url}?api_version={min_version}", **self.header)
308
- self.assertHttpStatus(response, 200)
309
- self.assertIn("API-Version", response)
310
- self.assertEqual(response["API-Version"], min_version)
311
-
312
- max_version = self.EXTRA_ALLOWED_VERSIONS[-1]
313
- response = self.client.get(f"{url}?api_version={max_version}", **self.header)
314
- self.assertHttpStatus(response, 200)
315
- self.assertIn("API-Version", response)
316
- self.assertEqual(response["API-Version"], max_version)
317
-
318
- invalid_version = "0.0"
319
- response = self.client.get(f"{url}?api_version={invalid_version}", **self.header)
320
- self.assertHttpStatus(response, 404)
321
- for version in self.EXTRA_ALLOWED_VERSIONS:
322
- self.assertIn(version, response.data["detail"])
323
-
324
- @override_settings(REST_FRAMEWORK=OVERRIDE_REST_FRAMEWORK)
325
269
  def test_header_and_query_version(self):
326
270
  """Test the behavior when the API version is specified in both the Accept header *and* a query parameter."""
327
271
  url = reverse("api-root")
328
272
 
329
- min_version = self.EXTRA_ALLOWED_VERSIONS[0]
330
- max_version = self.EXTRA_ALLOWED_VERSIONS[-1]
273
+ min_version = api_settings.ALLOWED_VERSIONS[0]
274
+ max_version = api_settings.ALLOWED_VERSIONS[-1]
331
275
  # Specify same version both as Accept header and as query parameter (valid)
332
276
  self.set_api_version(max_version)
333
277
  response = self.client.get(f"{url}?api_version={max_version}", **self.header)
@@ -873,6 +817,9 @@ class APIOrderingTestCase(testing.APITestCase):
873
817
  class NewUIGetMenuAPIViewTestCase(testing.APITestCase):
874
818
  def test_get_menu(self):
875
819
  """Asset response from new ui nav menu api returns a well formatted registry["new_ui_nav_menu"] expected by nautobot-ui."""
820
+ self.user.is_superuser = True
821
+ self.user.save()
822
+
876
823
  url = reverse("ui-api:get-menu")
877
824
  response = self.client.get(url, **self.header)
878
825
  expected_response = {
@@ -975,6 +922,7 @@ class NewUIGetMenuAPIViewTestCase(testing.APITestCase):
975
922
  },
976
923
  },
977
924
  }
925
+
978
926
  self.assertEqual(response.status_code, 200)
979
927
  self.assertEqual(response.data, expected_response)
980
928
 
@@ -1,3 +1,5 @@
1
+ import datetime
2
+
1
3
  from django.conf import settings
2
4
  from django.contrib.auth import get_user_model
3
5
  from django.contrib.contenttypes.models import ContentType
@@ -9,6 +11,8 @@ from django.test.utils import isolate_apps
9
11
  import django_filters
10
12
  from tree_queries.models import TreeNodeForeignKey
11
13
 
14
+ from nautobot.circuits.filters import CircuitFilterSet
15
+ from nautobot.circuits.models import Circuit, CircuitType, Provider
12
16
  from nautobot.core import filters, testing
13
17
  from nautobot.core.models import fields as core_fields
14
18
  from nautobot.core.utils import lookup
@@ -1450,6 +1454,129 @@ class SearchFilterTest(TestCase, testing.NautobotTestCaseMixin):
1450
1454
  q = filters.SearchFilter(filter_predicates={"asn": ["icontains"]})
1451
1455
 
1452
1456
 
1457
+ class LookupIsNullTest(TestCase, testing.NautobotTestCaseMixin):
1458
+ """
1459
+ Validate isnull is properly applied and filtering.
1460
+ """
1461
+
1462
+ platform_queryset = dcim_models.Platform.objects.all()
1463
+ platform_filterset = dcim_filters.PlatformFilterSet
1464
+ circuit_queryset = Circuit.objects.all()
1465
+ circuit_filterset = CircuitFilterSet
1466
+ device_queryset = dcim_models.Device.objects.all()
1467
+ device_filterset = dcim_filters.DeviceFilterSet
1468
+
1469
+ @classmethod
1470
+ def setUpTestData(cls):
1471
+ location_type = dcim_models.LocationType.objects.create(name="Location Type 1")
1472
+ location_status = extras_models.Status.objects.get_for_model(dcim_models.Location).first()
1473
+ location = dcim_models.Location.objects.create(
1474
+ name="Location 1",
1475
+ location_type=location_type,
1476
+ status=location_status,
1477
+ )
1478
+ manufacturer = dcim_models.Manufacturer.objects.create(name="Manufacturer 1")
1479
+ dcim_models.Platform.objects.create(name="Platform 1")
1480
+ platform = dcim_models.Platform.objects.create(name="Platform 2", manufacturer=manufacturer)
1481
+
1482
+ device_type = dcim_models.DeviceType.objects.create(
1483
+ manufacturer=manufacturer,
1484
+ model="Model 1",
1485
+ is_full_depth=True,
1486
+ )
1487
+ device_role = extras_models.Role.objects.create(name="Active Test")
1488
+ device_role.content_types.add(ContentType.objects.get_for_model(dcim_models.Device))
1489
+
1490
+ device_status = extras_models.Status.objects.get_for_model(dcim_models.Device).first()
1491
+
1492
+ dcim_models.Device.objects.create(
1493
+ name="Device 1",
1494
+ device_type=device_type,
1495
+ role=device_role,
1496
+ platform=platform,
1497
+ location=location,
1498
+ status=device_status,
1499
+ )
1500
+ dcim_models.Device.objects.create(
1501
+ device_type=device_type,
1502
+ role=device_role,
1503
+ platform=platform,
1504
+ location=location,
1505
+ status=device_status,
1506
+ )
1507
+
1508
+ provider = Provider.objects.create(name="provider 1", asn=1)
1509
+ circuit_type = CircuitType.objects.create(name="Circuit Type 1")
1510
+ circuit_status = extras_models.Status.objects.get_for_model(dcim_models.Location).first()
1511
+
1512
+ Circuit.objects.create(
1513
+ cid="Circuit 1",
1514
+ provider=provider,
1515
+ install_date=datetime.date(2020, 1, 1),
1516
+ commit_rate=1000,
1517
+ circuit_type=circuit_type,
1518
+ status=circuit_status,
1519
+ )
1520
+ Circuit.objects.create(
1521
+ cid="Circuit 2",
1522
+ provider=provider,
1523
+ circuit_type=circuit_type,
1524
+ status=circuit_status,
1525
+ )
1526
+
1527
+ def test_isnull_on_fk(self):
1528
+ """Test that the `isnull` filter is applied for True and False queries on foreign key fields."""
1529
+ params = {"manufacturer__isnull": True}
1530
+ self.assertQuerysetEqualAndNotEmpty(
1531
+ dcim_filters.PlatformFilterSet(params, self.platform_queryset).qs,
1532
+ dcim_models.Platform.objects.filter(manufacturer__isnull=True),
1533
+ )
1534
+ params = {"manufacturer__isnull": False}
1535
+ self.assertQuerysetEqualAndNotEmpty(
1536
+ dcim_filters.PlatformFilterSet(params, self.platform_queryset).qs,
1537
+ dcim_models.Platform.objects.filter(manufacturer__isnull=False),
1538
+ )
1539
+
1540
+ def test_isnull_on_integer(self):
1541
+ """Test that the `isnull` filter is applied for True and False queries on integer fields."""
1542
+ params = {"commit_rate__isnull": True}
1543
+ self.assertQuerysetEqualAndNotEmpty(
1544
+ CircuitFilterSet(params, self.circuit_queryset).qs,
1545
+ Circuit.objects.filter(commit_rate__isnull=True),
1546
+ )
1547
+ params = {"commit_rate__isnull": False}
1548
+ self.assertQuerysetEqualAndNotEmpty(
1549
+ CircuitFilterSet(params, self.circuit_queryset).qs,
1550
+ Circuit.objects.filter(commit_rate__isnull=False),
1551
+ )
1552
+
1553
+ def test_isnull_on_date(self):
1554
+ """Test that the `isnull` filter is applied for True and False queries on datetime fields."""
1555
+ params = {"install_date__isnull": True}
1556
+ self.assertQuerysetEqualAndNotEmpty(
1557
+ CircuitFilterSet(params, self.circuit_queryset).qs,
1558
+ Circuit.objects.filter(install_date__isnull=True),
1559
+ )
1560
+ params = {"install_date__isnull": False}
1561
+ self.assertQuerysetEqualAndNotEmpty(
1562
+ CircuitFilterSet(params, self.circuit_queryset).qs,
1563
+ Circuit.objects.filter(install_date__isnull=False),
1564
+ )
1565
+
1566
+ def test_isnull_on_char(self):
1567
+ """Test that the `isnull` filter is applied for True and False queries on char fields."""
1568
+ params = {"name__isnull": True}
1569
+ self.assertQuerysetEqualAndNotEmpty(
1570
+ dcim_filters.DeviceFilterSet(params, self.device_queryset).qs,
1571
+ dcim_models.Device.objects.filter(name__isnull=True),
1572
+ )
1573
+ params = {"name__isnull": False}
1574
+ self.assertQuerysetEqualAndNotEmpty(
1575
+ dcim_filters.DeviceFilterSet(params, self.device_queryset).qs,
1576
+ dcim_models.Device.objects.filter(name__isnull=False),
1577
+ )
1578
+
1579
+
1453
1580
  class FilterTypeTest(TestCase):
1454
1581
  client_class = testing.NautobotTestClient
1455
1582
 
@@ -687,7 +687,7 @@ class DynamicFilterFormTest(TestCase):
687
687
  ("racks", "Rack (name or ID)"),
688
688
  ("rack_groups", "Rack groups (name or ID)"),
689
689
  ("shipping_address", "Shipping address"),
690
- ("status", "Status"),
690
+ ("status", "Status (name or ID)"),
691
691
  ("vlans", "Tagged VLANs (VID or ID)"),
692
692
  ("tags", "Tags"),
693
693
  ("tenant_id", 'Tenant (ID) (deprecated, use "tenant" filter instead)'),
@@ -805,9 +805,9 @@ class DynamicFilterFormTest(TestCase):
805
805
  },
806
806
  )
807
807
 
808
- with self.subTest("Test for lookup_value with a NullBooleanField and StaticSelect2 widget"):
808
+ with self.subTest("Test for lookup_value with a ChoiceField and StaticSelect2 widget"):
809
809
  # If `lookup_field` value is a boolean filter and `lookup_type` lookup expr is `exact`, then
810
- # `lookup_value` field should be a NullBooleanField with StaticSelect2 widget
810
+ # `lookup_value` field should be a ChoiceField with StaticSelect2 widget
811
811
  form = forms.DynamicFilterForm(filterset=location_filterset, data=data, prefix="form-2")
812
812
  self.assertEqual(
813
813
  form.fields["lookup_type"].widget.attrs,
@@ -819,7 +819,7 @@ class DynamicFilterFormTest(TestCase):
819
819
  "placeholder": None,
820
820
  },
821
821
  )
822
- self.assertIsInstance(form.fields["lookup_value"], django_forms.NullBooleanField)
822
+ self.assertIsInstance(form.fields["lookup_value"], django_forms.ChoiceField)
823
823
  self.assertEqual(
824
824
  form.fields["lookup_value"].widget.attrs,
825
825
  {"class": "form-control nautobot-select2-static lookup_value-input form-control"},
@@ -47,6 +47,8 @@ from nautobot.dcim.models import (
47
47
  DeviceType,
48
48
  FrontPort,
49
49
  Interface,
50
+ InterfaceRedundancyGroup,
51
+ InterfaceRedundancyGroupAssociation,
50
52
  Location,
51
53
  LocationType,
52
54
  PowerFeed,
@@ -70,7 +72,16 @@ from nautobot.extras.models import (
70
72
  )
71
73
  from nautobot.extras.registry import registry
72
74
  from nautobot.ipam.factory import VLANGroupFactory
73
- from nautobot.ipam.models import IPAddress, VLAN, Namespace, Prefix
75
+ from nautobot.ipam.models import (
76
+ IPAddress,
77
+ IPAddressToInterface,
78
+ Namespace,
79
+ Prefix,
80
+ VLAN,
81
+ VRF,
82
+ VRFDeviceAssignment,
83
+ VRFPrefixAssignment,
84
+ )
74
85
  from nautobot.users.models import ObjectPermission, Token
75
86
  from nautobot.tenancy.models import Tenant
76
87
  from nautobot.virtualization.factory import ClusterTypeFactory
@@ -834,9 +845,55 @@ class GraphQLQueryTest(TestCase):
834
845
  device=cls.device1,
835
846
  status=interface_status,
836
847
  )
848
+ cls.namespace = Namespace.objects.first()
849
+ cls.intr_group_status = Status.objects.get_for_model(InterfaceRedundancyGroup).first()
850
+ cls.interface_redundancy_group_1 = InterfaceRedundancyGroup.objects.create(
851
+ name="IRGroup 1",
852
+ status=cls.intr_group_status,
853
+ )
854
+ cls.interface_redundancy_group_2 = InterfaceRedundancyGroup.objects.create(
855
+ name="IRGroup 2",
856
+ status=cls.intr_group_status,
857
+ )
858
+ cls.interface_redundancy_group_3 = InterfaceRedundancyGroup.objects.create(
859
+ name="IRGroup 3",
860
+ status=cls.intr_group_status,
861
+ )
862
+ cls.irg_associations = (
863
+ InterfaceRedundancyGroupAssociation.objects.create(
864
+ interface_redundancy_group=cls.interface_redundancy_group_1,
865
+ interface=cls.interface11,
866
+ priority=123,
867
+ ),
868
+ InterfaceRedundancyGroupAssociation.objects.create(
869
+ interface_redundancy_group=cls.interface_redundancy_group_2,
870
+ interface=cls.interface12,
871
+ priority=456,
872
+ ),
873
+ InterfaceRedundancyGroupAssociation.objects.create(
874
+ interface_redundancy_group=cls.interface_redundancy_group_3,
875
+ interface=cls.interface11,
876
+ priority=789,
877
+ ),
878
+ InterfaceRedundancyGroupAssociation.objects.create(
879
+ interface_redundancy_group=cls.interface_redundancy_group_3,
880
+ interface=cls.interface12,
881
+ priority=789,
882
+ ),
883
+ )
884
+ prefixes = Prefix.objects.all()[:2]
885
+ cls.namespace = prefixes[0].namespace
886
+ vrfs = (
887
+ VRF.objects.create(name="VRF 1", rd="65000:100", namespace=cls.namespace),
888
+ VRF.objects.create(name="VRF 2", rd="65000:200", namespace=cls.namespace),
889
+ )
890
+ prefixes[0].vrfs.add(vrfs[0])
891
+ prefixes[0].vrfs.add(vrfs[1])
892
+ prefixes[1].vrfs.add(vrfs[0])
893
+ prefixes[1].vrfs.add(vrfs[1])
894
+
837
895
  cls.ip_statuses = list(Status.objects.get_for_model(IPAddress))[:2]
838
896
  cls.prefix_statuses = list(Status.objects.get_for_model(Prefix))[:2]
839
- cls.namespace = Namespace.objects.first()
840
897
  cls.prefix1 = Prefix.objects.create(
841
898
  prefix="10.0.1.0/24", namespace=cls.namespace, status=cls.prefix_statuses[0]
842
899
  )
@@ -855,6 +912,10 @@ class GraphQLQueryTest(TestCase):
855
912
  tenant=cls.tenant2,
856
913
  face="rear",
857
914
  )
915
+ cls.device2.vrfs.add(vrfs[0])
916
+ cls.device2.vrfs.add(vrfs[1])
917
+ cls.device2.vrfs.add(vrfs[0])
918
+ cls.device2.vrfs.add(vrfs[1])
858
919
 
859
920
  cls.interface21 = Interface.objects.create(
860
921
  name="Int1",
@@ -1178,6 +1239,108 @@ query {
1178
1239
  # Assert GraphQL returned properties match those expected
1179
1240
  self.assertEqual(console_port_entry["connected_console_server_port"], connected_console_server_port)
1180
1241
 
1242
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
1243
+ def test_interface_redundancy_group_associations(self):
1244
+ """Test graphql functionality for InterfaceRedundancyGroupAssociation"""
1245
+
1246
+ query = """\
1247
+ query {
1248
+ interface_redundancy_group_associations {
1249
+ id
1250
+ interface { id }
1251
+ interface_redundancy_group { id }
1252
+ priority
1253
+ }
1254
+ }"""
1255
+
1256
+ result = self.execute_query(query)
1257
+ self.assertIsNone(result.errors)
1258
+ self.assertEqual(
1259
+ len(InterfaceRedundancyGroupAssociation.objects.all()),
1260
+ len(result.data["interface_redundancy_group_associations"]),
1261
+ )
1262
+ for association in result.data["interface_redundancy_group_associations"]:
1263
+ association_obj = InterfaceRedundancyGroupAssociation.objects.get(id=association["id"])
1264
+ # Assert GraphQL returned properties match those expected
1265
+ self.assertEqual(association["interface"]["id"], str(association_obj.interface.pk))
1266
+ self.assertEqual(
1267
+ association["interface_redundancy_group"]["id"], str(association_obj.interface_redundancy_group.pk)
1268
+ )
1269
+ self.assertEqual(association["priority"], association_obj.priority)
1270
+
1271
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
1272
+ def test_ip_address_to_interface(self):
1273
+ """Test graphql functionality for IPAddressToInterface"""
1274
+
1275
+ query = """\
1276
+ query {
1277
+ ip_address_assignments {
1278
+ id
1279
+ interface { id }
1280
+ vm_interface { id }
1281
+ ip_address { id }
1282
+ }
1283
+ }"""
1284
+
1285
+ result = self.execute_query(query)
1286
+ self.assertIsNone(result.errors)
1287
+ self.assertEqual(
1288
+ len(IPAddressToInterface.objects.all()),
1289
+ len(result.data["ip_address_assignments"]),
1290
+ )
1291
+ for association in result.data["ip_address_assignments"]:
1292
+ association_obj = IPAddressToInterface.objects.get(id=association["id"])
1293
+ # Assert GraphQL returned properties match those expected
1294
+ if association_obj.interface:
1295
+ self.assertEqual(association["interface"]["id"], str(association_obj.interface.pk))
1296
+ else:
1297
+ self.assertEqual(association["interface"], None)
1298
+ if association_obj.vm_interface:
1299
+ self.assertEqual(association["vm_interface"]["id"], str(association_obj.vm_interface.pk))
1300
+ else:
1301
+ self.assertEqual(association["vm_interface"], None)
1302
+ self.assertEqual(association["ip_address"]["id"], str(association_obj.ip_address.pk))
1303
+
1304
+ @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
1305
+ def test_vrf_assignments(self):
1306
+ """Test graphql functionality for VRFDeviceAssignment and VRFPrefixAssignment"""
1307
+
1308
+ query = """\
1309
+ query {
1310
+ vrf_device_assignments {
1311
+ id
1312
+ vrf { id }
1313
+ device { id }
1314
+ }
1315
+ vrf_prefix_assignments {
1316
+ id
1317
+ vrf { id }
1318
+ prefix { id }
1319
+ }
1320
+ }"""
1321
+
1322
+ result = self.execute_query(query)
1323
+ self.assertIsNone(result.errors)
1324
+ self.assertEqual(
1325
+ len(VRFDeviceAssignment.objects.all()),
1326
+ len(result.data["vrf_device_assignments"]),
1327
+ )
1328
+ self.assertEqual(
1329
+ len(VRFPrefixAssignment.objects.all()),
1330
+ len(result.data["vrf_prefix_assignments"]),
1331
+ )
1332
+ for assignment in result.data["vrf_device_assignments"]:
1333
+ assignment_obj = VRFDeviceAssignment.objects.get(id=assignment["id"])
1334
+ # Assert GraphQL returned properties match those expected
1335
+ self.assertEqual(assignment["vrf"]["id"], str(assignment_obj.vrf.pk))
1336
+ self.assertEqual(assignment["device"]["id"], str(assignment_obj.device.pk))
1337
+
1338
+ for assignment in result.data["vrf_prefix_assignments"]:
1339
+ assignment_obj = VRFPrefixAssignment.objects.get(id=assignment["id"])
1340
+ # Assert GraphQL returned properties match those expected
1341
+ self.assertEqual(assignment["vrf"]["id"], str(assignment_obj.vrf.pk))
1342
+ self.assertEqual(assignment["prefix"]["id"], str(assignment_obj.prefix.pk))
1343
+
1181
1344
  @override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
1182
1345
  def test_query_console_server_ports_cable_peer(self):
1183
1346
  """Test querying console server port terminations for their cable peers"""
@@ -0,0 +1,112 @@
1
+ from pathlib import Path
2
+
3
+ from django.contrib.contenttypes.models import ContentType
4
+ import yaml
5
+
6
+ from nautobot.core.testing import TransactionTestCase, create_job_result_and_run_job
7
+ from nautobot.dcim.models import DeviceType, Manufacturer
8
+ from nautobot.extras.choices import JobResultStatusChoices, LogLevelChoices
9
+ from nautobot.extras.models import ExportTemplate, JobLogEntry, Status
10
+ from nautobot.users.models import ObjectPermission
11
+
12
+
13
+ class ExportObjectListTest(TransactionTestCase):
14
+ """
15
+ Test the ExportObjectList system job.
16
+ """
17
+
18
+ databases = ("default", "job_logs")
19
+
20
+ def test_export_without_permission(self):
21
+ """Job should enforce user permissions on the content-type being asked for export."""
22
+ job_result = create_job_result_and_run_job(
23
+ "nautobot.core.jobs",
24
+ "ExportObjectList",
25
+ username=self.user.username, # otherwise run_job_for_testing defaults to a superuser account
26
+ content_type=ContentType.objects.get_for_model(Status).pk,
27
+ )
28
+ self.assertEqual(job_result.status, JobResultStatusChoices.STATUS_FAILURE)
29
+ log_error = JobLogEntry.objects.get(job_result=job_result, log_level=LogLevelChoices.LOG_ERROR)
30
+ self.assertEqual(log_error.message, f'User "{self.user}" does not have permission to view status objects')
31
+ self.assertFalse(job_result.files.exists())
32
+
33
+ def test_export_with_constrained_permission(self):
34
+ """Job should only allow the user to export objects they have permission to view."""
35
+ instance1, instance2 = Status.objects.all()[:2]
36
+ obj_perm = ObjectPermission(
37
+ name="Test permission",
38
+ constraints={"pk": instance1.pk},
39
+ actions=["view"],
40
+ )
41
+ obj_perm.save()
42
+ obj_perm.users.add(self.user)
43
+ obj_perm.object_types.add(ContentType.objects.get_for_model(Status))
44
+ job_result = create_job_result_and_run_job(
45
+ "nautobot.core.jobs",
46
+ "ExportObjectList",
47
+ username=self.user.username, # otherwise run_job_for_testing defaults to a superuser account
48
+ content_type=ContentType.objects.get_for_model(Status).pk,
49
+ )
50
+ self.assertEqual(job_result.status, JobResultStatusChoices.STATUS_SUCCESS)
51
+ self.assertTrue(job_result.files.exists())
52
+ self.assertEqual(Path(job_result.files.first().file.name).name, "nautobot_statuses.csv")
53
+ csv_data = job_result.files.first().file.read().decode("utf-8")
54
+ self.assertIn(str(instance1.pk), csv_data)
55
+ self.assertNotIn(str(instance2.pk), csv_data)
56
+
57
+ def test_export_all_to_csv(self):
58
+ """By default, job should export all instances to CSV."""
59
+ job_result = create_job_result_and_run_job(
60
+ "nautobot.core.jobs",
61
+ "ExportObjectList",
62
+ content_type=ContentType.objects.get_for_model(Status).pk,
63
+ )
64
+ self.assertEqual(job_result.status, JobResultStatusChoices.STATUS_SUCCESS)
65
+ self.assertTrue(job_result.files.exists())
66
+ self.assertEqual(Path(job_result.files.first().file.name).name, "nautobot_statuses.csv")
67
+ csv_data = job_result.files.first().file.read().decode("utf-8")
68
+ # May be more than one line per Status if they have newlines in their description strings
69
+ self.assertGreaterEqual(len(csv_data.split("\n")), Status.objects.count() + 1, csv_data) # +1 for CSV header
70
+
71
+ def test_export_all_via_export_template(self):
72
+ """When an export-template is specified, it should be used."""
73
+ et = ExportTemplate.objects.create(
74
+ content_type=ContentType.objects.get_for_model(Status),
75
+ name="Simple Export Template",
76
+ template_code="{% for obj in queryset %}{{ obj.name }}\n{% endfor %}",
77
+ file_extension="txt",
78
+ )
79
+ job_result = create_job_result_and_run_job(
80
+ "nautobot.core.jobs",
81
+ "ExportObjectList",
82
+ content_type=ContentType.objects.get_for_model(Status).pk,
83
+ export_template=et.pk,
84
+ )
85
+ self.assertEqual(job_result.status, JobResultStatusChoices.STATUS_SUCCESS)
86
+ self.assertTrue(job_result.files.exists())
87
+ self.assertEqual(Path(job_result.files.first().file.name).name, "nautobot_statuses.txt")
88
+ text_data = job_result.files.first().file.read().decode("utf-8")
89
+ self.assertEqual(len(text_data.split("\n")), Status.objects.count() + 1)
90
+ for status in Status.objects.iterator():
91
+ self.assertIn(status.name, text_data)
92
+
93
+ def test_export_devicetype_to_yaml(self):
94
+ """Export device-type to YAML."""
95
+ mfr = Manufacturer.objects.create(name="Cisco")
96
+ DeviceType.objects.create(
97
+ manufacturer=mfr,
98
+ model="Cisco CSR1000v",
99
+ u_height=0,
100
+ )
101
+ job_result = create_job_result_and_run_job(
102
+ "nautobot.core.jobs",
103
+ "ExportObjectList",
104
+ content_type=ContentType.objects.get_for_model(DeviceType).pk,
105
+ export_format="yaml",
106
+ )
107
+ self.assertEqual(job_result.status, JobResultStatusChoices.STATUS_SUCCESS)
108
+ self.assertTrue(job_result.files.exists())
109
+ self.assertEqual(Path(job_result.files.first().file.name).name, "nautobot_device_types.yaml")
110
+ yaml_data = job_result.files.first().file.read().decode("utf-8")
111
+ data = yaml.safe_load(yaml_data)
112
+ self.assertEqual(data["manufacturer"], "Cisco")
@@ -41,6 +41,9 @@ class OpenAPITest(TestCase):
41
41
  query_params = self.schema["paths"]["/dcim/devices/"]["get"]["parameters"]
42
42
  at_least_one_test = False
43
43
  for query_param_info in query_params:
44
+ if query_param_info["name"].endswith("_isnull"):
45
+ # The broad catch below does not apply to isnull, which will return a boolean.
46
+ continue
44
47
  if query_param_info["name"].startswith("created") or query_param_info["name"].startswith("last_updated"):
45
48
  self.assertEqual("array", query_param_info["schema"]["type"])
46
49
  self.assertEqual("string", query_param_info["schema"]["items"]["type"])
@@ -57,6 +60,9 @@ class OpenAPITest(TestCase):
57
60
  query_params = self.schema["paths"]["/dcim/devices/"]["get"]["parameters"]
58
61
  at_least_one_test = False
59
62
  for query_param_info in query_params:
63
+ if query_param_info["name"].endswith("_isnull"):
64
+ # The broad catch below does not apply to isnull, which will return a boolean.
65
+ continue
60
66
  if query_param_info["name"].startswith("device_redundancy_group_priority"):
61
67
  self.assertEqual("array", query_param_info["schema"]["type"])
62
68
  self.assertEqual("integer", query_param_info["schema"]["items"]["type"])