nautobot 2.4.5__py3-none-any.whl → 2.4.7__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/apps/forms.py +2 -0
- nautobot/circuits/templates/circuits/providernetwork.html +1 -1
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +2 -55
- nautobot/circuits/views.py +20 -23
- nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +2 -40
- nautobot/cloud/views.py +12 -0
- nautobot/core/api/mixins.py +10 -0
- nautobot/core/api/urls.py +2 -2
- nautobot/core/api/views.py +39 -1
- nautobot/core/celery/encoders.py +2 -2
- nautobot/core/forms/__init__.py +2 -0
- nautobot/core/forms/fields.py +23 -7
- nautobot/core/forms/utils.py +1 -0
- nautobot/core/forms/widgets.py +18 -0
- nautobot/core/jobs/bulk_actions.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +1 -1
- nautobot/core/models/name_color_content_types.py +9 -0
- nautobot/core/models/validators.py +7 -0
- nautobot/core/settings.py +0 -14
- nautobot/core/settings.yaml +0 -28
- nautobot/core/tables.py +6 -1
- nautobot/core/templates/generic/object_retrieve.html +1 -1
- nautobot/core/templates/widgets/sluginput.html +5 -1
- nautobot/core/templatetags/helpers.py +15 -1
- nautobot/core/testing/api.py +18 -0
- nautobot/core/testing/integration.py +6 -2
- nautobot/core/tests/nautobot_config.py +0 -2
- nautobot/core/tests/runner.py +17 -140
- nautobot/core/tests/test_api.py +4 -4
- nautobot/core/tests/test_authentication.py +83 -4
- nautobot/core/tests/test_forms.py +11 -8
- nautobot/core/tests/test_graphql.py +9 -0
- nautobot/core/tests/test_jobs.py +7 -0
- nautobot/core/ui/object_detail.py +47 -3
- nautobot/core/utils/lookup.py +2 -2
- nautobot/dcim/factory.py +2 -0
- nautobot/dcim/filters/__init__.py +5 -0
- nautobot/dcim/forms.py +27 -1
- nautobot/dcim/migrations/0068_alter_softwareimagefile_download_url.py +19 -0
- nautobot/dcim/migrations/0069_softwareimagefile_external_integration.py +25 -0
- nautobot/dcim/models/devices.py +9 -2
- nautobot/dcim/models/locations.py +9 -0
- nautobot/dcim/tables/devices.py +1 -0
- nautobot/dcim/templates/dcim/device_list.html +1 -1
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/manufacturer.html +1 -63
- nautobot/dcim/templates/dcim/module_list.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +4 -0
- nautobot/dcim/tests/integration/test_module_bay_position.py +125 -0
- nautobot/dcim/tests/test_api.py +74 -31
- nautobot/dcim/tests/test_filters.py +2 -0
- nautobot/dcim/tests/test_models.py +78 -0
- nautobot/dcim/tests/test_views.py +7 -1
- nautobot/dcim/urls.py +1 -45
- nautobot/dcim/views.py +35 -66
- nautobot/extras/choices.py +4 -0
- nautobot/extras/filters/__init__.py +6 -0
- nautobot/extras/forms/forms.py +83 -11
- nautobot/extras/models/customfields.py +10 -9
- nautobot/extras/plugins/marketplace_manifest.yml +18 -0
- nautobot/extras/signals.py +43 -4
- nautobot/extras/tables.py +4 -5
- nautobot/extras/tasks.py +4 -2
- nautobot/extras/templates/extras/contact_retrieve.html +1 -58
- nautobot/extras/templates/extras/exporttemplate.html +1 -53
- nautobot/extras/templates/extras/inc/panel_changelog.html +1 -1
- nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
- nautobot/extras/templates/extras/status.html +1 -37
- nautobot/extras/templates/extras/team_retrieve.html +1 -58
- nautobot/extras/tests/integration/test_notes.py +1 -1
- nautobot/extras/tests/test_api.py +22 -7
- nautobot/extras/tests/test_changelog.py +4 -4
- nautobot/extras/tests/test_customfields.py +27 -0
- nautobot/extras/tests/test_plugins.py +19 -13
- nautobot/extras/tests/test_relationships.py +9 -0
- nautobot/extras/tests/test_tags.py +2 -2
- nautobot/extras/tests/test_views.py +37 -6
- nautobot/extras/urls.py +3 -100
- nautobot/extras/views.py +111 -133
- nautobot/ipam/tables.py +7 -2
- nautobot/ipam/templates/ipam/namespace_retrieve.html +0 -41
- nautobot/ipam/templates/ipam/service.html +2 -46
- nautobot/ipam/templates/ipam/service_edit.html +1 -17
- nautobot/ipam/templates/ipam/service_retrieve.html +7 -0
- nautobot/ipam/tests/migration/__init__.py +0 -0
- nautobot/ipam/tests/migration/test_migrations.py +510 -0
- nautobot/ipam/tests/test_api.py +66 -36
- nautobot/ipam/tests/test_filters.py +0 -10
- nautobot/ipam/tests/test_views.py +44 -2
- nautobot/ipam/urls.py +2 -47
- nautobot/ipam/utils/migrations.py +185 -152
- nautobot/ipam/utils/testing.py +177 -0
- nautobot/ipam/views.py +95 -157
- nautobot/project-static/css/base.css +5 -0
- nautobot/project-static/docs/404.html +0 -2
- nautobot/project-static/docs/apps/index.html +0 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +62 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +47 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +18 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +70 -5
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +0 -2
- nautobot/project-static/docs/development/apps/api/configuration-view.html +0 -2
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/global-search.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/graphql.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +0 -2
- nautobot/project-static/docs/development/apps/api/prometheus.html +0 -2
- nautobot/project-static/docs/development/apps/api/setup.html +0 -2
- nautobot/project-static/docs/development/apps/api/testing.html +0 -89
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/notes.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/urls.html +0 -2
- nautobot/project-static/docs/development/apps/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/code-updates.html +0 -2
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +1 -3
- nautobot/project-static/docs/development/apps/migration/from-v1.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +0 -2
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +0 -2
- nautobot/project-static/docs/development/core/application-registry.html +0 -2
- nautobot/project-static/docs/development/core/best-practices.html +3 -5
- nautobot/project-static/docs/development/core/bootstrap-ui.html +0 -2
- nautobot/project-static/docs/development/core/caching.html +0 -2
- nautobot/project-static/docs/development/core/controllers.html +0 -2
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +0 -2
- nautobot/project-static/docs/development/core/generic-views.html +0 -2
- nautobot/project-static/docs/development/core/getting-started.html +78 -109
- nautobot/project-static/docs/development/core/homepage.html +0 -2
- nautobot/project-static/docs/development/core/index.html +0 -2
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +0 -2
- nautobot/project-static/docs/development/core/model-checklist.html +0 -2
- nautobot/project-static/docs/development/core/model-features.html +0 -2
- nautobot/project-static/docs/development/core/natural-keys.html +0 -2
- nautobot/project-static/docs/development/core/navigation-menu.html +0 -2
- nautobot/project-static/docs/development/core/release-checklist.html +1 -3
- nautobot/project-static/docs/development/core/role-internals.html +0 -2
- nautobot/project-static/docs/development/core/settings.html +0 -2
- nautobot/project-static/docs/development/core/style-guide.html +1 -3
- nautobot/project-static/docs/development/core/templates.html +0 -2
- nautobot/project-static/docs/development/core/testing.html +24 -200
- nautobot/project-static/docs/development/core/ui-component-framework.html +0 -2
- nautobot/project-static/docs/development/core/user-preferences.html +0 -2
- nautobot/project-static/docs/development/index.html +0 -2
- nautobot/project-static/docs/development/jobs/index.html +0 -2
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +0 -2
- nautobot/project-static/docs/index.html +0 -2
- nautobot/project-static/docs/media/user-guide/administration/getting-started/nautobot-cloud.png +0 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +1 -3
- nautobot/project-static/docs/overview/design_philosophy.html +0 -2
- nautobot/project-static/docs/release-notes/index.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.4.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.5.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.6.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.4.html +364 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +290 -290
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +2 -50
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +71 -2
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +3 -3
- nautobot/project-static/docs/user-guide/administration/installation/index.html +257 -18
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/notices.html +0 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +1 -3
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -13
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +8 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +1 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +40 -27
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +77 -7
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +0 -3
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -2
- nautobot/project-static/docs/user-guide/index.html +89 -4
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +207 -124
- nautobot/project-static/js/forms.js +88 -37
- nautobot/project-static/js/homepage_layout.js +12 -3
- nautobot/virtualization/forms.py +20 -0
- nautobot/virtualization/templates/virtualization/clustergroup.html +1 -39
- nautobot/virtualization/templates/virtualization/clustertype.html +1 -0
- nautobot/virtualization/tests/test_api.py +14 -3
- nautobot/virtualization/tests/test_views.py +10 -2
- nautobot/virtualization/urls.py +10 -93
- nautobot/virtualization/views.py +33 -72
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/METADATA +6 -5
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/RECORD +407 -402
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/WHEEL +1 -1
- nautobot/core/tests/performance_baselines.yml +0 -8900
- nautobot/dcim/templates/dcim/modulebay_create.html +0 -39
- nautobot/ipam/tests/test_migrations.py +0 -462
- /nautobot/ipam/templates/ipam/{namespace_ipaddresses.html → namespace_ip_addresses.html} +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/NOTICE +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/entry_points.txt +0 -0
|
@@ -1,38 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block content_left_page %}
|
|
5
|
-
<div class="panel panel-default">
|
|
6
|
-
<div class="panel-heading">
|
|
7
|
-
<strong>Status</strong>
|
|
8
|
-
</div>
|
|
9
|
-
<table class="table table-hover panel-body attr-table">
|
|
10
|
-
<tr>
|
|
11
|
-
<td>Name</td>
|
|
12
|
-
<td>
|
|
13
|
-
{{ object.name }}
|
|
14
|
-
</td>
|
|
15
|
-
</tr>
|
|
16
|
-
<tr>
|
|
17
|
-
<td>Content Type(s)</td>
|
|
18
|
-
<td>
|
|
19
|
-
{% for ct in content_types %}
|
|
20
|
-
{{ ct }}<br>
|
|
21
|
-
{% endfor %}
|
|
22
|
-
</td>
|
|
23
|
-
</tr>
|
|
24
|
-
<tr>
|
|
25
|
-
<td>Color</td>
|
|
26
|
-
<td>
|
|
27
|
-
<span class="label color-block" style="background-color: #{{ object.color }}"> </span>
|
|
28
|
-
</td>
|
|
29
|
-
</tr>
|
|
30
|
-
<tr>
|
|
31
|
-
<td>Description</td>
|
|
32
|
-
<td>
|
|
33
|
-
{{ object.description|placeholder }}
|
|
34
|
-
</td>
|
|
35
|
-
</tr>
|
|
36
|
-
</table>
|
|
37
|
-
</div>
|
|
38
|
-
{% endblock content_left_page %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -1,59 +1,2 @@
|
|
|
1
1
|
{% extends 'generic/object_retrieve.html' %}
|
|
2
|
-
{%
|
|
3
|
-
|
|
4
|
-
{% block content_left_page %}
|
|
5
|
-
<div class="panel panel-default">
|
|
6
|
-
<div class="panel-heading">
|
|
7
|
-
<strong>Team</strong>
|
|
8
|
-
</div>
|
|
9
|
-
<table class="table table-hover panel-body attr-table">
|
|
10
|
-
<tr>
|
|
11
|
-
<td>Name</td>
|
|
12
|
-
<td>{{ object.name }}</td>
|
|
13
|
-
</tr>
|
|
14
|
-
<tr>
|
|
15
|
-
<td>Phone</td>
|
|
16
|
-
<td>{{ object.phone|hyperlinked_phone_number }}</td>
|
|
17
|
-
</tr>
|
|
18
|
-
<tr>
|
|
19
|
-
<td>E-mail</td>
|
|
20
|
-
<td>{{ object.email|hyperlinked_email }}</td>
|
|
21
|
-
</tr>
|
|
22
|
-
<tr>
|
|
23
|
-
<td>Address</td>
|
|
24
|
-
<td>
|
|
25
|
-
{% if object.address %}
|
|
26
|
-
<div class="pull-right noprint">
|
|
27
|
-
<a href="https://maps.google.com/?q={{ object.address|urlencode }}" target="_blank" class="btn btn-primary btn-xs">
|
|
28
|
-
<i class="mdi mdi-map-marker"></i> Map it
|
|
29
|
-
</a>
|
|
30
|
-
</div>
|
|
31
|
-
<span>{{ object.address|linebreaksbr }}</span>
|
|
32
|
-
{% else %}
|
|
33
|
-
<span class="text-muted">—</span>
|
|
34
|
-
{% endif %}
|
|
35
|
-
</td>
|
|
36
|
-
</tr>
|
|
37
|
-
</table>
|
|
38
|
-
</div>
|
|
39
|
-
<div class="panel panel-default">
|
|
40
|
-
<div class="panel-heading">
|
|
41
|
-
<strong>Comments</strong>
|
|
42
|
-
</div>
|
|
43
|
-
<div class="panel-body rendered-markdown">
|
|
44
|
-
{% if object.comments %}
|
|
45
|
-
{{ object.comments|render_markdown }}
|
|
46
|
-
{% else %}
|
|
47
|
-
<span class="text-muted">None</span>
|
|
48
|
-
{% endif %}
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
{% endblock %}
|
|
52
|
-
|
|
53
|
-
{% block content_right_page %}
|
|
54
|
-
{% include 'panel_table.html' with table=contacts_table heading='Assigned Contacts' %}
|
|
55
|
-
{% endblock %}
|
|
56
|
-
|
|
57
|
-
{% block content_full_width_page %}
|
|
58
|
-
{% include 'panel_table.html' with table=contact_associations_table heading='Contact For' %}
|
|
59
|
-
{% endblock %}
|
|
2
|
+
{% comment %}3.0 TODO: remove this template, which only exists for backward compatibility with 2.4 and earlier{% endcomment %}
|
|
@@ -292,7 +292,7 @@ class ConfigContextTest(APIViewTestCases.APIViewTestCase):
|
|
|
292
292
|
schema = ConfigContextSchema.objects.create(
|
|
293
293
|
name="Schema 1", data_schema={"type": "object", "properties": {"foo": {"type": "string"}}}
|
|
294
294
|
)
|
|
295
|
-
self.add_permissions("extras.add_configcontext")
|
|
295
|
+
self.add_permissions("extras.add_configcontext", "extras.view_configcontextschema")
|
|
296
296
|
|
|
297
297
|
data = {
|
|
298
298
|
"name": "Config Context with schema",
|
|
@@ -2248,7 +2248,7 @@ class JobHookTest(APIViewTestCases.APIViewTestCase):
|
|
|
2248
2248
|
"type_delete": True,
|
|
2249
2249
|
}
|
|
2250
2250
|
|
|
2251
|
-
self.add_permissions("extras.add_jobhook")
|
|
2251
|
+
self.add_permissions("extras.add_jobhook", "extras.view_job")
|
|
2252
2252
|
response = self.client.post(self._get_list_url(), data, format="json", **self.header)
|
|
2253
2253
|
self.assertContains(
|
|
2254
2254
|
response,
|
|
@@ -2264,7 +2264,7 @@ class JobHookTest(APIViewTestCases.APIViewTestCase):
|
|
|
2264
2264
|
"type_delete": True,
|
|
2265
2265
|
}
|
|
2266
2266
|
|
|
2267
|
-
self.add_permissions("extras.change_jobhook")
|
|
2267
|
+
self.add_permissions("extras.change_jobhook", "extras.view_job")
|
|
2268
2268
|
job_hook2 = JobHook.objects.get(name="JobHook2")
|
|
2269
2269
|
response = self.client.patch(self._get_detail_url(job_hook2), data, format="json", **self.header)
|
|
2270
2270
|
self.assertContains(
|
|
@@ -2553,7 +2553,7 @@ class UserSavedViewAssociationTest(APIViewTestCases.APIViewTestCase):
|
|
|
2553
2553
|
"saved_view": saved_view.pk,
|
|
2554
2554
|
"view_name": duplicate_view_name,
|
|
2555
2555
|
}
|
|
2556
|
-
self.add_permissions("extras.add_usersavedviewassociation")
|
|
2556
|
+
self.add_permissions("extras.add_usersavedviewassociation", "users.view_user", "extras.view_savedview")
|
|
2557
2557
|
response = self.client.post(
|
|
2558
2558
|
self._get_list_url(), duplicate_user_to_savedview_create_data, format="json", **self.header
|
|
2559
2559
|
)
|
|
@@ -3240,7 +3240,15 @@ class RelationshipTest(APIViewTestCases.APIViewTestCase, RequiredRelationshipTes
|
|
|
3240
3240
|
location=existing_location_2,
|
|
3241
3241
|
)
|
|
3242
3242
|
|
|
3243
|
-
self.add_permissions(
|
|
3243
|
+
self.add_permissions(
|
|
3244
|
+
"dcim.view_location",
|
|
3245
|
+
"dcim.view_locationtype",
|
|
3246
|
+
"dcim.view_device",
|
|
3247
|
+
"dcim.add_location",
|
|
3248
|
+
"extras.view_relationship",
|
|
3249
|
+
"extras.add_relationshipassociation",
|
|
3250
|
+
"extras.view_status",
|
|
3251
|
+
)
|
|
3244
3252
|
response = self.client.post(
|
|
3245
3253
|
reverse("dcim-api:location-list"),
|
|
3246
3254
|
data={
|
|
@@ -3564,7 +3572,9 @@ class RelationshipAssociationTest(APIViewTestCases.APIViewTestCase):
|
|
|
3564
3572
|
),
|
|
3565
3573
|
]
|
|
3566
3574
|
|
|
3567
|
-
self.add_permissions(
|
|
3575
|
+
self.add_permissions(
|
|
3576
|
+
"extras.add_relationshipassociation", "dcim.view_device", "dcim.view_location", "extras.view_relationship"
|
|
3577
|
+
)
|
|
3568
3578
|
|
|
3569
3579
|
for side, field_error_name, data in associations:
|
|
3570
3580
|
response = self.client.post(self._get_list_url(), data, format="json", **self.header)
|
|
@@ -3585,7 +3595,9 @@ class RelationshipAssociationTest(APIViewTestCases.APIViewTestCase):
|
|
|
3585
3595
|
"destination_id": self.devices[2].pk,
|
|
3586
3596
|
}
|
|
3587
3597
|
|
|
3588
|
-
self.add_permissions(
|
|
3598
|
+
self.add_permissions(
|
|
3599
|
+
"extras.add_relationshipassociation", "extras.view_relationship", "dcim.view_device", "dcim.view_location"
|
|
3600
|
+
)
|
|
3589
3601
|
|
|
3590
3602
|
response = self.client.post(self._get_list_url(), data, format="json", **self.header)
|
|
3591
3603
|
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
|
|
@@ -3636,8 +3648,11 @@ class RelationshipAssociationTest(APIViewTestCases.APIViewTestCase):
|
|
|
3636
3648
|
Check that relationship-associations can be updated via the 'relationships' field.
|
|
3637
3649
|
"""
|
|
3638
3650
|
self.add_permissions(
|
|
3651
|
+
"dcim.view_device",
|
|
3639
3652
|
"dcim.view_location",
|
|
3640
3653
|
"dcim.change_location",
|
|
3654
|
+
"extras.view_relationship",
|
|
3655
|
+
"extras.view_relationshipassociation",
|
|
3641
3656
|
"extras.add_relationshipassociation",
|
|
3642
3657
|
"extras.delete_relationshipassociation",
|
|
3643
3658
|
)
|
|
@@ -277,7 +277,7 @@ class ChangeLogAPITest(APITestCase):
|
|
|
277
277
|
],
|
|
278
278
|
}
|
|
279
279
|
url = reverse("dcim-api:location-list")
|
|
280
|
-
self.add_permissions("dcim.add_location", "extras.view_status")
|
|
280
|
+
self.add_permissions("dcim.add_location", "dcim.view_locationtype", "extras.view_tag", "extras.view_status")
|
|
281
281
|
|
|
282
282
|
response = self.client.post(url, data, format="json", **self.header)
|
|
283
283
|
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
|
@@ -310,7 +310,7 @@ class ChangeLogAPITest(APITestCase):
|
|
|
310
310
|
},
|
|
311
311
|
"tags": [{"name": self.tags[2].name}],
|
|
312
312
|
}
|
|
313
|
-
self.add_permissions("dcim.change_location", "extras.view_status")
|
|
313
|
+
self.add_permissions("dcim.change_location", "extras.view_status", "dcim.view_locationtype", "extras.view_tag")
|
|
314
314
|
url = reverse("dcim-api:location-detail", kwargs={"pk": location.pk})
|
|
315
315
|
|
|
316
316
|
response = self.client.put(url, data, format="json", **self.header)
|
|
@@ -457,7 +457,7 @@ class ChangeLogAPITest(APITestCase):
|
|
|
457
457
|
"status": self.statuses[0].pk,
|
|
458
458
|
"location_type": location_type.pk,
|
|
459
459
|
}
|
|
460
|
-
self.add_permissions("dcim.add_location")
|
|
460
|
+
self.add_permissions("dcim.add_location", "dcim.view_locationtype", "extras.view_status")
|
|
461
461
|
url = reverse("dcim-api:location-list")
|
|
462
462
|
|
|
463
463
|
response = self.client.post(url, location_payload, format="json", **self.header)
|
|
@@ -492,7 +492,7 @@ class ChangeLogAPITest(APITestCase):
|
|
|
492
492
|
)
|
|
493
493
|
|
|
494
494
|
payload = {"tagged_vlans": [str(tagged_vlan.pk)], "description": "test vm interface m2m change"}
|
|
495
|
-
self.add_permissions("virtualization.change_vminterface", "ipam.change_vlan")
|
|
495
|
+
self.add_permissions("virtualization.change_vminterface", "ipam.change_vlan", "ipam.view_vlan")
|
|
496
496
|
url = reverse("virtualization-api:vminterface-detail", kwargs={"pk": vm_interface.pk})
|
|
497
497
|
response = self.client.patch(url, payload, format="json", **self.header)
|
|
498
498
|
vm_interface.refresh_from_db()
|
|
@@ -472,6 +472,9 @@ class CustomFieldDataAPITest(APITestCase):
|
|
|
472
472
|
"dcim.add_location",
|
|
473
473
|
"dcim.change_location",
|
|
474
474
|
"dcim.view_location",
|
|
475
|
+
"dcim.view_locationtype",
|
|
476
|
+
"extras.view_status",
|
|
477
|
+
"extras.view_customfield",
|
|
475
478
|
)
|
|
476
479
|
|
|
477
480
|
def setUp(self):
|
|
@@ -2080,6 +2083,30 @@ class CustomFieldBackgroundTasks(TransactionTestCase):
|
|
|
2080
2083
|
self.assertEqual(oc_list[0].change_context_detail, "delete custom field data")
|
|
2081
2084
|
self.assertEqual(oc_list[0].user, self.user)
|
|
2082
2085
|
|
|
2086
|
+
def test_clear_custom_field_data_task(self):
|
|
2087
|
+
obj_type = ContentType.objects.get_for_model(Location)
|
|
2088
|
+
cf_1 = CustomField.objects.create(label="CF1", type=CustomFieldTypeChoices.TYPE_TEXT)
|
|
2089
|
+
cf_1.content_types.set([obj_type])
|
|
2090
|
+
location_type = LocationType.objects.create(name="Root Type 2")
|
|
2091
|
+
location_status = Status.objects.get_for_model(Location).first()
|
|
2092
|
+
location = Location.objects.create(
|
|
2093
|
+
name="Location 1",
|
|
2094
|
+
location_type=location_type,
|
|
2095
|
+
status=location_status,
|
|
2096
|
+
_custom_field_data={"cf1": "foo"},
|
|
2097
|
+
)
|
|
2098
|
+
|
|
2099
|
+
with web_request_context(self.user):
|
|
2100
|
+
cf_1.content_types.clear()
|
|
2101
|
+
location.refresh_from_db()
|
|
2102
|
+
self.assertNotIn("cf1", location.cf)
|
|
2103
|
+
|
|
2104
|
+
oc_list = get_changes_for_model(location)
|
|
2105
|
+
self.assertEqual(len(oc_list), 1)
|
|
2106
|
+
self.assertEqual(oc_list[0].changed_object, location)
|
|
2107
|
+
self.assertEqual(oc_list[0].change_context_detail, "delete custom field data from existing content types")
|
|
2108
|
+
self.assertEqual(oc_list[0].user, self.user)
|
|
2109
|
+
|
|
2083
2110
|
def test_update_custom_field_choice_data_task(self):
|
|
2084
2111
|
obj_type = ContentType.objects.get_for_model(Location)
|
|
2085
2112
|
cf = CustomField(
|
|
@@ -486,7 +486,7 @@ class TestUserContextCustomValidator(CustomValidator):
|
|
|
486
486
|
"""
|
|
487
487
|
Used to validate that the correct user context is available in the custom validator.
|
|
488
488
|
"""
|
|
489
|
-
self.validation_error(self.context[
|
|
489
|
+
self.validation_error(f"TestUserContextCustomValidator: user is {self.context['user']}")
|
|
490
490
|
|
|
491
491
|
|
|
492
492
|
class AppCustomValidationTest(TestCase):
|
|
@@ -527,22 +527,28 @@ class AppCustomValidationTest(TestCase):
|
|
|
527
527
|
|
|
528
528
|
def test_custom_validator_non_web_request_uses_anonymous_user(self):
|
|
529
529
|
location_type = LocationType.objects.get(name="Campus")
|
|
530
|
-
registry["plugin_custom_validators"]["dcim.locationtype"]
|
|
530
|
+
before = registry["plugin_custom_validators"]["dcim.locationtype"]
|
|
531
|
+
try:
|
|
532
|
+
registry["plugin_custom_validators"]["dcim.locationtype"] = [TestUserContextCustomValidator]
|
|
531
533
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
534
|
+
with self.assertRaises(ValidationError) as context:
|
|
535
|
+
location_type.clean()
|
|
536
|
+
self.assertEqual(context.exception.message, "TestUserContextCustomValidator: user is AnonymousUser")
|
|
537
|
+
finally:
|
|
538
|
+
registry["plugin_custom_validators"]["dcim.locationtype"] = before
|
|
537
539
|
|
|
538
540
|
def test_custom_validator_web_request_uses_real_user(self):
|
|
539
541
|
location_type = LocationType.objects.get(name="Campus")
|
|
540
|
-
registry["plugin_custom_validators"]["dcim.locationtype"]
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
542
|
+
before = registry["plugin_custom_validators"]["dcim.locationtype"]
|
|
543
|
+
try:
|
|
544
|
+
registry["plugin_custom_validators"]["dcim.locationtype"] = [TestUserContextCustomValidator]
|
|
545
|
+
|
|
546
|
+
with self.assertRaises(ValidationError) as context:
|
|
547
|
+
with web_request_context(user=self.user):
|
|
548
|
+
location_type.clean()
|
|
549
|
+
self.assertEqual(context.exception.message, f"TestUserContextCustomValidator: user is {self.user}")
|
|
550
|
+
finally:
|
|
551
|
+
registry["plugin_custom_validators"]["dcim.locationtype"] = before
|
|
546
552
|
|
|
547
553
|
|
|
548
554
|
class ExampleModelCustomActionViewTest(TestCase):
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import logging
|
|
2
3
|
import uuid
|
|
3
4
|
|
|
4
5
|
from django.contrib.contenttypes.models import ContentType
|
|
6
|
+
from django.core.cache import cache
|
|
5
7
|
from django.core.exceptions import ValidationError
|
|
6
8
|
from django.urls import reverse
|
|
7
9
|
from django.utils.html import format_html
|
|
10
|
+
import redis.exceptions
|
|
8
11
|
|
|
9
12
|
from nautobot.circuits.models import CircuitType
|
|
10
13
|
from nautobot.core.forms import (
|
|
@@ -179,6 +182,12 @@ class RelationshipBaseTest:
|
|
|
179
182
|
),
|
|
180
183
|
]
|
|
181
184
|
|
|
185
|
+
def tearDown(self):
|
|
186
|
+
"""Ensure that relationship caches are cleared to avoid leakage into other tests."""
|
|
187
|
+
with contextlib.suppress(redis.exceptions.ConnectionError):
|
|
188
|
+
cache.delete_pattern(f"{Relationship.objects.get_for_model_source.cache_key_prefix}.*")
|
|
189
|
+
cache.delete_pattern(f"{Relationship.objects.get_for_model_destination.cache_key_prefix}.*")
|
|
190
|
+
|
|
182
191
|
|
|
183
192
|
class RelationshipTest(RelationshipBaseTest, ModelTestCases.BaseModelTestCase):
|
|
184
193
|
model = Relationship
|
|
@@ -46,7 +46,7 @@ class TaggedItemTest(APITestCase):
|
|
|
46
46
|
"location_type": self.location_type.pk,
|
|
47
47
|
}
|
|
48
48
|
url = reverse("dcim-api:location-list")
|
|
49
|
-
self.add_permissions("dcim.add_location")
|
|
49
|
+
self.add_permissions("dcim.add_location", "dcim.view_locationtype", "extras.view_tag", "extras.view_status")
|
|
50
50
|
|
|
51
51
|
response = self.client.post(url, data, format="json", **self.header)
|
|
52
52
|
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
|
@@ -67,7 +67,7 @@ class TaggedItemTest(APITestCase):
|
|
|
67
67
|
{"name": self.tags[3].name},
|
|
68
68
|
]
|
|
69
69
|
}
|
|
70
|
-
self.add_permissions("dcim.change_location")
|
|
70
|
+
self.add_permissions("dcim.change_location", "extras.view_tag")
|
|
71
71
|
url = reverse("dcim-api:location-detail", kwargs={"pk": location.pk})
|
|
72
72
|
|
|
73
73
|
response = self.client.patch(url, data, format="json", **self.header)
|
|
@@ -1069,12 +1069,14 @@ class ExportTemplateTestCase(
|
|
|
1069
1069
|
ViewTestCases.GetObjectViewTestCase,
|
|
1070
1070
|
ViewTestCases.GetObjectChangelogViewTestCase,
|
|
1071
1071
|
ViewTestCases.ListObjectsViewTestCase,
|
|
1072
|
+
ViewTestCases.BulkEditObjectsViewTestCase,
|
|
1072
1073
|
):
|
|
1073
1074
|
model = ExportTemplate
|
|
1074
1075
|
|
|
1075
1076
|
@classmethod
|
|
1076
1077
|
def setUpTestData(cls):
|
|
1077
1078
|
obj_type = ContentType.objects.get_for_model(Location)
|
|
1079
|
+
obj_type_1 = ContentType.objects.get_for_model(Interface)
|
|
1078
1080
|
|
|
1079
1081
|
templates = (
|
|
1080
1082
|
ExportTemplate(
|
|
@@ -1102,6 +1104,12 @@ class ExportTemplateTestCase(
|
|
|
1102
1104
|
"content_type": obj_type.pk,
|
|
1103
1105
|
"template_code": "template-4 test4",
|
|
1104
1106
|
}
|
|
1107
|
+
cls.bulk_edit_data = {
|
|
1108
|
+
"content_type": obj_type_1.pk,
|
|
1109
|
+
"description": "Updated template description",
|
|
1110
|
+
"mime_type": "application/json",
|
|
1111
|
+
"file_extension": "json",
|
|
1112
|
+
}
|
|
1105
1113
|
|
|
1106
1114
|
|
|
1107
1115
|
class ExternalIntegrationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
@@ -3376,6 +3384,7 @@ class RelationshipTestCase(
|
|
|
3376
3384
|
ViewTestCases.GetObjectChangelogViewTestCase,
|
|
3377
3385
|
ViewTestCases.ListObjectsViewTestCase,
|
|
3378
3386
|
RequiredRelationshipTestMixin,
|
|
3387
|
+
ViewTestCases.BulkEditObjectsViewTestCase,
|
|
3379
3388
|
):
|
|
3380
3389
|
model = Relationship
|
|
3381
3390
|
slug_source = "label"
|
|
@@ -3422,6 +3431,19 @@ class RelationshipTestCase(
|
|
|
3422
3431
|
"destination_hidden": True,
|
|
3423
3432
|
"destination_filter": None,
|
|
3424
3433
|
}
|
|
3434
|
+
cls.bulk_edit_data = {
|
|
3435
|
+
"description": "This is a relationship between VLANs and Interfaces.",
|
|
3436
|
+
"type": "many-to-many",
|
|
3437
|
+
"source_type": vlan_type.pk,
|
|
3438
|
+
"source_label": "Interfaces",
|
|
3439
|
+
"source_hidden": False,
|
|
3440
|
+
"source_filter": '{"status": ["' + status.name + '"]}',
|
|
3441
|
+
"destination_type": interface_type.pk,
|
|
3442
|
+
"destination_label": "VLANs",
|
|
3443
|
+
"destination_hidden": True,
|
|
3444
|
+
"destination_filter": None,
|
|
3445
|
+
"advanced_ui": True,
|
|
3446
|
+
}
|
|
3425
3447
|
|
|
3426
3448
|
cls.slug_test_object = "Primary Interface"
|
|
3427
3449
|
|
|
@@ -3584,23 +3606,28 @@ class StatusTestCase(
|
|
|
3584
3606
|
ViewTestCases.GetObjectViewTestCase,
|
|
3585
3607
|
ViewTestCases.GetObjectChangelogViewTestCase,
|
|
3586
3608
|
ViewTestCases.ListObjectsViewTestCase,
|
|
3609
|
+
ViewTestCases.BulkEditObjectsViewTestCase,
|
|
3587
3610
|
):
|
|
3588
3611
|
model = Status
|
|
3589
3612
|
|
|
3590
3613
|
@classmethod
|
|
3591
3614
|
def setUpTestData(cls):
|
|
3592
3615
|
# Status objects to test.
|
|
3593
|
-
|
|
3616
|
+
device_ct = ContentType.objects.get_for_model(Device)
|
|
3617
|
+
circuit_ct = ContentType.objects.get_for_model(Circuit)
|
|
3618
|
+
interface_ct = ContentType.objects.get_for_model(Interface)
|
|
3594
3619
|
|
|
3595
3620
|
cls.form_data = {
|
|
3596
3621
|
"name": "new_status",
|
|
3597
3622
|
"description": "I am a new status object.",
|
|
3598
3623
|
"color": "ffcc00",
|
|
3599
|
-
"content_types": [
|
|
3624
|
+
"content_types": [device_ct.pk],
|
|
3600
3625
|
}
|
|
3601
3626
|
|
|
3602
3627
|
cls.bulk_edit_data = {
|
|
3603
3628
|
"color": "000000",
|
|
3629
|
+
"add_content_types": [interface_ct.pk, circuit_ct.pk],
|
|
3630
|
+
"remove_content_types": [device_ct.pk],
|
|
3604
3631
|
}
|
|
3605
3632
|
|
|
3606
3633
|
|
|
@@ -3790,25 +3817,29 @@ class WebhookTestCase(
|
|
|
3790
3817
|
}
|
|
3791
3818
|
|
|
3792
3819
|
|
|
3793
|
-
class RoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|
3820
|
+
class RoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTestCases.BulkEditObjectsViewTestCase):
|
|
3794
3821
|
model = Role
|
|
3795
3822
|
|
|
3796
3823
|
@classmethod
|
|
3797
3824
|
def setUpTestData(cls):
|
|
3798
|
-
#
|
|
3799
|
-
|
|
3825
|
+
# Role objects to test.
|
|
3826
|
+
device_ct = ContentType.objects.get_for_model(Device)
|
|
3827
|
+
ipaddress_ct = ContentType.objects.get_for_model(IPAddress)
|
|
3828
|
+
prefix_ct = ContentType.objects.get_for_model(Prefix)
|
|
3800
3829
|
|
|
3801
3830
|
cls.form_data = {
|
|
3802
3831
|
"name": "New Role",
|
|
3803
3832
|
"description": "I am a new role object.",
|
|
3804
3833
|
"color": ColorChoices.COLOR_GREY,
|
|
3805
|
-
"content_types": [
|
|
3834
|
+
"content_types": [device_ct.pk],
|
|
3806
3835
|
}
|
|
3807
3836
|
|
|
3808
3837
|
cls.bulk_edit_data = {
|
|
3809
3838
|
"color": "000000",
|
|
3810
3839
|
"description": "I used to be a new role object.",
|
|
3811
3840
|
"weight": 255,
|
|
3841
|
+
"add_content_types": [ipaddress_ct.pk, prefix_ct.pk],
|
|
3842
|
+
"remove_content_types": [device_ct.pk],
|
|
3812
3843
|
}
|
|
3813
3844
|
|
|
3814
3845
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
nautobot/extras/urls.py
CHANGED
|
@@ -9,7 +9,6 @@ from nautobot.extras.models import (
|
|
|
9
9
|
CustomField,
|
|
10
10
|
CustomLink,
|
|
11
11
|
DynamicGroup,
|
|
12
|
-
ExportTemplate,
|
|
13
12
|
GitRepository,
|
|
14
13
|
GraphQLQuery,
|
|
15
14
|
Job,
|
|
@@ -17,7 +16,6 @@ from nautobot.extras.models import (
|
|
|
17
16
|
Note,
|
|
18
17
|
Relationship,
|
|
19
18
|
SecretsGroup,
|
|
20
|
-
Status,
|
|
21
19
|
Tag,
|
|
22
20
|
Webhook,
|
|
23
21
|
)
|
|
@@ -27,15 +25,18 @@ app_name = "extras"
|
|
|
27
25
|
router = NautobotUIViewSetRouter()
|
|
28
26
|
router.register("contacts", views.ContactUIViewSet)
|
|
29
27
|
router.register("contact-associations", views.ContactAssociationUIViewSet)
|
|
28
|
+
router.register("export-templates", views.ExportTemplateUIViewSet)
|
|
30
29
|
router.register("external-integrations", views.ExternalIntegrationUIViewSet)
|
|
31
30
|
router.register("job-buttons", views.JobButtonUIViewSet)
|
|
32
31
|
router.register("job-queues", views.JobQueueUIViewSet)
|
|
33
32
|
router.register("metadata-types", views.MetadataTypeUIViewSet)
|
|
34
33
|
router.register("object-metadata", views.ObjectMetadataUIViewSet)
|
|
34
|
+
router.register("relationships", views.RelationshipUIViewSet)
|
|
35
35
|
router.register("roles", views.RoleUIViewSet)
|
|
36
36
|
router.register("saved-views", views.SavedViewUIViewSet)
|
|
37
37
|
router.register("secrets", views.SecretUIViewSet)
|
|
38
38
|
router.register("static-group-associations", views.StaticGroupAssociationUIViewSet)
|
|
39
|
+
router.register("statuses", views.StatusUIViewSet)
|
|
39
40
|
router.register("teams", views.TeamUIViewSet)
|
|
40
41
|
|
|
41
42
|
urlpatterns = [
|
|
@@ -268,49 +269,6 @@ urlpatterns = [
|
|
|
268
269
|
name="dynamicgroup_notes",
|
|
269
270
|
kwargs={"model": DynamicGroup},
|
|
270
271
|
),
|
|
271
|
-
# Export Templates
|
|
272
|
-
path(
|
|
273
|
-
"export-templates/",
|
|
274
|
-
views.ExportTemplateListView.as_view(),
|
|
275
|
-
name="exporttemplate_list",
|
|
276
|
-
),
|
|
277
|
-
path(
|
|
278
|
-
"export-templates/add/",
|
|
279
|
-
views.ExportTemplateEditView.as_view(),
|
|
280
|
-
name="exporttemplate_add",
|
|
281
|
-
),
|
|
282
|
-
path(
|
|
283
|
-
"export-templates/delete/",
|
|
284
|
-
views.ExportTemplateBulkDeleteView.as_view(),
|
|
285
|
-
name="exporttemplate_bulk_delete",
|
|
286
|
-
),
|
|
287
|
-
path(
|
|
288
|
-
"export-templates/<uuid:pk>/",
|
|
289
|
-
views.ExportTemplateView.as_view(),
|
|
290
|
-
name="exporttemplate",
|
|
291
|
-
),
|
|
292
|
-
path(
|
|
293
|
-
"export-templates/<uuid:pk>/edit/",
|
|
294
|
-
views.ExportTemplateEditView.as_view(),
|
|
295
|
-
name="exporttemplate_edit",
|
|
296
|
-
),
|
|
297
|
-
path(
|
|
298
|
-
"export-templates/<uuid:pk>/delete/",
|
|
299
|
-
views.ExportTemplateDeleteView.as_view(),
|
|
300
|
-
name="exporttemplate_delete",
|
|
301
|
-
),
|
|
302
|
-
path(
|
|
303
|
-
"export-templates/<uuid:pk>/changelog/",
|
|
304
|
-
views.ObjectChangeLogView.as_view(),
|
|
305
|
-
name="exporttemplate_changelog",
|
|
306
|
-
kwargs={"model": ExportTemplate},
|
|
307
|
-
),
|
|
308
|
-
path(
|
|
309
|
-
"export-templates/<uuid:pk>/notes/",
|
|
310
|
-
views.ObjectNotesView.as_view(),
|
|
311
|
-
name="exporttemplate_notes",
|
|
312
|
-
kwargs={"model": ExportTemplate},
|
|
313
|
-
),
|
|
314
272
|
# Git repositories
|
|
315
273
|
path(
|
|
316
274
|
"git-repositories/",
|
|
@@ -512,32 +470,6 @@ urlpatterns = [
|
|
|
512
470
|
path("notes/<uuid:pk>/edit/", views.NoteEditView.as_view(), name="note_edit"),
|
|
513
471
|
path("notes/<uuid:pk>/delete/", views.NoteDeleteView.as_view(), name="note_delete"),
|
|
514
472
|
# Custom relationships
|
|
515
|
-
path("relationships/", views.RelationshipListView.as_view(), name="relationship_list"),
|
|
516
|
-
path(
|
|
517
|
-
"relationships/add/",
|
|
518
|
-
views.RelationshipEditView.as_view(),
|
|
519
|
-
name="relationship_add",
|
|
520
|
-
),
|
|
521
|
-
path(
|
|
522
|
-
"relationships/delete/",
|
|
523
|
-
views.RelationshipBulkDeleteView.as_view(),
|
|
524
|
-
name="relationship_bulk_delete",
|
|
525
|
-
),
|
|
526
|
-
path(
|
|
527
|
-
"relationships/<uuid:pk>/",
|
|
528
|
-
views.RelationshipView.as_view(),
|
|
529
|
-
name="relationship",
|
|
530
|
-
),
|
|
531
|
-
path(
|
|
532
|
-
"relationships/<uuid:pk>/edit/",
|
|
533
|
-
views.RelationshipEditView.as_view(),
|
|
534
|
-
name="relationship_edit",
|
|
535
|
-
),
|
|
536
|
-
path(
|
|
537
|
-
"relationships/<uuid:pk>/delete/",
|
|
538
|
-
views.RelationshipDeleteView.as_view(),
|
|
539
|
-
name="relationship_delete",
|
|
540
|
-
),
|
|
541
473
|
path(
|
|
542
474
|
"relationships/<uuid:pk>/changelog/",
|
|
543
475
|
views.ObjectChangeLogView.as_view(),
|
|
@@ -589,35 +521,6 @@ urlpatterns = [
|
|
|
589
521
|
name="secretsgroup_notes",
|
|
590
522
|
kwargs={"model": SecretsGroup},
|
|
591
523
|
),
|
|
592
|
-
# Custom statuses
|
|
593
|
-
path("statuses/", views.StatusListView.as_view(), name="status_list"),
|
|
594
|
-
path("statuses/add/", views.StatusEditView.as_view(), name="status_add"),
|
|
595
|
-
path("statuses/edit/", views.StatusBulkEditView.as_view(), name="status_bulk_edit"),
|
|
596
|
-
path(
|
|
597
|
-
"statuses/delete/",
|
|
598
|
-
views.StatusBulkDeleteView.as_view(),
|
|
599
|
-
name="status_bulk_delete",
|
|
600
|
-
),
|
|
601
|
-
path("statuses/import/", views.StatusBulkImportView.as_view(), name="status_import"), # 3.0 TODO: remove, unused
|
|
602
|
-
path("statuses/<uuid:pk>/", views.StatusView.as_view(), name="status"),
|
|
603
|
-
path("statuses/<uuid:pk>/edit/", views.StatusEditView.as_view(), name="status_edit"),
|
|
604
|
-
path(
|
|
605
|
-
"statuses/<uuid:pk>/delete/",
|
|
606
|
-
views.StatusDeleteView.as_view(),
|
|
607
|
-
name="status_delete",
|
|
608
|
-
),
|
|
609
|
-
path(
|
|
610
|
-
"statuses/<uuid:pk>/changelog/",
|
|
611
|
-
views.ObjectChangeLogView.as_view(),
|
|
612
|
-
name="status_changelog",
|
|
613
|
-
kwargs={"model": Status},
|
|
614
|
-
),
|
|
615
|
-
path(
|
|
616
|
-
"statuses/<uuid:pk>/notes/",
|
|
617
|
-
views.ObjectNotesView.as_view(),
|
|
618
|
-
name="status_notes",
|
|
619
|
-
kwargs={"model": Status},
|
|
620
|
-
),
|
|
621
524
|
# Tags
|
|
622
525
|
path("tags/", views.TagListView.as_view(), name="tag_list"),
|
|
623
526
|
path("tags/add/", views.TagEditView.as_view(), name="tag_add"),
|