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.
- nautobot/circuits/navigation.py +0 -25
- nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -9
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
- nautobot/circuits/tests/test_api.py +79 -2
- nautobot/circuits/tests/test_filters.py +1 -0
- nautobot/core/api/serializers.py +15 -5
- nautobot/core/api/views.py +18 -19
- nautobot/core/choices.py +1 -1
- nautobot/core/filters.py +12 -4
- nautobot/core/jobs/__init__.py +125 -3
- nautobot/core/management/commands/generate_test_data.py +6 -1
- nautobot/core/middleware.py +12 -4
- nautobot/core/models/fields.py +12 -2
- nautobot/core/settings.py +9 -8
- nautobot/core/tables.py +26 -31
- nautobot/core/templates/base_django.html +2 -2
- nautobot/core/templates/buttons/export.html +57 -30
- nautobot/core/templates/generic/object_list.html +2 -2
- nautobot/core/templates/generic/object_retrieve.html +8 -1
- nautobot/core/templates/home.html +5 -5
- nautobot/core/templates/inc/created_updated.html +2 -2
- nautobot/core/templates/inc/footer.html +2 -2
- nautobot/core/templates/inc/javascript.html +0 -10
- nautobot/core/templates/inc/media.html +2 -0
- nautobot/core/templates/inc/nav_menu.html +66 -68
- nautobot/core/templates/inc/object_details_advanced_panel.html +19 -0
- nautobot/core/templates/nautobot_config.py.j2 +10 -4
- nautobot/core/templates/panel_table.html +1 -1
- nautobot/core/templates/template.css +89 -0
- nautobot/core/templates/utilities/templatetags/table_config_form.html +1 -0
- nautobot/core/templatetags/buttons.py +7 -2
- nautobot/core/templatetags/helpers.py +9 -9
- nautobot/core/testing/views.py +34 -4
- nautobot/core/tests/integration/test_home.py +1 -43
- nautobot/core/tests/integration/test_navbar.py +10 -64
- nautobot/core/tests/integration/test_plugin_home.py +4 -5
- nautobot/core/tests/integration/test_plugin_navbar.py +20 -16
- nautobot/core/tests/integration/test_theme.py +4 -0
- nautobot/core/tests/test_api.py +14 -66
- nautobot/core/tests/test_filters.py +127 -0
- nautobot/core/tests/test_forms.py +4 -4
- nautobot/core/tests/test_graphql.py +165 -2
- nautobot/core/tests/test_jobs.py +112 -0
- nautobot/core/tests/test_openapi.py +6 -0
- nautobot/core/tests/test_utils.py +23 -20
- nautobot/core/tests/test_views.py +11 -85
- nautobot/core/urls.py +6 -1
- nautobot/core/utils/data.py +5 -1
- nautobot/core/utils/filtering.py +6 -4
- nautobot/core/utils/lookup.py +28 -0
- nautobot/core/utils/requests.py +2 -3
- nautobot/core/views/__init__.py +3 -4
- nautobot/core/views/generic.py +15 -11
- nautobot/core/views/mixins.py +9 -8
- nautobot/core/views/renderers.py +5 -0
- nautobot/core/views/utils.py +23 -24
- nautobot/dcim/api/serializers.py +8 -4
- nautobot/dcim/models/device_components.py +1 -0
- nautobot/dcim/models/devices.py +7 -6
- nautobot/dcim/navigation.py +10 -165
- nautobot/dcim/templates/dcim/location.html +1 -1
- nautobot/dcim/tests/features/locations.feature +143 -0
- nautobot/dcim/tests/test_api.py +8 -1
- nautobot/dcim/tests/test_filters.py +11 -3
- nautobot/dcim/views.py +5 -6
- nautobot/extras/admin.py +1 -1
- nautobot/extras/api/serializers.py +33 -0
- nautobot/extras/api/urls.py +6 -0
- nautobot/extras/api/views.py +45 -6
- nautobot/extras/context_managers.py +34 -8
- nautobot/extras/factory.py +28 -2
- nautobot/extras/filters/__init__.py +52 -0
- nautobot/extras/filters/mixins.py +4 -29
- nautobot/extras/forms/forms.py +43 -0
- nautobot/extras/jobs.py +39 -17
- nautobot/extras/migrations/0100_fileproxy_job_result.py +32 -0
- nautobot/extras/migrations/0101_externalintegration.py +61 -0
- nautobot/extras/migrations/0102_set_null_objectchange_contenttype.py +32 -0
- nautobot/extras/models/__init__.py +2 -0
- nautobot/extras/models/change_logging.py +2 -2
- nautobot/extras/models/customfields.py +2 -2
- nautobot/extras/models/models.py +101 -18
- nautobot/extras/models/relationships.py +13 -8
- nautobot/extras/navigation.py +17 -29
- nautobot/extras/signals.py +80 -59
- nautobot/extras/tables.py +28 -2
- nautobot/extras/templates/extras/externalintegration_retrieve.html +37 -0
- nautobot/extras/templates/extras/inc/jobresult.html +24 -0
- nautobot/extras/templates/extras/jobresult.html +24 -0
- nautobot/extras/templatetags/computed_fields.py +6 -13
- nautobot/extras/templatetags/custom_links.py +19 -12
- nautobot/extras/templatetags/job_buttons.py +34 -19
- nautobot/extras/templatetags/plugins.py +1 -1
- nautobot/extras/test_jobs/file_output.py +16 -0
- nautobot/extras/tests/test_api.py +92 -0
- nautobot/extras/tests/test_context_managers.py +94 -4
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_filters.py +64 -2
- nautobot/extras/tests/test_jobs.py +75 -22
- nautobot/extras/tests/test_models.py +34 -0
- nautobot/extras/tests/test_relationships.py +2 -2
- nautobot/extras/tests/test_views.py +204 -4
- nautobot/extras/tests/test_webhooks.py +61 -25
- nautobot/extras/urls.py +1 -0
- nautobot/extras/views.py +27 -13
- nautobot/extras/webhooks.py +16 -25
- nautobot/ipam/fields.py +5 -0
- nautobot/ipam/forms.py +16 -0
- nautobot/ipam/models.py +13 -2
- nautobot/ipam/navigation.py +2 -59
- nautobot/ipam/tables.py +1 -1
- nautobot/ipam/templates/ipam/ipaddress.html +0 -9
- nautobot/ipam/templates/ipam/prefix.html +0 -9
- nautobot/ipam/tests/features/prefixes.feature +134 -0
- nautobot/ipam/tests/test_filters.py +5 -10
- nautobot/ipam/tests/test_models.py +7 -0
- nautobot/ipam/tests/test_views.py +8 -1
- nautobot/ipam/views.py +99 -58
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +191 -191
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +874 -881
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
- nautobot/project-static/css/base.css +138 -99
- nautobot/project-static/css/dark.css +65 -6
- nautobot/project-static/docs/404.html +45 -17
- nautobot/project-static/docs/apps/index.html +45 -17
- nautobot/project-static/docs/apps/nautobot-apps.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1598 -1458
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +229 -152
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +46 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +354 -433
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +67 -39
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2083 -2234
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1389 -1247
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +129 -111
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3601 -3457
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +45 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +320 -284
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3863 -3801
- nautobot/project-static/docs/development/apps/api/configuration-view.html +45 -17
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/global-search.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/graphql.html +45 -17
- nautobot/project-static/docs/development/apps/api/models/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +45 -17
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +45 -17
- nautobot/project-static/docs/development/apps/api/prometheus.html +45 -17
- nautobot/project-static/docs/development/apps/api/setup.html +45 -17
- nautobot/project-static/docs/development/apps/api/testing.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/base-template.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/index.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/notes.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/urls.html +45 -17
- nautobot/project-static/docs/development/apps/api/views/view-overrides.html +45 -17
- nautobot/project-static/docs/development/apps/index.html +45 -17
- nautobot/project-static/docs/development/apps/migration/code-updates.html +45 -17
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +45 -17
- nautobot/project-static/docs/development/apps/migration/from-v1.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +45 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +45 -17
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +45 -17
- nautobot/project-static/docs/development/core/application-registry.html +45 -17
- nautobot/project-static/docs/development/core/best-practices.html +45 -17
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +45 -17
- nautobot/project-static/docs/development/core/extending-models.html +45 -17
- nautobot/project-static/docs/development/core/generic-views.html +45 -17
- nautobot/project-static/docs/development/core/getting-started.html +45 -17
- nautobot/project-static/docs/development/core/homepage.html +45 -17
- nautobot/project-static/docs/development/core/index.html +45 -17
- nautobot/project-static/docs/development/core/model-features.html +45 -17
- nautobot/project-static/docs/development/core/natural-keys.html +45 -17
- nautobot/project-static/docs/development/core/navigation-menu.html +45 -22
- nautobot/project-static/docs/development/core/react-ui.html +45 -17
- nautobot/project-static/docs/development/core/release-checklist.html +46 -18
- nautobot/project-static/docs/development/core/role-internals.html +45 -17
- nautobot/project-static/docs/development/core/style-guide.html +45 -17
- nautobot/project-static/docs/development/core/templates.html +45 -17
- nautobot/project-static/docs/development/core/testing.html +45 -17
- nautobot/project-static/docs/development/core/user-preferences.html +45 -17
- nautobot/project-static/docs/development/index.html +45 -17
- nautobot/project-static/docs/development/jobs/index.html +281 -235
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +45 -17
- nautobot/project-static/docs/index.html +45 -17
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.png +0 -0
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.txt +1 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +48 -20
- nautobot/project-static/docs/release-notes/version-1.0.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.1.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.2.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.3.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.4.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.5.html +45 -17
- nautobot/project-static/docs/release-notes/version-1.6.html +46 -18
- nautobot/project-static/docs/release-notes/version-2.0.html +372 -199
- nautobot/project-static/docs/release-notes/version-2.1.html +5724 -0
- nautobot/project-static/docs/requirements.txt +1 -1
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +247 -237
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +45 -17
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +110 -44
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +48 -20
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +45 -17
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +49 -20
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +45 -17
- nautobot/project-static/docs/user-guide/administration/installation/services.html +45 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +45 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +45 -17
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +45 -17
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +45 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +45 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +45 -17
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +45 -17
- nautobot/project-static/docs/user-guide/index.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +111 -17
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +48 -20
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +5359 -0
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +48 -20
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +114 -45
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +45 -17
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +45 -17
- nautobot/project-static/fonts/UFL.txt +96 -0
- nautobot/project-static/fonts/Ubuntu-Bold.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-BoldItalic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Italic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Medium.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-MediumItalic.woff2 +0 -0
- nautobot/project-static/fonts/Ubuntu-Regular.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Bold.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-BoldItalic.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Italic.woff2 +0 -0
- nautobot/project-static/fonts/UbuntuMono-Regular.woff2 +0 -0
- nautobot/project-static/img/dark-theme.png +0 -0
- nautobot/project-static/img/light-theme.png +0 -0
- nautobot/project-static/img/nautobot_chevron.svg +5 -0
- nautobot/project-static/img/nautobot_chevron_header.svg +5 -0
- nautobot/project-static/img/system-theme.png +0 -0
- nautobot/tenancy/navigation.py +0 -13
- nautobot/ui/package-lock.json +2 -2
- nautobot/ui/package.json +1 -1
- nautobot/users/admin.py +44 -0
- nautobot/users/migrations/0007_alter_objectpermission_object_types.py +33 -0
- nautobot/users/models.py +3 -2
- nautobot/virtualization/navigation.py +1 -33
- nautobot/virtualization/tests/test_api.py +1 -1
- nautobot/virtualization/tests/test_filters.py +1 -1
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/METADATA +2 -2
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/RECORD +405 -786
- CHANGELOG.md +0 -3
- CONTRIBUTING.md +0 -3
- NOTICE +0 -8
- nautobot/docs/apps/index.md +0 -22
- nautobot/docs/apps/nautobot-apps.md +0 -10
- nautobot/docs/assets/app-icons/icon-ChatOps.png +0 -0
- nautobot/docs/assets/app-icons/icon-DataValidationEngine.png +0 -0
- nautobot/docs/assets/app-icons/icon-DeviceLifecycle.png +0 -0
- nautobot/docs/assets/app-icons/icon-DeviceOnboarding.png +0 -0
- nautobot/docs/assets/app-icons/icon-FirewallModels.png +0 -0
- nautobot/docs/assets/app-icons/icon-GoldenConfiguration.png +0 -0
- nautobot/docs/assets/app-icons/icon-NautobotPluginNornir.png +0 -0
- nautobot/docs/assets/app-icons/icon-SSoT.png +0 -0
- nautobot/docs/assets/extra.css +0 -139
- nautobot/docs/assets/favicon.ico +0 -0
- nautobot/docs/assets/nautobot_logo.png +0 -0
- nautobot/docs/assets/nautobot_logo.svg +0 -131
- nautobot/docs/assets/networktocode_bw.png +0 -0
- nautobot/docs/assets/overrides/partials/copyright.html +0 -20
- nautobot/docs/development/apps/api/configuration-view.md +0 -35
- nautobot/docs/development/apps/api/database-backend-config.md +0 -26
- nautobot/docs/development/apps/api/models/django-admin.md +0 -20
- nautobot/docs/development/apps/api/models/global-search.md +0 -11
- nautobot/docs/development/apps/api/models/graphql.md +0 -97
- nautobot/docs/development/apps/api/models/index.md +0 -81
- nautobot/docs/development/apps/api/nautobot-app-config.md +0 -84
- nautobot/docs/development/apps/api/platform-features/custom-validators.md +0 -30
- nautobot/docs/development/apps/api/platform-features/filter-extensions.md +0 -49
- nautobot/docs/development/apps/api/platform-features/git-repository-content.md +0 -62
- nautobot/docs/development/apps/api/platform-features/index.md +0 -1
- nautobot/docs/development/apps/api/platform-features/jinja2-filters.md +0 -28
- nautobot/docs/development/apps/api/platform-features/jobs.md +0 -29
- nautobot/docs/development/apps/api/platform-features/populating-extensibility-features.md +0 -58
- nautobot/docs/development/apps/api/platform-features/secrets-providers.md +0 -64
- nautobot/docs/development/apps/api/platform-features/uniquely-identify-objects.md +0 -63
- nautobot/docs/development/apps/api/prometheus.md +0 -25
- nautobot/docs/development/apps/api/setup.md +0 -132
- nautobot/docs/development/apps/api/testing.md +0 -55
- nautobot/docs/development/apps/api/ui-extensions/banners.md +0 -26
- nautobot/docs/development/apps/api/ui-extensions/home-page.md +0 -9
- nautobot/docs/development/apps/api/ui-extensions/index.md +0 -1
- nautobot/docs/development/apps/api/ui-extensions/navigation.md +0 -15
- nautobot/docs/development/apps/api/ui-extensions/object-detail-views.md +0 -74
- nautobot/docs/development/apps/api/ui-extensions/tabs.md +0 -52
- nautobot/docs/development/apps/api/views/base-template.md +0 -38
- nautobot/docs/development/apps/api/views/core-view-overrides.md +0 -26
- nautobot/docs/development/apps/api/views/django-generic-views.md +0 -23
- nautobot/docs/development/apps/api/views/help-documentation.md +0 -16
- nautobot/docs/development/apps/api/views/index.md +0 -3
- nautobot/docs/development/apps/api/views/nautobot-generic-views.md +0 -35
- nautobot/docs/development/apps/api/views/nautobotuiviewset.md +0 -147
- nautobot/docs/development/apps/api/views/nautobotuiviewsetrouter.md +0 -41
- nautobot/docs/development/apps/api/views/notes.md +0 -25
- nautobot/docs/development/apps/api/views/rest-api.md +0 -64
- nautobot/docs/development/apps/api/views/urls.md +0 -26
- nautobot/docs/development/apps/api/views/view-overrides.md +0 -50
- nautobot/docs/development/apps/index.md +0 -75
- nautobot/docs/development/apps/migration/code-updates.md +0 -160
- nautobot/docs/development/apps/migration/dependency-updates.md +0 -13
- nautobot/docs/development/apps/migration/from-v1.md +0 -56
- nautobot/docs/development/apps/migration/model-updates/dcim.md +0 -285
- nautobot/docs/development/apps/migration/model-updates/extras.md +0 -30
- nautobot/docs/development/apps/migration/model-updates/global.md +0 -5
- nautobot/docs/development/apps/migration/model-updates/ipam.md +0 -22
- nautobot/docs/development/apps/porting-from-netbox.md +0 -23
- nautobot/docs/development/core/application-registry.md +0 -216
- nautobot/docs/development/core/best-practices.md +0 -469
- nautobot/docs/development/core/docker-compose-advanced-use-cases.md +0 -228
- nautobot/docs/development/core/extending-models.md +0 -93
- nautobot/docs/development/core/generic-views.md +0 -65
- nautobot/docs/development/core/getting-started.md +0 -859
- nautobot/docs/development/core/homepage.md +0 -63
- nautobot/docs/development/core/index.md +0 -334
- nautobot/docs/development/core/model-features.md +0 -44
- nautobot/docs/development/core/natural-keys.md +0 -121
- nautobot/docs/development/core/navigation-menu.md +0 -142
- nautobot/docs/development/core/react-ui.md +0 -137
- nautobot/docs/development/core/release-checklist.md +0 -312
- nautobot/docs/development/core/role-internals.md +0 -28
- nautobot/docs/development/core/style-guide.md +0 -200
- nautobot/docs/development/core/templates.md +0 -101
- nautobot/docs/development/core/testing.md +0 -238
- nautobot/docs/development/core/user-preferences.md +0 -11
- nautobot/docs/development/index.md +0 -1
- nautobot/docs/development/jobs/index.md +0 -835
- nautobot/docs/development/jobs/migration/from-v1.md +0 -160
- nautobot/docs/generate_code_reference_pages.py +0 -20
- nautobot/docs/img/edge_dev_circuit_relationship.png +0 -0
- nautobot/docs/img/leaf_dev_no_circuit_relationship.png +0 -0
- nautobot/docs/img/relationship_w_json_filter.png +0 -0
- nautobot/docs/index.md +0 -105
- nautobot/docs/media/admin_ui_run_permission.png +0 -0
- nautobot/docs/media/development/homepage_changelog_panel.png +0 -0
- nautobot/docs/media/development/homepage_dcim_panel.png +0 -0
- nautobot/docs/media/development/index_bug_wf.jpg +0 -0
- nautobot/docs/media/development/index_feature_request_wf.jpg +0 -0
- nautobot/docs/media/development/index_release_cadence.drawio +0 -90
- nautobot/docs/media/development/index_release_cadence.jpg +0 -0
- nautobot/docs/media/installation/nautobot_ui_admin.png +0 -0
- nautobot/docs/media/installation/nautobot_ui_guest.png +0 -0
- nautobot/docs/media/models/dcim_cable_trace.png +0 -0
- nautobot/docs/media/models/dcim_cable_trace_circuit.png +0 -0
- nautobot/docs/media/models/dynamicgroup_filtering_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
- nautobot/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
- nautobot/docs/media/models/jobbutton_form.png +0 -0
- nautobot/docs/media/models/site_jobbuttons.png +0 -0
- nautobot/docs/media/nautobot_application_stack_high_level.drawio +0 -1
- nautobot/docs/media/nautobot_application_stack_high_level.png +0 -0
- nautobot/docs/media/nautobot_application_stack_low_level.drawio +0 -1
- nautobot/docs/media/nautobot_application_stack_low_level.png +0 -0
- nautobot/docs/media/nautobot_chatops.gif +0 -0
- nautobot/docs/media/nautobot_config_context.gif +0 -0
- nautobot/docs/media/nautobot_golden_config.gif +0 -0
- nautobot/docs/media/nautobot_graphql.gif +0 -0
- nautobot/docs/media/nautobot_mainpage.gif +0 -0
- nautobot/docs/media/nautobot_prefix_hierarchy.gif +0 -0
- nautobot/docs/media/plugins/plugin_admin_config.png +0 -0
- nautobot/docs/media/plugins/plugin_admin_ui.png +0 -0
- nautobot/docs/media/plugins/plugin_rest_api_endpoint.png +0 -0
- nautobot/docs/media/power_distribution.png +0 -0
- nautobot/docs/media/ss_config_contexts.png +0 -0
- nautobot/docs/media/ss_graphiql.png +0 -0
- nautobot/docs/media/ss_main_page.png +0 -0
- nautobot/docs/media/ss_plugin_chatops.png +0 -0
- nautobot/docs/media/ss_plugin_golden_config.png +0 -0
- nautobot/docs/media/ss_prefix_hierarchy.png +0 -0
- nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-1.png +0 -0
- nautobot/docs/media/user-guide/administration/guides/s3-django-storage/user-guide-s3-2.png +0 -0
- nautobot/docs/media/user-guide/administration/upgrading/from-v1/ipam/tenant-affinity.png +0 -0
- nautobot/docs/nautobot_logo.png +0 -0
- nautobot/docs/nautobot_logo.svg +0 -131
- nautobot/docs/release-notes/index.md +0 -3
- nautobot/docs/release-notes/version-1.0.md +0 -530
- nautobot/docs/release-notes/version-1.1.md +0 -337
- nautobot/docs/release-notes/version-1.2.md +0 -509
- nautobot/docs/release-notes/version-1.3.md +0 -554
- nautobot/docs/release-notes/version-1.4.md +0 -677
- nautobot/docs/release-notes/version-1.5.md +0 -840
- nautobot/docs/release-notes/version-1.6.md +0 -290
- nautobot/docs/release-notes/version-2.0.md +0 -1359
- nautobot/docs/requirements.txt +0 -12
- nautobot/docs/user-guide/administration/configuration/authentication/ldap.md +0 -286
- nautobot/docs/user-guide/administration/configuration/authentication/remote.md +0 -46
- nautobot/docs/user-guide/administration/configuration/authentication/sso.md +0 -528
- nautobot/docs/user-guide/administration/configuration/index.md +0 -190
- nautobot/docs/user-guide/administration/configuration/node-configuration.md +0 -31
- nautobot/docs/user-guide/administration/configuration/optional-settings.md +0 -1302
- nautobot/docs/user-guide/administration/configuration/required-settings.md +0 -244
- nautobot/docs/user-guide/administration/guides/caching.md +0 -108
- nautobot/docs/user-guide/administration/guides/celery-queues.md +0 -42
- nautobot/docs/user-guide/administration/guides/healthcheck.md +0 -11
- nautobot/docs/user-guide/administration/guides/permissions.md +0 -98
- nautobot/docs/user-guide/administration/guides/prometheus-metrics.md +0 -55
- nautobot/docs/user-guide/administration/guides/replicating-nautobot.md +0 -70
- nautobot/docs/user-guide/administration/guides/s3-django-storage.md +0 -145
- nautobot/docs/user-guide/administration/installation/app-install.md +0 -94
- nautobot/docs/user-guide/administration/installation/docker.md +0 -286
- nautobot/docs/user-guide/administration/installation/external-authentication.md +0 -9
- nautobot/docs/user-guide/administration/installation/http-server.md +0 -279
- nautobot/docs/user-guide/administration/installation/index.md +0 -101
- nautobot/docs/user-guide/administration/installation/install_system.md +0 -493
- nautobot/docs/user-guide/administration/installation/nautobot.md +0 -367
- nautobot/docs/user-guide/administration/installation/selinux-troubleshooting.md +0 -194
- nautobot/docs/user-guide/administration/installation/services.md +0 -340
- nautobot/docs/user-guide/administration/migration/migrating-from-netbox.md +0 -336
- nautobot/docs/user-guide/administration/migration/migrating-from-postgresql.md +0 -122
- nautobot/docs/user-guide/administration/tools/nautobot-server.md +0 -858
- nautobot/docs/user-guide/administration/tools/nautobot-shell.md +0 -263
- nautobot/docs/user-guide/administration/upgrading/database-backup.md +0 -11
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.md +0 -55
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.md +0 -73
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.md +0 -211
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/index.md +0 -16
- nautobot/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.md +0 -157
- nautobot/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.md +0 -153
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-behavior-changes.yaml +0 -82
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-removed-fields.yaml +0 -175
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-api-renamed-fields.yaml +0 -124
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-location-changes.yaml +0 -241
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-removals.yaml +0 -57
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-renames.yaml +0 -5
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-behavior-changes.yaml +0 -76
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-removed-fields.yaml +0 -202
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-database-renamed-fields.yaml +0 -343
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-corrected-fields.yaml +0 -31
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-enhanced-fields.yaml +0 -244
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-removed-fields.yaml +0 -595
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-filters-renamed-fields.yaml +0 -253
- nautobot/docs/user-guide/administration/upgrading/from-v1/tables/v2-logging-renamed-loggers.yaml +0 -23
- nautobot/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.md +0 -574
- nautobot/docs/user-guide/administration/upgrading/upgrading.md +0 -127
- nautobot/docs/user-guide/core-data-model/circuits/circuit.md +0 -19
- nautobot/docs/user-guide/core-data-model/circuits/circuittermination.md +0 -10
- nautobot/docs/user-guide/core-data-model/circuits/circuittype.md +0 -8
- nautobot/docs/user-guide/core-data-model/circuits/provider.md +0 -5
- nautobot/docs/user-guide/core-data-model/circuits/providernetwork.md +0 -7
- nautobot/docs/user-guide/core-data-model/dcim/cable.md +0 -43
- nautobot/docs/user-guide/core-data-model/dcim/consoleport.md +0 -8
- nautobot/docs/user-guide/core-data-model/dcim/consoleporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/consoleserverport.md +0 -8
- nautobot/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/device.md +0 -29
- nautobot/docs/user-guide/core-data-model/dcim/devicebay.md +0 -11
- nautobot/docs/user-guide/core-data-model/dcim/devicebaytemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/deviceredundancygroup.md +0 -279
- nautobot/docs/user-guide/core-data-model/dcim/devicetype.md +0 -44
- nautobot/docs/user-guide/core-data-model/dcim/frontport.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/frontporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/interface.md +0 -34
- nautobot/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.md +0 -24
- nautobot/docs/user-guide/core-data-model/dcim/interfacetemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/inventoryitem.md +0 -10
- nautobot/docs/user-guide/core-data-model/dcim/location.md +0 -15
- nautobot/docs/user-guide/core-data-model/dcim/locationtype.md +0 -43
- nautobot/docs/user-guide/core-data-model/dcim/manufacturer.md +0 -3
- nautobot/docs/user-guide/core-data-model/dcim/platform.md +0 -19
- nautobot/docs/user-guide/core-data-model/dcim/powerfeed.md +0 -25
- nautobot/docs/user-guide/core-data-model/dcim/poweroutlet.md +0 -14
- nautobot/docs/user-guide/core-data-model/dcim/poweroutlettemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/powerpanel.md +0 -12
- nautobot/docs/user-guide/core-data-model/dcim/powerport.md +0 -15
- nautobot/docs/user-guide/core-data-model/dcim/powerporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/rack.md +0 -41
- nautobot/docs/user-guide/core-data-model/dcim/rackgroup.md +0 -7
- nautobot/docs/user-guide/core-data-model/dcim/rackreservation.md +0 -3
- nautobot/docs/user-guide/core-data-model/dcim/rearport.md +0 -9
- nautobot/docs/user-guide/core-data-model/dcim/rearporttemplate.md +0 -6
- nautobot/docs/user-guide/core-data-model/dcim/virtualchassis.md +0 -8
- nautobot/docs/user-guide/core-data-model/extras/configcontext.md +0 -78
- nautobot/docs/user-guide/core-data-model/extras/configcontextschema.md +0 -73
- nautobot/docs/user-guide/core-data-model/ipam/ipaddress.md +0 -69
- nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +0 -1
- nautobot/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
- nautobot/docs/user-guide/core-data-model/ipam/namespace.md +0 -18
- nautobot/docs/user-guide/core-data-model/ipam/prefix.md +0 -65
- nautobot/docs/user-guide/core-data-model/ipam/rir.md +0 -10
- nautobot/docs/user-guide/core-data-model/ipam/routetarget.md +0 -5
- nautobot/docs/user-guide/core-data-model/ipam/service.md +0 -8
- nautobot/docs/user-guide/core-data-model/ipam/vlan.md +0 -17
- nautobot/docs/user-guide/core-data-model/ipam/vlangroup.md +0 -5
- nautobot/docs/user-guide/core-data-model/ipam/vrf.md +0 -15
- nautobot/docs/user-guide/core-data-model/tenancy/tenant.md +0 -20
- nautobot/docs/user-guide/core-data-model/tenancy/tenantgroup.md +0 -5
- nautobot/docs/user-guide/core-data-model/virtualization/cluster.md +0 -5
- nautobot/docs/user-guide/core-data-model/virtualization/clustergroup.md +0 -3
- nautobot/docs/user-guide/core-data-model/virtualization/clustertype.md +0 -3
- nautobot/docs/user-guide/core-data-model/virtualization/virtualmachine.md +0 -17
- nautobot/docs/user-guide/core-data-model/virtualization/vminterface.md +0 -19
- nautobot/docs/user-guide/feature-guides/custom-fields.md +0 -350
- nautobot/docs/user-guide/feature-guides/getting-started/creating-devices.md +0 -130
- nautobot/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.md +0 -113
- nautobot/docs/user-guide/feature-guides/getting-started/index.md +0 -29
- nautobot/docs/user-guide/feature-guides/getting-started/interfaces.md +0 -100
- nautobot/docs/user-guide/feature-guides/getting-started/ipam.md +0 -104
- nautobot/docs/user-guide/feature-guides/getting-started/platforms.md +0 -78
- nautobot/docs/user-guide/feature-guides/getting-started/search-bar.md +0 -40
- nautobot/docs/user-guide/feature-guides/getting-started/tenants.md +0 -40
- nautobot/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.md +0 -87
- nautobot/docs/user-guide/feature-guides/git-data-source.md +0 -307
- nautobot/docs/user-guide/feature-guides/graphql.md +0 -342
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
- nautobot/docs/user-guide/feature-guides/ip-address-merge-tool.md +0 -63
- nautobot/docs/user-guide/feature-guides/relationships.md +0 -125
- nautobot/docs/user-guide/index.md +0 -1
- nautobot/docs/user-guide/platform-functionality/change-logging.md +0 -21
- nautobot/docs/user-guide/platform-functionality/computedfield.md +0 -89
- nautobot/docs/user-guide/platform-functionality/customfield.md +0 -123
- nautobot/docs/user-guide/platform-functionality/customlink.md +0 -59
- nautobot/docs/user-guide/platform-functionality/dynamicgroup.md +0 -660
- nautobot/docs/user-guide/platform-functionality/exporttemplate.md +0 -55
- nautobot/docs/user-guide/platform-functionality/gitrepository.md +0 -353
- nautobot/docs/user-guide/platform-functionality/graphql.md +0 -259
- nautobot/docs/user-guide/platform-functionality/graphqlquery.md +0 -28
- nautobot/docs/user-guide/platform-functionality/imageattachment.md +0 -10
- nautobot/docs/user-guide/platform-functionality/jobs/index.md +0 -193
- nautobot/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.md +0 -78
- nautobot/docs/user-guide/platform-functionality/jobs/jobbutton.md +0 -79
- nautobot/docs/user-guide/platform-functionality/jobs/jobhook.md +0 -15
- nautobot/docs/user-guide/platform-functionality/jobs/models.md +0 -65
- nautobot/docs/user-guide/platform-functionality/napalm.md +0 -85
- nautobot/docs/user-guide/platform-functionality/note.md +0 -7
- nautobot/docs/user-guide/platform-functionality/relationship.md +0 -158
- nautobot/docs/user-guide/platform-functionality/rest-api/authentication.md +0 -67
- nautobot/docs/user-guide/platform-functionality/rest-api/filtering.md +0 -142
- nautobot/docs/user-guide/platform-functionality/rest-api/overview.md +0 -1045
- nautobot/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.md +0 -9
- nautobot/docs/user-guide/platform-functionality/role.md +0 -17
- nautobot/docs/user-guide/platform-functionality/secret.md +0 -136
- nautobot/docs/user-guide/platform-functionality/status.md +0 -92
- nautobot/docs/user-guide/platform-functionality/tag.md +0 -62
- nautobot/docs/user-guide/platform-functionality/template-filters.md +0 -306
- nautobot/docs/user-guide/platform-functionality/users/objectpermission.md +0 -56
- nautobot/docs/user-guide/platform-functionality/users/token.md +0 -21
- nautobot/docs/user-guide/platform-functionality/webhook.md +0 -137
- nautobot/project-static/docs/media/nautobot_application_stack_low_level.drawio +0 -1
- nautobot/project-static/docs/media/nautobot_chatops.gif +0 -0
- nautobot/project-static/docs/media/nautobot_config_context.gif +0 -0
- nautobot/project-static/docs/media/nautobot_golden_config.gif +0 -0
- nautobot/project-static/docs/media/nautobot_graphql.gif +0 -0
- nautobot/project-static/docs/media/nautobot_mainpage.gif +0 -0
- nautobot/project-static/docs/media/nautobot_prefix_hierarchy.gif +0 -0
- nautobot-2.0.4.dist-info/LICENSE.txt +0 -177
- /LICENSE.txt → /nautobot-2.1.0b1.dist-info/LICENSE.txt +0 -0
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/WHEEL +0 -0
- {nautobot-2.0.4.dist-info → nautobot-2.1.0b1.dist-info}/entry_points.txt +0 -0
|
@@ -442,58 +442,61 @@ class LookupRelatedFunctionTest(TestCase):
|
|
|
442
442
|
location_fields = ["comments", "name", "contact_email", "physical_address", "shipping_address"]
|
|
443
443
|
for field_name in location_fields:
|
|
444
444
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Location, field_name)
|
|
445
|
-
self.
|
|
445
|
+
self.assertIs(type(form_field), forms.MultiValueCharField)
|
|
446
446
|
|
|
447
447
|
device_fields = ["serial", "name"]
|
|
448
448
|
for field_name in device_fields:
|
|
449
449
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, field_name)
|
|
450
|
-
self.
|
|
450
|
+
self.assertIs(type(form_field), forms.MultiValueCharField)
|
|
451
451
|
|
|
452
452
|
with self.subTest("Test IntegerField"):
|
|
453
453
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Location, "asn")
|
|
454
|
-
self.
|
|
454
|
+
self.assertIs(type(form_field), django_forms.IntegerField)
|
|
455
455
|
|
|
456
456
|
device_fields = ["vc_position", "vc_priority"]
|
|
457
457
|
for field_name in device_fields:
|
|
458
458
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, field_name)
|
|
459
|
-
self.
|
|
459
|
+
self.assertIs(type(form_field), django_forms.IntegerField)
|
|
460
460
|
|
|
461
461
|
with self.subTest("Test DynamicModelMultipleChoiceField"):
|
|
462
462
|
location_fields = ["tenant", "status"]
|
|
463
463
|
for field_name in location_fields:
|
|
464
464
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Location, field_name)
|
|
465
|
-
self.
|
|
465
|
+
self.assertIs(type(form_field), forms.DynamicModelMultipleChoiceField)
|
|
466
466
|
|
|
467
467
|
device_fields = ["cluster", "device_type", "location"]
|
|
468
468
|
for field_name in device_fields:
|
|
469
469
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, field_name)
|
|
470
|
-
self.
|
|
470
|
+
self.assertIs(type(form_field), forms.DynamicModelMultipleChoiceField)
|
|
471
471
|
|
|
472
|
-
with self.subTest("Test NullBooleanField"):
|
|
473
472
|
location_fields = ["has_circuit_terminations", "has_devices"]
|
|
474
473
|
for field_name in location_fields:
|
|
475
|
-
|
|
476
|
-
|
|
474
|
+
with self.subTest("Test ChoiceField", model=dcim_models.Location, field_name=field_name):
|
|
475
|
+
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Location, field_name)
|
|
476
|
+
self.assertIs(type(form_field), django_forms.ChoiceField)
|
|
477
|
+
self.assertIs(type(form_field.widget), forms.StaticSelect2)
|
|
477
478
|
|
|
478
|
-
device_fields = ["has_console_ports", "has_interfaces"]
|
|
479
|
+
device_fields = ["has_console_ports", "has_interfaces", "local_config_context_data"]
|
|
479
480
|
for field_name in device_fields:
|
|
480
|
-
|
|
481
|
-
|
|
481
|
+
with self.subTest("Test ChoiceField", model=dcim_models.Device, field_name=field_name):
|
|
482
|
+
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, field_name)
|
|
483
|
+
self.assertIs(type(form_field), django_forms.ChoiceField)
|
|
484
|
+
self.assertIs(type(form_field.widget), forms.StaticSelect2)
|
|
482
485
|
|
|
483
|
-
with self.subTest("Test
|
|
486
|
+
with self.subTest("Test MultipleChoiceField"):
|
|
484
487
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, "face")
|
|
485
|
-
self.
|
|
488
|
+
self.assertIs(type(form_field), django_forms.MultipleChoiceField)
|
|
486
489
|
|
|
487
490
|
with self.subTest("Test DateTimePicker"):
|
|
488
491
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Location, "last_updated")
|
|
489
|
-
self.
|
|
492
|
+
self.assertIs(type(form_field.widget), forms.DateTimePicker)
|
|
490
493
|
|
|
491
494
|
form_field = filtering.get_filterset_parameter_form_field(dcim_models.Device, "last_updated")
|
|
492
|
-
self.
|
|
495
|
+
self.assertIs(type(form_field.widget), forms.DateTimePicker)
|
|
493
496
|
|
|
494
497
|
with self.subTest("Test DatePicker"):
|
|
495
498
|
form_field = filtering.get_filterset_parameter_form_field(circuits_models.Circuit, "install_date")
|
|
496
|
-
self.
|
|
499
|
+
self.assertIs(type(form_field.widget), forms.DatePicker)
|
|
497
500
|
|
|
498
501
|
with self.subTest("Test Invalid parameter"):
|
|
499
502
|
with self.assertRaises(exceptions.FilterSetFieldNotFound) as err:
|
|
@@ -502,15 +505,15 @@ class LookupRelatedFunctionTest(TestCase):
|
|
|
502
505
|
|
|
503
506
|
with self.subTest("Test Content types"):
|
|
504
507
|
form_field = filtering.get_filterset_parameter_form_field(extras_models.Status, "content_types")
|
|
505
|
-
self.
|
|
508
|
+
self.assertIs(type(form_field), forms.MultipleContentTypeField)
|
|
506
509
|
|
|
507
510
|
# Assert total ContentTypes generated by form_field is == total `content_types` generated by TaggableClassesQuery
|
|
508
511
|
form_field = filtering.get_filterset_parameter_form_field(extras_models.Tag, "content_types")
|
|
509
|
-
self.
|
|
512
|
+
self.assertIs(type(form_field), forms.MultipleContentTypeField)
|
|
510
513
|
self.assertEqual(form_field.queryset.count(), extras_utils.TaggableClassesQuery().as_queryset().count())
|
|
511
514
|
|
|
512
515
|
form_field = filtering.get_filterset_parameter_form_field(extras_models.JobHook, "content_types")
|
|
513
|
-
self.
|
|
516
|
+
self.assertIs(type(form_field), forms.MultipleContentTypeField)
|
|
514
517
|
self.assertEqual(form_field.queryset.count(), extras_utils.ChangeLoggedModelsQuery().as_queryset().count())
|
|
515
518
|
|
|
516
519
|
def test_convert_querydict_to_factory_formset_dict(self):
|
|
@@ -37,7 +37,7 @@ class HomeViewTestCase(TestCase):
|
|
|
37
37
|
|
|
38
38
|
# Search bar in nav
|
|
39
39
|
nav_search_bar_pattern = re.compile(
|
|
40
|
-
'<nav.*<form action="/search/" method="get" class="navbar-form
|
|
40
|
+
'<nav.*<form action="/search/" method="get" class="navbar-form" id="navbar_search" role="search">.*</form>.*</nav>'
|
|
41
41
|
)
|
|
42
42
|
nav_search_bar_result = nav_search_bar_pattern.search(
|
|
43
43
|
response.content.decode(response.charset).replace("\n", "")
|
|
@@ -53,8 +53,7 @@ class HomeViewTestCase(TestCase):
|
|
|
53
53
|
|
|
54
54
|
return nav_search_bar_result, body_search_bar_result
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
def test_search_bar_not_visible_if_user_not_authenticated_and_hide_restricted_ui_True(self):
|
|
56
|
+
def test_search_bar_not_visible_if_user_not_authenticated(self):
|
|
58
57
|
self.client.logout()
|
|
59
58
|
|
|
60
59
|
nav_search_bar_result, body_search_bar_result = self.make_request()
|
|
@@ -62,23 +61,7 @@ class HomeViewTestCase(TestCase):
|
|
|
62
61
|
self.assertIsNone(nav_search_bar_result)
|
|
63
62
|
self.assertIsNone(body_search_bar_result)
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
def test_search_bar_visible_if_user_authenticated_and_hide_restricted_ui_True(self):
|
|
67
|
-
nav_search_bar_result, body_search_bar_result = self.make_request()
|
|
68
|
-
|
|
69
|
-
self.assertIsNotNone(nav_search_bar_result)
|
|
70
|
-
self.assertIsNotNone(body_search_bar_result)
|
|
71
|
-
|
|
72
|
-
@override_settings(HIDE_RESTRICTED_UI=False)
|
|
73
|
-
def test_search_bar_visible_if_hide_restricted_ui_False(self):
|
|
74
|
-
# Assert if user is authenticated
|
|
75
|
-
nav_search_bar_result, body_search_bar_result = self.make_request()
|
|
76
|
-
|
|
77
|
-
self.assertIsNotNone(nav_search_bar_result)
|
|
78
|
-
self.assertIsNotNone(body_search_bar_result)
|
|
79
|
-
|
|
80
|
-
# Assert if user is logout
|
|
81
|
-
self.client.logout()
|
|
64
|
+
def test_search_bar_visible_if_user_authenticated(self):
|
|
82
65
|
nav_search_bar_result, body_search_bar_result = self.make_request()
|
|
83
66
|
|
|
84
67
|
self.assertIsNotNone(nav_search_bar_result)
|
|
@@ -229,27 +212,8 @@ class NavRestrictedUI(TestCase):
|
|
|
229
212
|
response = self.client.get(reverse("home"))
|
|
230
213
|
return response.content.decode(response.charset)
|
|
231
214
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
"""The "Installed Apps" menu item should be available to is_staff user regardless of HIDE_RESTRICTED_UI."""
|
|
235
|
-
# Make user admin
|
|
236
|
-
self.user.is_staff = True
|
|
237
|
-
self.user.save()
|
|
238
|
-
|
|
239
|
-
response_content = self.make_request()
|
|
240
|
-
self.assertInHTML(
|
|
241
|
-
f"""
|
|
242
|
-
<a href="{self.url}"
|
|
243
|
-
data-item-weight="{self.item_weight}">
|
|
244
|
-
Installed Plugins
|
|
245
|
-
</a>
|
|
246
|
-
""",
|
|
247
|
-
response_content,
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
@override_settings(HIDE_RESTRICTED_UI=False)
|
|
251
|
-
def test_installed_apps_visible_to_staff_with_hide_restricted_ui_false(self):
|
|
252
|
-
"""The "Installed Apps" menu item should be available to is_staff user regardless of HIDE_RESTRICTED_UI."""
|
|
215
|
+
def test_installed_apps_visible_to_staff(self):
|
|
216
|
+
"""The "Installed Apps" menu item should be available to is_staff user."""
|
|
253
217
|
# Make user admin
|
|
254
218
|
self.user.is_staff = True
|
|
255
219
|
self.user.save()
|
|
@@ -265,29 +229,11 @@ class NavRestrictedUI(TestCase):
|
|
|
265
229
|
response_content,
|
|
266
230
|
)
|
|
267
231
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
"""The "Installed Apps" menu item should be hidden from a non-staff user when HIDE_RESTRICTED_UI=True."""
|
|
271
|
-
response_content = self.make_request()
|
|
272
|
-
|
|
273
|
-
self.assertNotRegex(response_content, r"Installed\s+Apps")
|
|
274
|
-
|
|
275
|
-
@override_settings(HIDE_RESTRICTED_UI=False)
|
|
276
|
-
def test_installed_apps_disabled_to_non_staff_user_with_hide_restricted_ui_false(self):
|
|
277
|
-
"""The "Installed Apps" menu item should be disabled for a non-staff user when HIDE_RESTRICTED_UI=False."""
|
|
232
|
+
def test_installed_apps_not_visible_to_non_staff_user_without_permission(self):
|
|
233
|
+
"""The "Installed Apps" menu item should be hidden from a non-staff user without permission."""
|
|
278
234
|
response_content = self.make_request()
|
|
279
235
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
self.assertInHTML(
|
|
283
|
-
f"""
|
|
284
|
-
<a href="{self.url}"
|
|
285
|
-
data-item-weight="{self.item_weight}">
|
|
286
|
-
Installed Plugins
|
|
287
|
-
</a>
|
|
288
|
-
""",
|
|
289
|
-
response_content,
|
|
290
|
-
)
|
|
236
|
+
self.assertNotRegex(response_content, r"Installed\s+Plugins")
|
|
291
237
|
|
|
292
238
|
|
|
293
239
|
class LoginUI(TestCase):
|
|
@@ -326,9 +272,9 @@ class LoginUI(TestCase):
|
|
|
326
272
|
sso_login_search_result = self.make_request()
|
|
327
273
|
self.assertIsNotNone(sso_login_search_result)
|
|
328
274
|
|
|
329
|
-
@override_settings(
|
|
330
|
-
def
|
|
331
|
-
"""Assert that api docs and graphql redirects to login page if user is unauthenticated
|
|
275
|
+
@override_settings(BANNER_TOP="Hello, Banner Top", BANNER_BOTTOM="Hello, Banner Bottom")
|
|
276
|
+
def test_routes_redirect_back_to_login_unauthenticated(self):
|
|
277
|
+
"""Assert that api docs and graphql redirects to login page if user is unauthenticated."""
|
|
332
278
|
self.client.logout()
|
|
333
279
|
headers = {"HTTP_ACCEPT": "text/html"}
|
|
334
280
|
urls = [reverse("api_docs"), reverse("graphql")]
|
|
@@ -346,26 +292,6 @@ class LoginUI(TestCase):
|
|
|
346
292
|
self.assertNotIn("Hello, Banner Top", response_content)
|
|
347
293
|
self.assertNotIn("Hello, Banner Bottom", response_content)
|
|
348
294
|
|
|
349
|
-
@override_settings(HIDE_RESTRICTED_UI=False, BANNER_TOP="Hello, Banner Top", BANNER_BOTTOM="Hello, Banner Bottom")
|
|
350
|
-
def test_routes_no_redirect_back_to_login_if_hide_restricted_ui_false(self):
|
|
351
|
-
"""Assert that api docs and graphql do not redirects to login page if user is unauthenticated and HIDE_RESTRICTED_UI=False."""
|
|
352
|
-
self.client.logout()
|
|
353
|
-
headers = {"HTTP_ACCEPT": "text/html"}
|
|
354
|
-
urls = [reverse("api_docs"), reverse("graphql")]
|
|
355
|
-
for url in urls:
|
|
356
|
-
response = self.client.get(url, **headers)
|
|
357
|
-
self.assertHttpStatus(response, 200)
|
|
358
|
-
self.assertEqual(response.request["PATH_INFO"], url)
|
|
359
|
-
response_content = response.content.decode(response.charset).replace("\n", "")
|
|
360
|
-
# Assert Footer items(`self.footer_elements`), Banner and Banner Top is not hidden
|
|
361
|
-
for footer_text in self.footer_elements:
|
|
362
|
-
self.assertInHTML(footer_text, response_content)
|
|
363
|
-
|
|
364
|
-
# Only API Docs implements BANNERS
|
|
365
|
-
if url == urls[0]:
|
|
366
|
-
self.assertInHTML("Hello, Banner Top", response_content)
|
|
367
|
-
self.assertInHTML("Hello, Banner Bottom", response_content)
|
|
368
|
-
|
|
369
295
|
|
|
370
296
|
class MetricsViewTestCase(TestCase):
|
|
371
297
|
def query_and_parse_metrics(self):
|
nautobot/core/urls.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.conf import settings
|
|
2
2
|
from django.conf.urls import include
|
|
3
3
|
from django.urls import path
|
|
4
|
+
from django.views.generic import TemplateView
|
|
4
5
|
from django.views.static import serve
|
|
5
6
|
|
|
6
7
|
from nautobot.core.views import CustomGraphQLView, HomeView, StaticMediaFailureView, SearchView, nautobot_metrics_view
|
|
@@ -31,7 +32,7 @@ urlpatterns = [
|
|
|
31
32
|
path("api/", include("nautobot.core.api.urls")),
|
|
32
33
|
# GraphQL
|
|
33
34
|
path("graphql/", CustomGraphQLView.as_view(graphiql=True), name="graphql"),
|
|
34
|
-
# Serving static media in Django
|
|
35
|
+
# Serving static media in Django (TODO: should be DEBUG mode only - "This view is NOT hardened for production use")
|
|
35
36
|
path("media/<path:path>", serve, {"document_root": settings.MEDIA_ROOT}),
|
|
36
37
|
# Admin
|
|
37
38
|
path("admin/", admin_site.urls),
|
|
@@ -46,6 +47,10 @@ urlpatterns = [
|
|
|
46
47
|
path(r"health/", include("health_check.urls")),
|
|
47
48
|
# FileProxy attachments download/get URLs used in admin views only
|
|
48
49
|
path("files/", include("db_file_storage.urls")),
|
|
50
|
+
# Templated css file
|
|
51
|
+
path(
|
|
52
|
+
"template.css", TemplateView.as_view(template_name="template.css", content_type="text/css"), name="template_css"
|
|
53
|
+
),
|
|
49
54
|
]
|
|
50
55
|
|
|
51
56
|
|
nautobot/core/utils/data.py
CHANGED
|
@@ -100,7 +100,11 @@ def render_jinja2(template_code, context):
|
|
|
100
100
|
"""
|
|
101
101
|
rendering_engine = engines["jinja"]
|
|
102
102
|
template = rendering_engine.from_string(template_code)
|
|
103
|
-
|
|
103
|
+
# For reasons unknown to me, django-jinja2 `template.render()` implicitly calls `mark_safe()` on the rendered text.
|
|
104
|
+
# This is a security risk in general, especially so in our case because we're often using this function to render
|
|
105
|
+
# a user-provided template and don't want to open ourselves up to script injection or similar issues.
|
|
106
|
+
# There's no `mark_unsafe()` function, but concatenating a SafeString to an ordinary string (even "") suffices.
|
|
107
|
+
return "" + template.render(context=context)
|
|
104
108
|
|
|
105
109
|
|
|
106
110
|
def shallow_compare_dict(source_dict, destination_dict, exclude=None):
|
nautobot/core/utils/filtering.py
CHANGED
|
@@ -2,6 +2,7 @@ import re
|
|
|
2
2
|
|
|
3
3
|
from django import forms
|
|
4
4
|
from django_filters import (
|
|
5
|
+
BooleanFilter,
|
|
5
6
|
ChoiceFilter,
|
|
6
7
|
ModelMultipleChoiceFilter,
|
|
7
8
|
MultipleChoiceFilter,
|
|
@@ -93,8 +94,10 @@ def get_filterset_parameter_form_field(model, parameter, filterset=None):
|
|
|
93
94
|
from nautobot.extras.utils import ChangeLoggedModelsQuery, RoleModelsQuery, TaggableClassesQuery
|
|
94
95
|
from nautobot.core.filters import MultiValueDecimalFilter, MultiValueFloatFilter
|
|
95
96
|
from nautobot.core.forms import (
|
|
97
|
+
BOOLEAN_CHOICES,
|
|
96
98
|
DynamicModelMultipleChoiceField,
|
|
97
99
|
MultipleContentTypeField,
|
|
100
|
+
StaticSelect2,
|
|
98
101
|
StaticSelect2Multiple,
|
|
99
102
|
)
|
|
100
103
|
from nautobot.virtualization.models import VirtualMachine
|
|
@@ -150,11 +153,10 @@ def get_filterset_parameter_form_field(model, parameter, filterset=None):
|
|
|
150
153
|
choices_as_strings=True, queryset=queryset_map[plural_name]().as_queryset()
|
|
151
154
|
)
|
|
152
155
|
elif isinstance(field, (MultipleChoiceFilter, ChoiceFilter)) and "choices" in field.extra:
|
|
153
|
-
|
|
154
|
-
form_field_class.widget = StaticSelect2Multiple()
|
|
155
|
-
form_attr = {"choices": field.extra.get("choices")}
|
|
156
|
+
form_field = forms.MultipleChoiceField(choices=field.extra.get("choices"), widget=StaticSelect2Multiple)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
elif isinstance(field, BooleanFilter):
|
|
159
|
+
form_field = forms.ChoiceField(choices=BOOLEAN_CHOICES, widget=StaticSelect2)
|
|
158
160
|
|
|
159
161
|
form_field.required = False
|
|
160
162
|
form_field.initial = None
|
nautobot/core/utils/lookup.py
CHANGED
|
@@ -192,3 +192,31 @@ def get_table_for_model(model):
|
|
|
192
192
|
(Union[Table, None]): Either the `Table` class or `None`
|
|
193
193
|
"""
|
|
194
194
|
return get_related_class_for_model(model, module_name="tables", object_suffix="Table")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_created_and_last_updated_usernames_for_model(instance):
|
|
198
|
+
"""
|
|
199
|
+
Args:
|
|
200
|
+
instance: A model class instance
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
created_by: Username of the user that created the instance
|
|
204
|
+
last_updated_by: Username of the user that last modified the instance
|
|
205
|
+
"""
|
|
206
|
+
from nautobot.extras.choices import ObjectChangeActionChoices
|
|
207
|
+
from nautobot.extras.models import ObjectChange
|
|
208
|
+
|
|
209
|
+
object_change_records = get_changes_for_model(instance)
|
|
210
|
+
created_by = None
|
|
211
|
+
last_updated_by = None
|
|
212
|
+
try:
|
|
213
|
+
created_by_record = object_change_records.get(action=ObjectChangeActionChoices.ACTION_CREATE)
|
|
214
|
+
created_by = created_by_record.user_name
|
|
215
|
+
except ObjectChange.DoesNotExist:
|
|
216
|
+
pass
|
|
217
|
+
|
|
218
|
+
last_updated_by_record = object_change_records.first()
|
|
219
|
+
if last_updated_by_record:
|
|
220
|
+
last_updated_by = last_updated_by_record.user_name
|
|
221
|
+
|
|
222
|
+
return created_by, last_updated_by
|
nautobot/core/utils/requests.py
CHANGED
|
@@ -114,13 +114,12 @@ def get_filterable_params_from_filter_params(filter_params, non_filter_params, f
|
|
|
114
114
|
Returns:
|
|
115
115
|
(QueryDict): Filter param querydict with only queryset filterable params
|
|
116
116
|
"""
|
|
117
|
-
for non_filter_param in non_filter_params:
|
|
118
|
-
filter_params.pop(non_filter_param, None)
|
|
119
|
-
|
|
120
117
|
# Some FilterSet field only accept single choice not multiple choices
|
|
121
118
|
# e.g datetime field, bool fields etc.
|
|
122
119
|
final_filter_params = {}
|
|
123
120
|
for field in filter_params.keys():
|
|
121
|
+
if field in non_filter_params:
|
|
122
|
+
continue
|
|
124
123
|
if filter_params.get(field):
|
|
125
124
|
# `is_single_choice_field` implements `get_filterset_field`, which throws an exception if a field is not found.
|
|
126
125
|
# If an exception is thrown, instead of throwing an exception, set `_is_single_choice_field` to 'False'
|
nautobot/core/views/__init__.py
CHANGED
|
@@ -25,7 +25,6 @@ from prometheus_client.registry import Collector
|
|
|
25
25
|
from nautobot.core.constants import SEARCH_MAX_RESULTS
|
|
26
26
|
from nautobot.core.forms import SearchForm
|
|
27
27
|
from nautobot.core.releases import get_latest_release
|
|
28
|
-
from nautobot.core.utils.config import get_settings_or_config
|
|
29
28
|
from nautobot.core.utils.lookup import get_route_for_model
|
|
30
29
|
from nautobot.extras.models import GraphQLQuery
|
|
31
30
|
from nautobot.extras.registry import registry
|
|
@@ -58,8 +57,8 @@ class HomeView(AccessMixin, TemplateView):
|
|
|
58
57
|
return template.render(additional_context)
|
|
59
58
|
|
|
60
59
|
def get(self, request, *args, **kwargs):
|
|
61
|
-
# Redirect user to login page if not authenticated
|
|
62
|
-
if not request.user.is_authenticated
|
|
60
|
+
# Redirect user to login page if not authenticated
|
|
61
|
+
if not request.user.is_authenticated:
|
|
63
62
|
return self.handle_no_permission()
|
|
64
63
|
# Check whether a new release is available. (Only for staff/superusers.)
|
|
65
64
|
new_release = None
|
|
@@ -242,7 +241,7 @@ def csrf_failure(request, reason="", template_name="403_csrf_failure.html"):
|
|
|
242
241
|
|
|
243
242
|
class CustomGraphQLView(GraphQLView):
|
|
244
243
|
def render_graphiql(self, request, **data):
|
|
245
|
-
if not request.user.is_authenticated
|
|
244
|
+
if not request.user.is_authenticated:
|
|
246
245
|
graphql_url = reverse("graphql")
|
|
247
246
|
login_url = reverse(settings.LOGIN_URL)
|
|
248
247
|
return redirect(f"{login_url}?next={graphql_url}")
|
nautobot/core/views/generic.py
CHANGED
|
@@ -16,9 +16,8 @@ from django.db.models import ManyToManyField, ProtectedError
|
|
|
16
16
|
from django.forms import Form, ModelMultipleChoiceField, MultipleHiddenInput
|
|
17
17
|
from django.http import HttpResponse, JsonResponse
|
|
18
18
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
19
|
-
from django.utils.html import
|
|
19
|
+
from django.utils.html import format_html
|
|
20
20
|
from django.utils.http import is_safe_url
|
|
21
|
-
from django.utils.safestring import mark_safe
|
|
22
21
|
from django.views.generic import View
|
|
23
22
|
from django_tables2 import RequestConfig
|
|
24
23
|
from rest_framework.exceptions import ParseError
|
|
@@ -40,6 +39,7 @@ from nautobot.core.forms import (
|
|
|
40
39
|
from nautobot.core.forms.forms import DynamicFilterFormSet
|
|
41
40
|
from nautobot.core.templatetags.helpers import bettertitle, validated_viewname
|
|
42
41
|
from nautobot.core.utils.config import get_settings_or_config
|
|
42
|
+
from nautobot.core.utils.lookup import get_created_and_last_updated_usernames_for_model
|
|
43
43
|
from nautobot.core.utils.permissions import get_permission_for_model
|
|
44
44
|
from nautobot.core.utils.requests import (
|
|
45
45
|
convert_querydict_to_factory_formset_acceptable_querydict,
|
|
@@ -101,6 +101,8 @@ class ObjectView(ObjectPermissionRequiredMixin, View):
|
|
|
101
101
|
Generic GET handler for accessing an object.
|
|
102
102
|
"""
|
|
103
103
|
instance = get_object_or_404(self.queryset, **kwargs)
|
|
104
|
+
# Get the ObjectChange records to populate the advanced tab information
|
|
105
|
+
created_by, last_updated_by = get_created_and_last_updated_usernames_for_model(instance)
|
|
104
106
|
|
|
105
107
|
# TODO: this feels inelegant - should the tabs lookup be a dedicated endpoint rather than piggybacking
|
|
106
108
|
# on the object-retrieve endpoint?
|
|
@@ -128,6 +130,8 @@ class ObjectView(ObjectPermissionRequiredMixin, View):
|
|
|
128
130
|
"object": instance,
|
|
129
131
|
"verbose_name": self.queryset.model._meta.verbose_name,
|
|
130
132
|
"verbose_name_plural": self.queryset.model._meta.verbose_name_plural,
|
|
133
|
+
"created_by": created_by,
|
|
134
|
+
"last_updated_by": last_updated_by,
|
|
131
135
|
**self.get_extra_context(request, instance),
|
|
132
136
|
},
|
|
133
137
|
)
|
|
@@ -153,7 +157,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|
|
153
157
|
template_name = "generic/object_list.html"
|
|
154
158
|
action_buttons = ("add", "import", "export")
|
|
155
159
|
non_filter_params = (
|
|
156
|
-
"export", # trigger for CSV/export-template/YAML export
|
|
160
|
+
"export", # trigger for CSV/export-template/YAML export # 3.0 TODO: remove, irrelevant after #4746
|
|
157
161
|
"page", # used by django-tables2.RequestConfig
|
|
158
162
|
"per_page", # used by get_paginate_count
|
|
159
163
|
"sort", # table sorting
|
|
@@ -167,7 +171,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|
|
167
171
|
def get_required_permission(self):
|
|
168
172
|
return get_permission_for_model(self.queryset.model, "view")
|
|
169
173
|
|
|
170
|
-
# TODO: remove
|
|
174
|
+
# 3.0 TODO: remove, irrelevant after #4746
|
|
171
175
|
def queryset_to_yaml(self):
|
|
172
176
|
"""
|
|
173
177
|
Export the queryset of objects as concatenated YAML documents.
|
|
@@ -209,7 +213,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|
|
209
213
|
if not filterset.is_valid():
|
|
210
214
|
messages.error(
|
|
211
215
|
request,
|
|
212
|
-
|
|
216
|
+
format_html("Invalid filters were specified: {}", filterset.errors),
|
|
213
217
|
)
|
|
214
218
|
self.queryset = self.queryset.none()
|
|
215
219
|
|
|
@@ -230,7 +234,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|
|
230
234
|
filter_form = self.filterset_form(filter_params, label_suffix="")
|
|
231
235
|
|
|
232
236
|
# Check for export template rendering
|
|
233
|
-
if request.GET.get("export"):
|
|
237
|
+
if request.GET.get("export"): # 3.0 TODO: remove, irrelevant after #4746
|
|
234
238
|
et = get_object_or_404(
|
|
235
239
|
ExportTemplate,
|
|
236
240
|
content_type=content_type,
|
|
@@ -245,7 +249,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|
|
245
249
|
)
|
|
246
250
|
|
|
247
251
|
# Check for YAML export support
|
|
248
|
-
elif "export" in request.GET and hasattr(model, "to_yaml"):
|
|
252
|
+
elif "export" in request.GET and hasattr(model, "to_yaml"): # 3.0 TODO: remove, irrelevant after #4746
|
|
249
253
|
response = HttpResponse(self.queryset_to_yaml(), content_type="text/yaml")
|
|
250
254
|
filename = f"{settings.BRANDING_PREPENDED_FILENAME}{self.queryset.model._meta.verbose_name_plural}.yaml"
|
|
251
255
|
response["Content-Disposition"] = f'attachment; filename="{filename}"'
|
|
@@ -397,10 +401,10 @@ class ObjectEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
|
|
397
401
|
msg = f"{verb} {self.queryset.model._meta.verbose_name}"
|
|
398
402
|
logger.info(f"{msg} {obj} (PK: {obj.pk})")
|
|
399
403
|
if hasattr(obj, "get_absolute_url"):
|
|
400
|
-
msg =
|
|
404
|
+
msg = format_html('{} <a href="{}">{}</a>', msg, obj.get_absolute_url(), obj)
|
|
401
405
|
else:
|
|
402
|
-
msg =
|
|
403
|
-
messages.success(request,
|
|
406
|
+
msg = format_html("{} {}", msg, obj)
|
|
407
|
+
messages.success(request, msg)
|
|
404
408
|
|
|
405
409
|
def post(self, request, *args, **kwargs):
|
|
406
410
|
logger = logging.getLogger(__name__ + ".ObjectEditView")
|
|
@@ -752,7 +756,7 @@ class ObjectImportView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
|
|
752
756
|
logger.info(f"Import object {obj} (PK: {obj.pk})")
|
|
753
757
|
messages.success(
|
|
754
758
|
request,
|
|
755
|
-
|
|
759
|
+
format_html('Imported object: <a href="{}">{}</a>', obj.get_absolute_url(), obj),
|
|
756
760
|
)
|
|
757
761
|
|
|
758
762
|
if "_addanother" in request.POST:
|
nautobot/core/views/mixins.py
CHANGED
|
@@ -19,8 +19,7 @@ from django.template.loader import select_template, TemplateDoesNotExist
|
|
|
19
19
|
from django.urls import reverse
|
|
20
20
|
from django.urls.exceptions import NoReverseMatch
|
|
21
21
|
from django.utils.http import is_safe_url
|
|
22
|
-
from django.utils.html import
|
|
23
|
-
from django.utils.safestring import mark_safe
|
|
22
|
+
from django.utils.html import format_html
|
|
24
23
|
from django.views.generic.edit import FormView
|
|
25
24
|
|
|
26
25
|
from rest_framework import mixins, exceptions
|
|
@@ -605,7 +604,7 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
|
|
|
605
604
|
filterset_class = None
|
|
606
605
|
filterset_form_class = None
|
|
607
606
|
non_filter_params = (
|
|
608
|
-
"export", # trigger for CSV/export-template/YAML export
|
|
607
|
+
"export", # trigger for CSV/export-template/YAML export # 3.0 TODO: remove, irrelevant after #4746
|
|
609
608
|
"page", # used by django-tables2.RequestConfig
|
|
610
609
|
"per_page", # used by get_paginate_count
|
|
611
610
|
"sort", # table sorting
|
|
@@ -622,11 +621,12 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
|
|
|
622
621
|
if not self.filterset.is_valid():
|
|
623
622
|
messages.error(
|
|
624
623
|
self.request,
|
|
625
|
-
|
|
624
|
+
format_html("Invalid filters were specified: {}", self.filterset.errors),
|
|
626
625
|
)
|
|
627
626
|
queryset = queryset.none()
|
|
628
627
|
return queryset
|
|
629
628
|
|
|
629
|
+
# 3.0 TODO: remove, irrelevant after #4746
|
|
630
630
|
def check_for_export(self, request, model, content_type):
|
|
631
631
|
# Check for export template rendering
|
|
632
632
|
queryset = self.filter_queryset(self.get_queryset())
|
|
@@ -653,6 +653,7 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
|
|
|
653
653
|
|
|
654
654
|
return None
|
|
655
655
|
|
|
656
|
+
# 3.0 TODO: remove, irrelevant after #4746
|
|
656
657
|
def queryset_to_yaml(self):
|
|
657
658
|
"""
|
|
658
659
|
Export the queryset of objects as concatenated YAML documents.
|
|
@@ -667,7 +668,7 @@ class ObjectListViewMixin(NautobotViewSetMixin, mixins.ListModelMixin):
|
|
|
667
668
|
List the model instances.
|
|
668
669
|
"""
|
|
669
670
|
context = {"use_new_ui": True}
|
|
670
|
-
if "export" in request.GET:
|
|
671
|
+
if "export" in request.GET: # 3.0 TODO: remove, irrelevant after #4746
|
|
671
672
|
queryset = self.get_queryset()
|
|
672
673
|
model = queryset.model
|
|
673
674
|
content_type = ContentType.objects.get_for_model(model)
|
|
@@ -748,10 +749,10 @@ class ObjectEditViewMixin(NautobotViewSetMixin, mixins.CreateModelMixin, mixins.
|
|
|
748
749
|
msg = f'{"Created" if object_created else "Modified"} {queryset.model._meta.verbose_name}'
|
|
749
750
|
self.logger.info(f"{msg} {obj} (PK: {obj.pk})")
|
|
750
751
|
if hasattr(obj, "get_absolute_url"):
|
|
751
|
-
msg =
|
|
752
|
+
msg = format_html('{} <a href="{}">{}</a>', msg, obj.get_absolute_url(), obj)
|
|
752
753
|
else:
|
|
753
|
-
msg =
|
|
754
|
-
messages.success(request,
|
|
754
|
+
msg = format_html("{} {}", msg, obj)
|
|
755
|
+
messages.success(request, msg)
|
|
755
756
|
if "_addanother" in request.POST:
|
|
756
757
|
# If the object has clone_fields, pre-populate a new instance of the form
|
|
757
758
|
if hasattr(obj, "clone_fields"):
|
nautobot/core/views/renderers.py
CHANGED
|
@@ -14,6 +14,7 @@ from nautobot.core.forms import (
|
|
|
14
14
|
from nautobot.core.forms.forms import DynamicFilterFormSet
|
|
15
15
|
from nautobot.core.templatetags.helpers import bettertitle, validated_viewname
|
|
16
16
|
from nautobot.core.utils.config import get_settings_or_config
|
|
17
|
+
from nautobot.core.utils.lookup import get_created_and_last_updated_usernames_for_model
|
|
17
18
|
from nautobot.core.utils.permissions import get_permission_for_model
|
|
18
19
|
from nautobot.core.utils.requests import (
|
|
19
20
|
convert_querydict_to_factory_formset_acceptable_querydict,
|
|
@@ -229,6 +230,10 @@ class NautobotHTMLRenderer(renderers.BrowsableAPIRenderer):
|
|
|
229
230
|
"verbose_name_plural": queryset.model._meta.verbose_name_plural,
|
|
230
231
|
}
|
|
231
232
|
if view.action == "retrieve":
|
|
233
|
+
created_by, last_updated_by = get_created_and_last_updated_usernames_for_model(instance)
|
|
234
|
+
|
|
235
|
+
context["created_by"] = created_by
|
|
236
|
+
context["last_updated_by"] = last_updated_by
|
|
232
237
|
context.update(view.get_extra_context(request, instance))
|
|
233
238
|
else:
|
|
234
239
|
if view.action == "list":
|