nautobot 2.2.0b1__py3-none-any.whl → 2.2.1__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.
- nautobot/__init__.py +31 -0
- nautobot/apps/api.py +1 -2
- nautobot/apps/utils.py +4 -0
- nautobot/apps/views.py +2 -0
- nautobot/circuits/api/urls.py +1 -2
- nautobot/circuits/api/views.py +0 -12
- nautobot/circuits/apps.py +1 -1
- nautobot/circuits/tests/test_filters.py +1 -1
- nautobot/core/api/routers.py +50 -3
- nautobot/core/api/utils.py +4 -0
- nautobot/core/api/views.py +21 -15
- nautobot/core/cli/__init__.py +18 -11
- nautobot/core/constants.py +85 -0
- nautobot/core/filters.py +7 -1
- nautobot/core/forms/widgets.py +1 -2
- nautobot/core/graphql/schema.py +1 -0
- nautobot/core/management/commands/generate_test_data.py +4 -4
- nautobot/core/models/__init__.py +1 -0
- nautobot/core/settings.py +24 -3
- nautobot/core/settings.yaml +20 -0
- nautobot/core/signals.py +1 -0
- nautobot/core/tables.py +2 -1
- nautobot/core/templates/admin/base.html +23 -94
- nautobot/core/templates/generic/object_retrieve.html +2 -2
- nautobot/core/templates/graphene/graphiql.html +18 -47
- nautobot/core/templates/inc/footer.html +5 -5
- nautobot/core/templates/inc/javascript.html +4 -4
- nautobot/core/templates/inc/media.html +2 -2
- nautobot/core/templates/inc/nav_menu.html +0 -7
- nautobot/core/templates/nautobot_config.py.j2 +14 -1
- nautobot/core/templates/rest_framework/api.html +12 -5
- nautobot/core/templatetags/helpers.py +2 -2
- nautobot/core/testing/__init__.py +1 -1
- nautobot/core/testing/filters.py +1 -1
- nautobot/core/testing/views.py +30 -0
- nautobot/core/tests/integration/test_view_authentication.py +68 -0
- nautobot/core/tests/test_api.py +13 -6
- nautobot/core/tests/test_csv.py +5 -4
- nautobot/core/tests/test_filters.py +2 -1
- nautobot/core/tests/test_graphql.py +4 -14
- nautobot/core/tests/test_navigations.py +3 -0
- nautobot/core/tests/test_views.py +44 -16
- nautobot/core/utils/data.py +1 -2
- nautobot/core/utils/lookup.py +126 -0
- nautobot/core/views/__init__.py +3 -7
- nautobot/core/views/generic.py +20 -6
- nautobot/core/views/mixins.py +7 -1
- nautobot/core/views/renderers.py +11 -6
- nautobot/dcim/api/serializers.py +4 -4
- nautobot/dcim/api/urls.py +2 -3
- nautobot/dcim/api/views.py +7 -18
- nautobot/dcim/apps.py +8 -4
- nautobot/dcim/elevations.py +5 -1
- nautobot/dcim/factory.py +7 -7
- nautobot/dcim/filters/__init__.py +16 -17
- nautobot/dcim/forms.py +61 -45
- nautobot/dcim/homepage.py +11 -3
- nautobot/dcim/management/commands/migrate_location_contacts.py +218 -0
- nautobot/dcim/migrations/0057_controller_models.py +11 -70
- nautobot/dcim/models/__init__.py +2 -2
- nautobot/dcim/models/devices.py +14 -16
- nautobot/dcim/models/racks.py +1 -3
- nautobot/dcim/navigation.py +23 -31
- nautobot/dcim/signals.py +6 -6
- nautobot/dcim/tables/__init__.py +2 -2
- nautobot/dcim/tables/devices.py +13 -16
- nautobot/dcim/tables/template_code.py +1 -1
- nautobot/dcim/templates/dcim/controller_create.html +70 -0
- nautobot/dcim/templates/dcim/controller_retrieve.html +35 -18
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +88 -0
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +75 -43
- nautobot/dcim/templates/dcim/device.html +11 -3
- nautobot/dcim/templates/dcim/device_edit.html +1 -1
- nautobot/dcim/templates/dcim/devicefamily_retrieve.html +4 -0
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +1 -1
- nautobot/dcim/tests/test_api.py +47 -6
- nautobot/dcim/tests/test_filters.py +92 -81
- nautobot/dcim/tests/test_graphql.py +11 -1
- nautobot/dcim/tests/test_models.py +15 -15
- nautobot/dcim/tests/test_signals.py +3 -1
- nautobot/dcim/tests/test_views.py +24 -12
- nautobot/dcim/urls.py +1 -1
- nautobot/dcim/views.py +25 -15
- nautobot/extras/api/serializers.py +20 -1
- nautobot/extras/api/urls.py +1 -2
- nautobot/extras/api/views.py +0 -10
- nautobot/extras/apps.py +7 -0
- nautobot/extras/context_managers.py +15 -4
- nautobot/extras/filters/__init__.py +53 -2
- nautobot/extras/filters/customfields.py +14 -9
- nautobot/extras/filters/mixins.py +6 -1
- nautobot/extras/forms/contacts.py +7 -0
- nautobot/extras/health_checks.py +1 -0
- nautobot/extras/jobs.py +1 -0
- nautobot/extras/managers.py +15 -2
- nautobot/extras/models/contacts.py +1 -0
- nautobot/extras/models/customfields.py +25 -2
- nautobot/extras/models/datasources.py +1 -0
- nautobot/extras/models/mixins.py +1 -0
- nautobot/extras/navigation.py +71 -65
- nautobot/extras/plugins/__init__.py +2 -1
- nautobot/extras/plugins/views.py +7 -11
- nautobot/extras/querysets.py +1 -2
- nautobot/extras/secrets/providers.py +1 -0
- nautobot/extras/signals.py +15 -5
- nautobot/extras/tasks.py +70 -17
- nautobot/extras/tests/test_api.py +2 -4
- nautobot/extras/tests/test_customfields.py +72 -9
- nautobot/extras/tests/test_dynamicgroups.py +2 -0
- nautobot/extras/tests/test_filters.py +89 -4
- nautobot/extras/tests/test_models.py +9 -0
- nautobot/extras/tests/test_relationships.py +10 -1
- nautobot/extras/tests/test_views.py +112 -1
- nautobot/extras/views.py +18 -17
- nautobot/ipam/api/serializers.py +10 -0
- nautobot/ipam/api/urls.py +1 -2
- nautobot/ipam/api/views.py +0 -11
- nautobot/ipam/apps.py +3 -2
- nautobot/ipam/tables.py +2 -22
- nautobot/ipam/tests/test_graphql.py +2 -3
- nautobot/ipam/tests/test_tables.py +42 -0
- nautobot/ipam/tests/test_views.py +1 -0
- nautobot/ipam/views.py +9 -9
- nautobot/project-static/css/base.css +1 -0
- nautobot/project-static/docs/404.html +126 -73
- nautobot/project-static/docs/apps/index.html +127 -71
- nautobot/project-static/docs/apps/nautobot-apps.html +127 -71
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js → bundle.bd41221c.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js.map → bundle.bd41221c.min.js.map} +3 -3
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +167 -73
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +165 -72
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +128 -72
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +345 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +172 -73
- nautobot/project-static/docs/development/apps/api/configuration-view.html +127 -71
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/global-search.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/graphql.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +127 -71
- nautobot/project-static/docs/development/apps/api/prometheus.html +127 -71
- nautobot/project-static/docs/development/apps/api/setup.html +127 -71
- nautobot/project-static/docs/development/apps/api/testing.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/base-template.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +141 -80
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +144 -83
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/notes.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/urls.html +127 -71
- nautobot/project-static/docs/development/apps/index.html +127 -71
- nautobot/project-static/docs/development/apps/migration/code-updates.html +127 -71
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +127 -71
- nautobot/project-static/docs/development/apps/migration/from-v1.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +127 -71
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +127 -71
- nautobot/project-static/docs/development/core/application-registry.html +127 -71
- nautobot/project-static/docs/development/core/best-practices.html +145 -79
- nautobot/project-static/docs/development/core/bootstrap-ui.html +127 -71
- nautobot/project-static/docs/development/core/caching.html +127 -71
- nautobot/project-static/docs/development/core/controllers.html +141 -275
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +127 -71
- nautobot/project-static/docs/development/core/extending-models.html +13 -8166
- nautobot/project-static/docs/development/core/generic-views.html +142 -86
- nautobot/project-static/docs/development/core/getting-started.html +146 -81
- nautobot/project-static/docs/development/core/homepage.html +145 -89
- nautobot/project-static/docs/development/core/index.html +127 -71
- nautobot/project-static/docs/development/core/model-checklist.html +8354 -0
- nautobot/project-static/docs/development/core/model-features.html +130 -74
- nautobot/project-static/docs/development/core/natural-keys.html +127 -71
- nautobot/project-static/docs/development/core/navigation-menu.html +127 -71
- nautobot/project-static/docs/development/core/release-checklist.html +127 -71
- nautobot/project-static/docs/development/core/role-internals.html +127 -71
- nautobot/project-static/docs/development/core/settings.html +127 -71
- nautobot/project-static/docs/development/core/style-guide.html +127 -71
- nautobot/project-static/docs/development/core/templates.html +127 -71
- nautobot/project-static/docs/development/core/testing.html +127 -71
- nautobot/project-static/docs/development/core/user-preferences.html +127 -71
- nautobot/project-static/docs/development/extending-models.html +3 -3
- nautobot/project-static/docs/development/index.html +127 -71
- nautobot/project-static/docs/development/jobs/index.html +128 -72
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +127 -71
- nautobot/project-static/docs/index.html +126 -73
- nautobot/project-static/docs/models/dcim/{controllerdevicegroup.html → controllermanageddevicegroup.html} +3 -3
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.0.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.1.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.2.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.3.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.4.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.5.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.6.html +127 -71
- nautobot/project-static/docs/release-notes/version-2.0.html +127 -71
- nautobot/project-static/docs/release-notes/version-2.1.html +538 -254
- nautobot/project-static/docs/release-notes/version-2.2.html +520 -101
- nautobot/project-static/docs/requirements.txt +3 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +264 -259
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +192 -71
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +131 -71
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +130 -74
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +134 -74
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +8616 -0
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +130 -74
- nautobot/project-static/docs/user-guide/administration/installation/services.html +127 -71
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +127 -71
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +127 -71
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +127 -71
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +362 -79
- nautobot/project-static/docs/user-guide/core-data-model/dcim/{controllerdevicegroup.html → controllermanageddevicegroup.html} +210 -85
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +130 -74
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +138 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +138 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/{contact-and-team.html → contacts-and-teams.html} +128 -72
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +129 -73
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +129 -73
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +127 -71
- nautobot/project-static/docs/user-guide/index.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +127 -71
- nautobot/project-static/jquery/jquery-3.7.1.min.js +2 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_444444_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_555555_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777620_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777777_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_cc0000_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_ffffff_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.css +7 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.js +6 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.structure.min.css +5 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/jquery-ui.theme.min.css +1 -1
- nautobot/tenancy/api/urls.py +1 -2
- nautobot/tenancy/api/views.py +0 -12
- nautobot/tenancy/tables.py +1 -1
- nautobot/tenancy/tests/test_views.py +1 -0
- nautobot/users/api/urls.py +1 -2
- nautobot/users/api/views.py +2 -65
- nautobot/users/views.py +8 -8
- nautobot/virtualization/api/urls.py +1 -2
- nautobot/virtualization/api/views.py +0 -12
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/METADATA +24 -24
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/RECORD +418 -412
- nautobot/dcim/templates/dcim/controllerdevicegroup_create.html +0 -43
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css.map +0 -1
- nautobot/project-static/jquery/jquery-3.6.0.min.js +0 -2
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.css +0 -7
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.js +0 -6
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.structure.min.css +0 -5
- /nautobot/dcim/templates/dcim/{controllerdevicegroup_retrieve.html → controllermanageddevicegroup_retrieve.html} +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/NOTICE +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/WHEEL +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.1.dist-info}/entry_points.txt +0 -0
nautobot/core/settings.yaml
CHANGED
|
@@ -1171,6 +1171,19 @@ properties:
|
|
|
1171
1171
|
"Guide to Nautobot Prometheus metrics": "../guides/prometheus-metrics.md"
|
|
1172
1172
|
type: "boolean"
|
|
1173
1173
|
version_added: "2.1.5"
|
|
1174
|
+
METRICS_DISABLED_APPS:
|
|
1175
|
+
default: []
|
|
1176
|
+
description: >-
|
|
1177
|
+
A list of app names for which Prometheus metrics should be disabled.
|
|
1178
|
+
(If provided as an environment variable, it should be a comma-separated string, for example
|
|
1179
|
+
`NAUTOBOT_METRICS_DISABLED_APPS="nautobot_ssot, nautobot_device_lifecycle_mgmt"`.)
|
|
1180
|
+
environment_variable: "NAUTOBOT_METRICS_DISABLED_APPS"
|
|
1181
|
+
items:
|
|
1182
|
+
type: "string"
|
|
1183
|
+
see_also:
|
|
1184
|
+
"Guide to Nautobot Prometheus metrics": "../guides/prometheus-metrics.md"
|
|
1185
|
+
type: "array"
|
|
1186
|
+
version_added: "2.2.1"
|
|
1174
1187
|
METRICS_ENABLED:
|
|
1175
1188
|
default: false
|
|
1176
1189
|
description: "Toggle the availability of Prometheus-compatible metrics at `/metrics`."
|
|
@@ -1376,6 +1389,13 @@ properties:
|
|
|
1376
1389
|
environment_variable: "NAUTOBOT_RACK_ELEVATION_DEFAULT_UNIT_WIDTH"
|
|
1377
1390
|
is_constance_config: true
|
|
1378
1391
|
type: "integer"
|
|
1392
|
+
RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT:
|
|
1393
|
+
default: false
|
|
1394
|
+
description: "Enables two-digit format for the rack unit numbering in a rack elevation diagram."
|
|
1395
|
+
environment_variable: "NAUTOBOT_RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT"
|
|
1396
|
+
is_constance_config: true
|
|
1397
|
+
type: "boolean"
|
|
1398
|
+
version_added: "2.2.1"
|
|
1379
1399
|
REDIS_LOCK_TIMEOUT:
|
|
1380
1400
|
default: 600
|
|
1381
1401
|
description: >-
|
nautobot/core/signals.py
CHANGED
nautobot/core/tables.py
CHANGED
|
@@ -34,7 +34,7 @@ class BaseTable(django_tables2.Table):
|
|
|
34
34
|
"class": "table table-hover table-headings",
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
def __init__(self, *args, user=None, **kwargs):
|
|
37
|
+
def __init__(self, *args, user=None, hide_hierarchy_ui=False, **kwargs):
|
|
38
38
|
# Add custom field columns
|
|
39
39
|
model = self._meta.model
|
|
40
40
|
|
|
@@ -64,6 +64,7 @@ class BaseTable(django_tables2.Table):
|
|
|
64
64
|
|
|
65
65
|
# Init table
|
|
66
66
|
super().__init__(*args, **kwargs)
|
|
67
|
+
self.hide_hierarchy_ui = hide_hierarchy_ui
|
|
67
68
|
|
|
68
69
|
# Set default empty_text if none was provided
|
|
69
70
|
if self.empty_text is None:
|
|
@@ -8,55 +8,7 @@
|
|
|
8
8
|
<html lang="en"{% if request.COOKIES|get_item:"theme" == 'dark' %} data-theme="dark"{% endif %}>
|
|
9
9
|
<head>
|
|
10
10
|
<title>{% block title %}Admin Home{% endblock %} - Nautobot</title>
|
|
11
|
-
|
|
12
|
-
href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"
|
|
13
|
-
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/css/bootstrap.min.css'">
|
|
14
|
-
<link rel="stylesheet"
|
|
15
|
-
href="{% static 'materialdesignicons-6.5.95/css/materialdesignicons.min.css' %}"
|
|
16
|
-
onerror="window.location='{% url 'media_failure' %}?filename=materialdesignicons-6.5.95/css/materialdesignicons.min.css'">
|
|
17
|
-
<link rel="stylesheet"
|
|
18
|
-
href="{% static 'jquery-ui-1.13.1/jquery-ui.min.css' %}"
|
|
19
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.1/jquery-ui.min.css'">
|
|
20
|
-
<link rel="stylesheet"
|
|
21
|
-
href="{% static 'select2-4.0.13/select2.min.css' %}"
|
|
22
|
-
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.13/select2.min.css'">
|
|
23
|
-
<link rel="stylesheet"
|
|
24
|
-
href="{% static 'select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css' %}"
|
|
25
|
-
onerror="window.location='{% url 'media_failure' %}?filename=select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css'">
|
|
26
|
-
<link rel="stylesheet"
|
|
27
|
-
href="{% static 'flatpickr-4.6.9/themes/light.min.css' %}"
|
|
28
|
-
onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.9/themes/light.min.css'">
|
|
29
|
-
<link rel="stylesheet" id="dark-theme"
|
|
30
|
-
href="{% versioned_static 'css/dark.css' %}"
|
|
31
|
-
onerror="window.location='{% url 'media_failure' %}?filename=css/dark.css'"{% if request.COOKIES|get_item:"theme" != 'dark' %} disabled="disabled"{% endif %} />
|
|
32
|
-
<link rel="stylesheet" id="base-theme"
|
|
33
|
-
href="{% versioned_static 'css/base.css' %}"
|
|
34
|
-
onerror="window.location='{% url 'media_failure' %}?filename=css/base.css'">
|
|
35
|
-
<link rel="apple-touch-icon" sizes="180x180" href="{% custom_branding_or_static 'icon_180' 'img/nautobot_icon_180x180.png' %}">
|
|
36
|
-
<link rel="icon" type="image/png" sizes="32x32" href="{% custom_branding_or_static 'icon_32' 'img/nautobot_icon_32x32.png' %}">
|
|
37
|
-
<link rel="icon" type="image/png" sizes="16x16" href="{% custom_branding_or_static 'icon_16' 'img/nautobot_icon_16x16.png' %}">
|
|
38
|
-
<link rel="icon" type="image/png" href="{% custom_branding_or_static 'icon_192' 'img/nautobot_icon_192x192.png' %}" sizes="192x192">
|
|
39
|
-
<link rel="mask-icon" href="{% custom_branding_or_static 'icon_mask' 'img/nautobot_icon_monochrome.svg' %}" color="#0097ff">
|
|
40
|
-
<link rel="shortcut icon" href="{% custom_branding_or_static 'favicon' 'img/favicon.ico' %}">
|
|
41
|
-
|
|
42
|
-
<script src="{% static 'jquery/jquery-3.6.0.min.js' %}"
|
|
43
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery/jquery-3.6.0.min.js'"></script>
|
|
44
|
-
<script src="{% static 'jquery-ui-1.13.1/jquery-ui.min.js' %}"
|
|
45
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.1/jquery-ui.min.js'"></script>
|
|
46
|
-
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"
|
|
47
|
-
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/js/bootstrap.min.js'"></script>
|
|
48
|
-
<script src="{% static 'select2-4.0.13/select2.min.js' %}"
|
|
49
|
-
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.13/select2.min.js'"></script>
|
|
50
|
-
<script src="{% static 'flatpickr-4.6.9/flatpickr.min.js' %}"
|
|
51
|
-
onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.9/flatpickr.min.js'"></script>
|
|
52
|
-
<script src="{% static 'js/forms.js' %}"
|
|
53
|
-
onerror="window.location='{% url 'media_failure' %}?filename=js/forms.js'"></script>
|
|
54
|
-
|
|
55
|
-
<meta name="msapplication-TileColor" content="#2d89ef">
|
|
56
|
-
<meta name="theme-color" content="#ffffff">
|
|
57
|
-
<meta charset="UTF-8">
|
|
58
|
-
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
|
59
|
-
|
|
11
|
+
{% include 'inc/media.html' %}
|
|
60
12
|
{% block extrahead %}{% endblock %}
|
|
61
13
|
{% block extrastyle %}{% endblock %}
|
|
62
14
|
|
|
@@ -94,23 +46,27 @@
|
|
|
94
46
|
}
|
|
95
47
|
</style>
|
|
96
48
|
</head>
|
|
97
|
-
<body {% if is_popup %}style="padding-
|
|
49
|
+
<body {% if is_popup %}style="padding-left: 0px;"{% endif %}>
|
|
50
|
+
|
|
98
51
|
{% if not is_popup %}
|
|
99
52
|
{% include 'inc/nav_menu.html' %}
|
|
100
53
|
{% endif %}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<
|
|
111
|
-
|
|
54
|
+
|
|
55
|
+
<div class="container-fluid wrapper" id="main-content" {% if is_popup %}style="padding-bottom: 0px;"{% endif %}>
|
|
56
|
+
{% if not is_popup %}
|
|
57
|
+
{% if "BANNER_TOP"|settings_or_config %}
|
|
58
|
+
<div class="alert alert-info text-center" role="alert">
|
|
59
|
+
{{ "BANNER_TOP"|settings_or_config|safe }}
|
|
60
|
+
</div>
|
|
61
|
+
{% endif %}
|
|
62
|
+
{% if settings.MAINTENANCE_MODE %}
|
|
63
|
+
<div class="alert alert-warning text-center" role="alert">
|
|
64
|
+
<h4><i class="mdi mdi-alert"></i> Maintenance Mode</h4>
|
|
65
|
+
<p>Nautobot is currently in maintenance mode. Functionality may be limited.</p>
|
|
66
|
+
</div>
|
|
67
|
+
{% endif %}
|
|
68
|
+
{% plugin_banners %}
|
|
112
69
|
{% endif %}
|
|
113
|
-
{% plugin_banners %}
|
|
114
70
|
{% for message in messages %}
|
|
115
71
|
<div class="alert alert-{{ message.tags }} alert-dismissable" role="alert">
|
|
116
72
|
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
@@ -148,8 +104,6 @@
|
|
|
148
104
|
{% block content %}{{ content }}{% endblock %}
|
|
149
105
|
</div>
|
|
150
106
|
</div>
|
|
151
|
-
|
|
152
|
-
{% block footer %}<footer id="footer"></footer>{% endblock %}
|
|
153
107
|
<div class="push"></div>
|
|
154
108
|
{% if "BANNER_BOTTOM"|settings_or_config %}
|
|
155
109
|
<div class="alert alert-info text-center banner-bottom" role="alert">
|
|
@@ -158,37 +112,12 @@
|
|
|
158
112
|
{% endif %}
|
|
159
113
|
</div>
|
|
160
114
|
{% if not is_popup %}
|
|
161
|
-
|
|
162
|
-
<div class="container-fluid">
|
|
163
|
-
<div class="row">
|
|
164
|
-
<div class="col-xs-4">
|
|
165
|
-
<p class="text-muted">{{ settings.HOSTNAME }} (v{{ settings.VERSION }})</p>
|
|
166
|
-
</div>
|
|
167
|
-
<div class="col-xs-4 text-center">
|
|
168
|
-
<p class="text-muted">{% now 'Y-m-d H:i:s T' %}</p>
|
|
169
|
-
</div>
|
|
170
|
-
<div class="col-xs-4 text-right noprint">
|
|
171
|
-
<p class="text-muted">
|
|
172
|
-
<a href="#theme_modal" data-toggle="modal" data-target="#theme_modal" id="btn-theme-modal"><i class="mdi mdi-theme-light-dark text-primary"></i>Theme</a> ·
|
|
173
|
-
<i class="mdi mdi-book-open-page-variant text-primary"></i>
|
|
174
|
-
{% if settings.BRANDING_URLS.docs %}
|
|
175
|
-
<a href="{{ settings.BRANDING_URLS.docs }}">Docs</a>
|
|
176
|
-
{% else %}
|
|
177
|
-
<a href="{% static 'docs/index.html' %}">Docs</a>
|
|
178
|
-
{% endif %}
|
|
179
|
-
·
|
|
180
|
-
<i class="mdi mdi-cloud-braces text-primary"></i> <a href="{% url 'api_docs' %}">API</a> ·
|
|
181
|
-
<i class="mdi mdi-graphql text-primary"></i> <a href="{% url 'graphql' %}">GraphQL</a> ·
|
|
182
|
-
<i class="mdi mdi-xml text-primary"></i> <a href="{{ settings.BRANDING_URLS.code }}">Code</a> ·
|
|
183
|
-
<i class="mdi mdi-lifebuoy text-primary"></i> <a href="{{ settings.BRANDING_URLS.help }}">Help</a>
|
|
184
|
-
</p>
|
|
185
|
-
</div>
|
|
186
|
-
</div>
|
|
187
|
-
</div>
|
|
188
|
-
</footer>
|
|
115
|
+
{% include 'inc/footer.html' %}
|
|
189
116
|
{% endif %}
|
|
190
117
|
{% include 'modals/modal_theme.html' with name='theme'%}
|
|
191
|
-
|
|
192
|
-
{% block javascript %}
|
|
118
|
+
|
|
119
|
+
{% block javascript %}
|
|
120
|
+
{% include 'inc/javascript.html' %}
|
|
121
|
+
{% endblock %}
|
|
193
122
|
</body>
|
|
194
123
|
</html>
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
Advanced
|
|
88
88
|
</a>
|
|
89
89
|
</li>
|
|
90
|
-
{% if
|
|
90
|
+
{% if object.is_contact_associable_model %}
|
|
91
91
|
<li role="presentation"{% if request.GET.tab == 'contacts' %} class="active"{% endif %}>
|
|
92
92
|
<a href="{{ object.get_absolute_url }}#contacts" onclick="switch_tab(this.href)" aria-controls="contacts" role="tab" data-toggle="tab">
|
|
93
93
|
Contacts
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
</div>
|
|
160
160
|
</div>
|
|
161
161
|
</div>
|
|
162
|
-
{% if
|
|
162
|
+
{% if object.is_contact_associable_model %}
|
|
163
163
|
<div id="contacts" role="tabpanel" class="tab-pane {% if request.GET.tab == 'contacts' %}active{% else %}fade{% endif %}">
|
|
164
164
|
<div class="row">
|
|
165
165
|
<div class="col-md-12">
|
|
@@ -10,53 +10,31 @@ add "&raw" to the end of the URL within a browser.
|
|
|
10
10
|
<!DOCTYPE html>
|
|
11
11
|
<html>
|
|
12
12
|
<head>
|
|
13
|
+
{% include 'inc/media.html' %}
|
|
14
|
+
{% block extra_styles %}{% endblock %}
|
|
13
15
|
<!-- Nautobot template requirements -->
|
|
14
16
|
<title>{% block title %}GraphiQL{% endblock %} - {{ settings.BRANDING_TITLE }}</title>
|
|
15
|
-
|
|
16
|
-
href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}"
|
|
17
|
-
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/css/bootstrap.min.css'">
|
|
18
|
-
<link rel="stylesheet"
|
|
19
|
-
href="{% static 'materialdesignicons-6.5.95/css/materialdesignicons.min.css' %}"
|
|
20
|
-
onerror="window.location='{% url 'media_failure' %}?filename=materialdesignicons-6.5.95/css/materialdesignicons.min.css'">
|
|
21
|
-
<link rel="stylesheet"
|
|
22
|
-
href="{% static 'jquery-ui-1.13.1/jquery-ui.min.css' %}"
|
|
23
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.1/jquery-ui.min.css'">
|
|
24
|
-
<link rel="stylesheet"
|
|
25
|
-
href="{% static 'select2-4.0.13/select2.min.css' %}"
|
|
26
|
-
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.13/select2.min.css'">
|
|
27
|
-
<link rel="stylesheet"
|
|
28
|
-
href="{% static 'select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css' %}"
|
|
29
|
-
onerror="window.location='{% url 'media_failure' %}?filename=select2-bootstrap-0.1.0-beta.10/select2-bootstrap.min.css'">
|
|
30
|
-
<link rel="stylesheet"
|
|
31
|
-
href="{% static 'flatpickr-4.6.9/themes/light.min.css' %}"
|
|
32
|
-
onerror="window.location='{% url 'media_failure' %}?filename=flatpickr-4.6.9/themes/light.min.css'">
|
|
33
|
-
<link rel="stylesheet" id="dark-theme"
|
|
34
|
-
href="{% versioned_static 'css/dark.css' %}"
|
|
35
|
-
onerror="window.location='{% url 'media_failure' %}?filename=css/dark.css'" disabled="disabled" />
|
|
36
|
-
<link rel="stylesheet"
|
|
37
|
-
href="{% versioned_static 'css/base.css' %}"
|
|
38
|
-
onerror="window.location='{% url 'media_failure' %}?filename=css/base.css'">
|
|
39
|
-
<link rel="apple-touch-icon" sizes="180x180" href="{% custom_branding_or_static 'icon_180' 'img/nautobot_icon_180x180.png' %}">
|
|
40
|
-
<link rel="icon" type="image/png" sizes="32x32" href="{% custom_branding_or_static 'icon_32' 'img/nautobot_icon_32x32.png' %}">
|
|
41
|
-
<link rel="icon" type="image/png" sizes="16x16" href="{% custom_branding_or_static 'icon_16' 'img/nautobot_icon_16x16.png' %}">
|
|
42
|
-
<link rel="icon" type="image/png" sizes="192x192" href="{% custom_branding_or_static 'icon_192' 'img/nautobot_icon_192x192.png' %}">
|
|
43
|
-
<link rel="mask-icon" type="image/png" color="#0097ff" href="{% custom_branding_or_static 'icon_mask' 'img/nautobot_icon_monochrome.png' %}">
|
|
44
|
-
<link rel="shortcut icon" href="{% custom_branding_or_static 'favicon' 'img/favicon.ico' %}">
|
|
45
|
-
<meta name="msapplication-TileColor" content="#2d89ef">
|
|
46
|
-
<meta name="theme-color" content="#ffffff">
|
|
47
|
-
<meta charset="UTF-8">
|
|
48
|
-
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
|
|
17
|
+
|
|
49
18
|
<!-- GraphiQL template requirements -->
|
|
50
19
|
<style>
|
|
51
|
-
|
|
52
|
-
height: 100%;
|
|
20
|
+
#editor {
|
|
53
21
|
margin: 0;
|
|
54
22
|
width: 100%;
|
|
23
|
+
height: calc(100vh - 56px - 3rem);
|
|
55
24
|
}
|
|
56
25
|
.toolbar .dropdown-menu > li > a {
|
|
57
26
|
clear: left;
|
|
58
27
|
margin-right: 120px; /* leave room for the "Save Changes" button if present */
|
|
59
28
|
}
|
|
29
|
+
.graphiql-container .doc-explorer-title-bar {
|
|
30
|
+
box-sizing: content-box;
|
|
31
|
+
}
|
|
32
|
+
.graphiql-container .history-title-bar {
|
|
33
|
+
box-sizing: content-box;
|
|
34
|
+
}
|
|
35
|
+
.graphiql-container .docExplorerShow {
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
}
|
|
60
38
|
</style>
|
|
61
39
|
<!-- As Nautobot may be run without internet access, we source these files locally rather than from an online CDN -->
|
|
62
40
|
<link rel="stylesheet"
|
|
@@ -72,23 +50,16 @@ add "&raw" to the end of the URL within a browser.
|
|
|
72
50
|
onerror="window.location='{% url 'media_failure' %}?filename=graphiql-1.5.16/graphiql.min.js'"></script>
|
|
73
51
|
<script src="{% static 'subscriptions-transport-ws-0.9.18/client.min.js' %}"
|
|
74
52
|
onerror="window.location='{% url 'media_failure' %}?filename=subscriptions-transport-ws-0.9.18/client.min.js'"></script>
|
|
75
|
-
<!-- Custom CSS to address some conflicts between the two -->
|
|
76
|
-
<style>
|
|
77
|
-
body {
|
|
78
|
-
padding-top: 54px;
|
|
79
|
-
}
|
|
80
|
-
.graphiql-container .doc-explorer-title-bar {
|
|
81
|
-
box-sizing: content-box;
|
|
82
|
-
}
|
|
83
|
-
</style>
|
|
84
53
|
</head>
|
|
85
54
|
<body>
|
|
86
55
|
<!-- Nautobot page contents -->
|
|
87
56
|
{% include 'inc/nav_menu.html' %}
|
|
88
57
|
{% include 'modals/modal_theme.html' with name='theme'%}
|
|
89
58
|
{% include 'inc/javascript.html' %}
|
|
90
|
-
|
|
91
|
-
|
|
59
|
+
<div class="container-fluid wrapper" id="main-content">
|
|
60
|
+
<!-- GraphiQL page contents -->
|
|
61
|
+
<div id="editor"></div>
|
|
62
|
+
</div>
|
|
92
63
|
{% include 'inc/footer.html' %}
|
|
93
64
|
{% csrf_token %}
|
|
94
65
|
<script type="application/javascript">
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{% load plugins %}
|
|
4
4
|
|
|
5
5
|
<style>
|
|
6
|
-
/* Styles for viewports narrower than
|
|
7
|
-
@media (max-width:
|
|
6
|
+
/* Styles for viewports narrower than 1232px, i.e. bootstrap 'xs' and 'sm' layouts */
|
|
7
|
+
@media (max-width: 1232px) {
|
|
8
8
|
.footer-col-1, .footer-col-2, .footer-col-3 {
|
|
9
9
|
text-align: center !important;
|
|
10
10
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<footer class="footer" id="footer">
|
|
20
20
|
<div class="container-fluid">
|
|
21
21
|
<div class="row">
|
|
22
|
-
<div class="col-xl-4 col-lg-4 col-md-
|
|
22
|
+
<div class="col-xl-4 col-lg-4 col-md-3 col-sm-12 col-xs-12 text-left footer-col-1 no-wrap">
|
|
23
23
|
{% if request.user.is_authenticated %}
|
|
24
24
|
<p class="text-muted">
|
|
25
25
|
{% if settings.BRANDING_FILEPATHS.logo and settings.BRANDING_POWERED_BY_URL %}<a href="{{ settings.BRANDING_POWERED_BY_URL }}"><img src="{% static 'img/nautobot_logo.svg' %}" height="20" /> Powered</a> ·{% endif %}
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
</p>
|
|
28
28
|
{% endif %}
|
|
29
29
|
</div>
|
|
30
|
-
<div class="col-xl-4 col-lg-
|
|
30
|
+
<div class="col-xl-4 col-lg-3 col-md-3 col-sm-12 col-xs-12 text-center footer-col-2">
|
|
31
31
|
<p class="text-muted">{% now 'Y-m-d H:i:s T' %}</p>
|
|
32
32
|
</div>
|
|
33
|
-
<div class="col-xl-4 col-lg-
|
|
33
|
+
<div class="col-xl-4 col-lg-5 col-md-6 col-sm-12 col-xs-12 text-right footer-col-3 noprint">
|
|
34
34
|
{% if request.user.is_authenticated %}
|
|
35
35
|
<p class="text-muted footer-links">
|
|
36
36
|
<a href="#theme_modal" data-toggle="modal" data-target="#theme_modal" id="btn-theme-modal"><i class="mdi mdi-theme-light-dark text-primary"></i>Theme</a> ·
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
{% load plugins %}
|
|
3
3
|
{% load static %}
|
|
4
4
|
|
|
5
|
-
<script src="{% static 'jquery/jquery-3.
|
|
6
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery/jquery-3.
|
|
7
|
-
<script src="{% static 'jquery-ui-1.13.
|
|
8
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.
|
|
5
|
+
<script src="{% static 'jquery/jquery-3.7.1.min.js' %}"
|
|
6
|
+
onerror="window.location='{% url 'media_failure' %}?filename=jquery/jquery-3.7.1.min.js'"></script>
|
|
7
|
+
<script src="{% static 'jquery-ui-1.13.2/jquery-ui.min.js' %}"
|
|
8
|
+
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.2/jquery-ui.min.js'"></script>
|
|
9
9
|
<script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"
|
|
10
10
|
onerror="window.location='{% url 'media_failure' %}?filename=bootstrap-3.4.1-dist/js/bootstrap.min.js'"></script>
|
|
11
11
|
<script src="{% static 'select2-4.0.13/select2.min.js' %}"
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
href="{% static 'materialdesignicons-6.5.95/css/materialdesignicons.min.css' %}"
|
|
12
12
|
onerror="window.location='{% url 'media_failure' %}?filename=materialdesignicons-6.5.95/css/materialdesignicons.min.css'">
|
|
13
13
|
<link rel="stylesheet"
|
|
14
|
-
href="{% static 'jquery-ui-1.13.
|
|
15
|
-
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.
|
|
14
|
+
href="{% static 'jquery-ui-1.13.2/jquery-ui.min.css' %}"
|
|
15
|
+
onerror="window.location='{% url 'media_failure' %}?filename=jquery-ui-1.13.2/jquery-ui.min.css'">
|
|
16
16
|
<link rel="stylesheet"
|
|
17
17
|
href="{% static 'select2-4.0.13/select2.min.css' %}"
|
|
18
18
|
onerror="window.location='{% url 'media_failure' %}?filename=select2-4.0.13/select2.min.css'">
|
|
@@ -121,9 +121,6 @@
|
|
|
121
121
|
document.addEventListener('DOMContentLoaded', function() {
|
|
122
122
|
const navbar = document.querySelector('.navbar-fixed-left');
|
|
123
123
|
const navbarHeader = document.querySelector('.navbar-header');
|
|
124
|
-
const breadcrumb = document.querySelector('.breadcrumb');
|
|
125
|
-
const bannerAlertArea = document.querySelector('.banner-alert-area');
|
|
126
|
-
const bannerAlert = document.querySelector('.plugin-banner') !== null;
|
|
127
124
|
const mainContent = document.querySelector('#main-content');
|
|
128
125
|
const footer = document.querySelector('#footer');
|
|
129
126
|
const dropdownToggles = document.querySelectorAll('.navbar-fixed-left .navbar-nav > .dropdown > a[data-toggle="collapse"]');
|
|
@@ -180,10 +177,6 @@
|
|
|
180
177
|
function adjustElementsForNavbarState(isCollapsed) {
|
|
181
178
|
const marginLeftValue = isCollapsed ? '-240px' : '0px';
|
|
182
179
|
mainContent.style.marginLeft = marginLeftValue;
|
|
183
|
-
bannerAlertArea.classList.toggle('collapsed', isCollapsed);
|
|
184
|
-
if(!bannerAlert && breadcrumb) {
|
|
185
|
-
breadcrumb.classList.toggle('collapsed', isCollapsed);
|
|
186
|
-
};
|
|
187
180
|
if(footer) footer.style.marginLeft = marginLeftValue;
|
|
188
181
|
toggler.style.left = isCollapsed ? '-5px' : '225px';
|
|
189
182
|
}
|
|
@@ -415,6 +415,11 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
|
|
|
415
415
|
#
|
|
416
416
|
# METRICS_AUTHENTICATED = is_truthy(os.getenv("NAUTOBOT_METRICS_AUTHENTICATED", "False"))
|
|
417
417
|
|
|
418
|
+
# Disable app metrics for specific apps
|
|
419
|
+
#
|
|
420
|
+
# if "NAUTOBOT_METRICS_DISABLED_APPS" in os.environ and os.environ["NAUTOBOT_METRICS_DISABLED_APPS"] != "":
|
|
421
|
+
# METRICS_DISABLED_APPS = os.getenv("NAUTOBOT_METRICS_DISABLED_APPS", "").split(",")
|
|
422
|
+
|
|
418
423
|
# Credentials that Nautobot will uses to authenticate to devices when connecting via NAPALM.
|
|
419
424
|
#
|
|
420
425
|
# NAPALM_USERNAME = os.getenv("NAUTOBOT_NAPALM_USERNAME", "")
|
|
@@ -472,6 +477,14 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
|
|
|
472
477
|
# ):
|
|
473
478
|
# RACK_ELEVATION_DEFAULT_UNIT_WIDTH = int(os.environ["NAUTOBOT_RACK_ELEVATION_DEFAULT_UNIT_WIDTH"])
|
|
474
479
|
|
|
480
|
+
# Enable two-digit format for the rack unit numbering in rack elevations.
|
|
481
|
+
#
|
|
482
|
+
# if (
|
|
483
|
+
# "NAUTOBOT_RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT" in os.environ
|
|
484
|
+
# and os.environ["NAUTOBOT_RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT"] != ""
|
|
485
|
+
# ):
|
|
486
|
+
# RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT = is_truthy(os.environ["NAUTOBOT_RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT"])
|
|
487
|
+
|
|
475
488
|
# Sets an age out timer of redis lock. This is NOT implicitly applied to locks, must be added
|
|
476
489
|
# to a lock creation as `timeout=settings.REDIS_LOCK_TIMEOUT`
|
|
477
490
|
#
|
|
@@ -509,7 +522,7 @@ INSTALLATION_METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_INSTALLATION_METRIC
|
|
|
509
522
|
# class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG.
|
|
510
523
|
# These default to None and {} respectively.
|
|
511
524
|
#
|
|
512
|
-
# STORAGE_BACKEND = 'storages.backends.
|
|
525
|
+
# STORAGE_BACKEND = 'storages.backends.s3.S3Storage'
|
|
513
526
|
# STORAGE_CONFIG = {
|
|
514
527
|
# 'AWS_ACCESS_KEY_ID': 'Key ID',
|
|
515
528
|
# 'AWS_SECRET_ACCESS_KEY': 'Secret',
|
|
@@ -7,13 +7,20 @@
|
|
|
7
7
|
{% include 'inc/media.html' %}
|
|
8
8
|
{% endblock bootstrap_theme %}
|
|
9
9
|
|
|
10
|
-
{% block navbar %}
|
|
11
|
-
{% include 'inc/nav_menu.html' %}
|
|
12
|
-
{% endblock navbar %}
|
|
13
|
-
|
|
14
10
|
{% block body %}
|
|
15
|
-
{
|
|
11
|
+
{% include 'inc/nav_menu.html' %}
|
|
12
|
+
<div class="container-fluid" id="main-content">
|
|
13
|
+
{{ block.super }}
|
|
14
|
+
</div>
|
|
16
15
|
{% include 'inc/footer.html' %}
|
|
16
|
+
<style>
|
|
17
|
+
.navbar-static-top {
|
|
18
|
+
display: none;
|
|
19
|
+
}
|
|
20
|
+
#main-content {
|
|
21
|
+
min-height: calc(100vh - 70px);
|
|
22
|
+
}
|
|
23
|
+
</style>
|
|
17
24
|
{% endblock body %}
|
|
18
25
|
|
|
19
26
|
{% block script %}
|
|
@@ -85,7 +85,7 @@ def hyperlinked_object(value, field="display"):
|
|
|
85
85
|
@register.filter()
|
|
86
86
|
def hyperlinked_email(value):
|
|
87
87
|
"""Render an email address as a `mailto:` hyperlink."""
|
|
88
|
-
if value
|
|
88
|
+
if not value:
|
|
89
89
|
return placeholder(value)
|
|
90
90
|
return format_html('<a href="mailto:{}">{}</a>', value, value)
|
|
91
91
|
|
|
@@ -94,7 +94,7 @@ def hyperlinked_email(value):
|
|
|
94
94
|
@register.filter()
|
|
95
95
|
def hyperlinked_phone_number(value):
|
|
96
96
|
"""Render a phone number as a `tel:` hyperlink."""
|
|
97
|
-
if value
|
|
97
|
+
if not value:
|
|
98
98
|
return placeholder(value)
|
|
99
99
|
return format_html('<a href="tel:{}">{}</a>', value, value)
|
|
100
100
|
|
|
@@ -109,7 +109,7 @@ def get_job_class_and_model(module, name, source="local"):
|
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
@tag("unit")
|
|
112
|
-
class TransactionTestCase(
|
|
112
|
+
class TransactionTestCase(NautobotTestCaseMixin, _TransactionTestCase):
|
|
113
113
|
"""
|
|
114
114
|
Base test case class using the TransactionTestCase for unit testing
|
|
115
115
|
"""
|
nautobot/core/testing/filters.py
CHANGED
|
@@ -44,7 +44,7 @@ class FilterTestCases:
|
|
|
44
44
|
# randomly break out of loop after 2 values have been selected
|
|
45
45
|
if len(test_values) > 1 and random.choice([True, False]): # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
46
46
|
break
|
|
47
|
-
if value[field_name] and value["count"]
|
|
47
|
+
if value[field_name] and value["count"] < qs_count:
|
|
48
48
|
qs_count -= value["count"]
|
|
49
49
|
test_values.append(str(value[field_name]))
|
|
50
50
|
|
nautobot/core/testing/views.py
CHANGED
|
@@ -17,6 +17,7 @@ from tree_queries.models import TreeNode
|
|
|
17
17
|
|
|
18
18
|
from nautobot.core import testing
|
|
19
19
|
from nautobot.core.models.generics import PrimaryModel
|
|
20
|
+
from nautobot.core.models.tree_queries import TreeModel
|
|
20
21
|
from nautobot.core.templatetags import helpers
|
|
21
22
|
from nautobot.core.testing import mixins
|
|
22
23
|
from nautobot.core.utils import lookup
|
|
@@ -24,6 +25,7 @@ from nautobot.extras import choices as extras_choices, models as extras_models,
|
|
|
24
25
|
from nautobot.extras.forms import CustomFieldModelFormMixin, RelationshipModelFormMixin
|
|
25
26
|
from nautobot.extras.models import CustomFieldModel, RelationshipModel
|
|
26
27
|
from nautobot.extras.models.mixins import NotesMixin
|
|
28
|
+
from nautobot.ipam.models import Prefix
|
|
27
29
|
from nautobot.users import models as users_models
|
|
28
30
|
|
|
29
31
|
__all__ = (
|
|
@@ -722,6 +724,8 @@ class ViewTestCases:
|
|
|
722
724
|
"""
|
|
723
725
|
|
|
724
726
|
filterset = None
|
|
727
|
+
filter_on_field = "name"
|
|
728
|
+
sort_on_field = "tags"
|
|
725
729
|
|
|
726
730
|
def get_filterset(self):
|
|
727
731
|
return self.filterset or lookup.get_filterset_for_model(self.model)
|
|
@@ -737,6 +741,32 @@ class ViewTestCases:
|
|
|
737
741
|
def get_list_view(self):
|
|
738
742
|
return lookup.get_view_for_model(self.model, view_type="List")
|
|
739
743
|
|
|
744
|
+
def test_table_with_indentation_is_removed_on_filter_or_sort(self):
|
|
745
|
+
self.user.is_superuser = True
|
|
746
|
+
self.user.save()
|
|
747
|
+
|
|
748
|
+
if not issubclass(self.model, (TreeModel)) and self.model is not Prefix:
|
|
749
|
+
self.skipTest("Skipping Non TreeModels")
|
|
750
|
+
|
|
751
|
+
with self.subTest("Assert indentation is present"):
|
|
752
|
+
response = self.client.get(f"{self._get_url('list')}")
|
|
753
|
+
response_body = response.content.decode(response.charset)
|
|
754
|
+
self.assertInHTML('<i class="mdi mdi-circle-small"></i>', response_body)
|
|
755
|
+
|
|
756
|
+
with self.subTest("Assert indentation is removed on filter"):
|
|
757
|
+
queryset = (
|
|
758
|
+
self._get_queryset().filter(parent__isnull=False).values_list(self.filter_on_field, flat=True)[:5]
|
|
759
|
+
)
|
|
760
|
+
filter_values = "&".join([f"{self.filter_on_field}={instance_value}" for instance_value in queryset])
|
|
761
|
+
response = self.client.get(f"{self._get_url('list')}?{filter_values}")
|
|
762
|
+
response_body = response.content.decode(response.charset)
|
|
763
|
+
self.assertNotIn('<i class="mdi mdi-circle-small"></i>', response_body)
|
|
764
|
+
|
|
765
|
+
with self.subTest("Assert indentation is removed on sort"):
|
|
766
|
+
response = self.client.get(f"{self._get_url('list')}?sort={self.sort_on_field}")
|
|
767
|
+
response_body = response.content.decode(response.charset)
|
|
768
|
+
self.assertNotIn('<i class="mdi mdi-circle-small"></i>', response_body)
|
|
769
|
+
|
|
740
770
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
741
771
|
def test_list_objects_anonymous(self):
|
|
742
772
|
# Make the request as an unauthenticated user
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from django.test import tag
|
|
2
|
+
|
|
3
|
+
from nautobot.core.testing import TestCase
|
|
4
|
+
from nautobot.core.utils.lookup import get_url_for_url_pattern, get_url_patterns
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@tag("integration")
|
|
8
|
+
class AuthenticationEnforcedTestCase(TestCase):
|
|
9
|
+
r"""
|
|
10
|
+
Test that all\* registered views require authentication to access.
|
|
11
|
+
|
|
12
|
+
\* with a very small number of known exceptions such as login and logout views.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def test_all_views_require_authentication(self):
|
|
16
|
+
self.client.logout()
|
|
17
|
+
url_patterns = get_url_patterns()
|
|
18
|
+
|
|
19
|
+
for url_pattern in url_patterns:
|
|
20
|
+
with self.subTest(url_pattern=url_pattern):
|
|
21
|
+
url = get_url_for_url_pattern(url_pattern)
|
|
22
|
+
response = self.client.get(url, follow=True)
|
|
23
|
+
|
|
24
|
+
if response.status_code == 405: # Method not allowed
|
|
25
|
+
response = self.client.post(url, follow=True)
|
|
26
|
+
|
|
27
|
+
# Is a view that *should* be open to unauthenticated users?
|
|
28
|
+
if url in [
|
|
29
|
+
"/admin/login/",
|
|
30
|
+
"/api/plugins/example-app/webhook/",
|
|
31
|
+
"/health/",
|
|
32
|
+
"/login/",
|
|
33
|
+
"/media-failure/",
|
|
34
|
+
"/template.css",
|
|
35
|
+
]:
|
|
36
|
+
self.assertHttpStatus(response, 200, msg=url)
|
|
37
|
+
elif response.status_code == 200:
|
|
38
|
+
# UI views generally should redirect unauthenticated users to the appropriate login page
|
|
39
|
+
if url.startswith("/admin"):
|
|
40
|
+
if "logout" in url:
|
|
41
|
+
# /admin/logout/ sets next=/admin/ because having login redirect to logout would be silly
|
|
42
|
+
redirect_url = "/admin/login/?next=/admin/"
|
|
43
|
+
else:
|
|
44
|
+
redirect_url = f"/admin/login/?next={url}"
|
|
45
|
+
else:
|
|
46
|
+
if "logout" in url:
|
|
47
|
+
# /logout/ sets next=/ because having login redirect back to logout would be silly
|
|
48
|
+
redirect_url = "/login/?next=/"
|
|
49
|
+
else:
|
|
50
|
+
redirect_url = f"/login/?next={url}"
|
|
51
|
+
self.assertRedirects(response, redirect_url)
|
|
52
|
+
elif response.status_code != 403:
|
|
53
|
+
if any(
|
|
54
|
+
url.startswith(path)
|
|
55
|
+
for path in [
|
|
56
|
+
"/complete/", # social auth
|
|
57
|
+
"/health/string/", # health-check
|
|
58
|
+
"/login/", # social auth
|
|
59
|
+
"/media/", # MEDIA_ROOT
|
|
60
|
+
"/plugins/example-app/docs/", # STATIC_ROOT
|
|
61
|
+
]
|
|
62
|
+
):
|
|
63
|
+
self.assertEqual(response.status_code, 404)
|
|
64
|
+
else:
|
|
65
|
+
self.fail(
|
|
66
|
+
f"Unexpected {response.status_code} response at {url}: "
|
|
67
|
+
+ response.content.decode(response.charset)
|
|
68
|
+
)
|