nautobot 2.3.15b1__py3-none-any.whl → 2.3.16__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/views.py +3 -3
- nautobot/cloud/models.py +1 -1
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/serializers.py +9 -9
- nautobot/core/api/views.py +3 -2
- nautobot/core/apps/__init__.py +5 -2
- nautobot/core/celery/schedulers.py +1 -1
- nautobot/core/filters.py +19 -16
- nautobot/core/forms/fields.py +5 -5
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +4 -4
- nautobot/core/jobs/cleanup.py +1 -1
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/models/__init__.py +1 -1
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +2 -2
- nautobot/core/settings.py +3 -0
- nautobot/core/settings.yaml +8 -0
- nautobot/core/tables.py +5 -5
- nautobot/core/templates/inc/media.html +3 -0
- nautobot/core/templates/nautobot_config.py.j2 +3 -0
- nautobot/core/testing/filters.py +7 -3
- nautobot/core/testing/views.py +5 -0
- nautobot/core/tests/integration/test_app_home.py +0 -1
- nautobot/core/tests/integration/test_app_navbar.py +0 -1
- nautobot/core/tests/integration/test_filters.py +0 -2
- nautobot/core/tests/integration/test_home.py +0 -1
- nautobot/core/tests/integration/test_navbar.py +0 -1
- nautobot/core/tests/integration/test_view_authentication.py +1 -0
- nautobot/core/tests/runner.py +1 -1
- nautobot/core/tests/test_views.py +29 -0
- nautobot/core/urls.py +9 -0
- nautobot/core/views/generic.py +51 -43
- nautobot/core/views/mixins.py +21 -11
- nautobot/dcim/api/serializers.py +48 -48
- nautobot/dcim/forms.py +2 -0
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +22 -20
- nautobot/dcim/models/devices.py +1 -1
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +6 -5
- nautobot/dcim/models/racks.py +4 -4
- nautobot/dcim/tables/__init__.py +3 -3
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/tests/test_filters.py +1 -0
- nautobot/dcim/tests/test_graphql.py +52 -0
- nautobot/dcim/tests/test_models.py +4 -1
- nautobot/dcim/views.py +1 -1
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +72 -69
- nautobot/extras/api/views.py +4 -4
- nautobot/extras/forms/mixins.py +1 -1
- nautobot/extras/health_checks.py +1 -2
- nautobot/extras/jobs.py +5 -5
- nautobot/extras/managers.py +3 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
- nautobot/extras/models/customfields.py +12 -11
- nautobot/extras/models/groups.py +13 -9
- nautobot/extras/models/jobs.py +4 -4
- nautobot/extras/models/models.py +2 -2
- nautobot/extras/plugins/views.py +1 -1
- nautobot/extras/tables.py +5 -5
- nautobot/extras/test_jobs/api_test_job.py +1 -1
- nautobot/extras/test_jobs/atomic_transaction.py +2 -2
- nautobot/extras/test_jobs/dry_run.py +1 -1
- nautobot/extras/test_jobs/fail.py +5 -5
- nautobot/extras/test_jobs/file_output.py +1 -1
- nautobot/extras/test_jobs/file_upload_fail.py +1 -1
- nautobot/extras/test_jobs/file_upload_pass.py +1 -1
- nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
- nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
- nautobot/extras/test_jobs/log_redaction.py +1 -1
- nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
- nautobot/extras/test_jobs/modify_db.py +1 -1
- nautobot/extras/test_jobs/object_var_optional.py +1 -1
- nautobot/extras/test_jobs/object_var_required.py +1 -1
- nautobot/extras/test_jobs/object_vars.py +1 -1
- nautobot/extras/test_jobs/pass.py +3 -3
- nautobot/extras/test_jobs/profiling.py +1 -1
- nautobot/extras/test_jobs/relative_import.py +3 -3
- nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
- nautobot/extras/test_jobs/task_queues.py +1 -1
- nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
- nautobot/extras/tests/test_api.py +13 -13
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_datasources.py +2 -1
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +6 -6
- nautobot/extras/tests/test_forms.py +20 -1
- nautobot/extras/tests/test_jobs.py +11 -11
- nautobot/extras/tests/test_models.py +10 -10
- nautobot/extras/tests/test_relationships.py +1 -1
- nautobot/extras/tests/test_views.py +16 -16
- nautobot/extras/views.py +20 -16
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +33 -33
- nautobot/ipam/api/views.py +37 -61
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tests/test_api.py +12 -1
- nautobot/ipam/tests/test_forms.py +51 -47
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_querysets.py +14 -0
- nautobot/project-static/docs/404.html +2 -2
- nautobot/project-static/docs/apps/index.html +2 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +3 -3
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3 -3
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +4 -4
- nautobot/project-static/docs/development/apps/api/configuration-view.html +2 -2
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/global-search.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/graphql.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +2 -2
- nautobot/project-static/docs/development/apps/api/prometheus.html +2 -2
- nautobot/project-static/docs/development/apps/api/setup.html +2 -2
- nautobot/project-static/docs/development/apps/api/testing.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/notes.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/urls.html +2 -2
- nautobot/project-static/docs/development/apps/index.html +2 -2
- nautobot/project-static/docs/development/apps/migration/code-updates.html +2 -2
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +2 -2
- nautobot/project-static/docs/development/apps/migration/from-v1.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +2 -2
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +2 -2
- nautobot/project-static/docs/development/core/application-registry.html +2 -2
- nautobot/project-static/docs/development/core/best-practices.html +2 -2
- nautobot/project-static/docs/development/core/bootstrap-ui.html +2 -2
- nautobot/project-static/docs/development/core/caching.html +2 -2
- nautobot/project-static/docs/development/core/controllers.html +2 -2
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +27 -70
- nautobot/project-static/docs/development/core/generic-views.html +2 -2
- nautobot/project-static/docs/development/core/getting-started.html +2 -2
- nautobot/project-static/docs/development/core/homepage.html +2 -2
- nautobot/project-static/docs/development/core/index.html +2 -2
- nautobot/project-static/docs/development/core/model-checklist.html +2 -2
- nautobot/project-static/docs/development/core/model-features.html +2 -2
- nautobot/project-static/docs/development/core/natural-keys.html +2 -2
- nautobot/project-static/docs/development/core/navigation-menu.html +2 -2
- nautobot/project-static/docs/development/core/release-checklist.html +2 -2
- nautobot/project-static/docs/development/core/role-internals.html +2 -2
- nautobot/project-static/docs/development/core/settings.html +2 -2
- nautobot/project-static/docs/development/core/style-guide.html +2 -2
- nautobot/project-static/docs/development/core/templates.html +2 -2
- nautobot/project-static/docs/development/core/testing.html +2 -2
- nautobot/project-static/docs/development/core/user-preferences.html +2 -2
- nautobot/project-static/docs/development/index.html +2 -2
- nautobot/project-static/docs/development/jobs/index.html +2 -2
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +2 -2
- nautobot/project-static/docs/index.html +2 -2
- nautobot/project-static/docs/overview/application_stack.html +2 -2
- nautobot/project-static/docs/overview/design_philosophy.html +2 -2
- nautobot/project-static/docs/release-notes/index.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.0.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.1.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.2.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.3.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.4.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.5.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.6.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.0.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.1.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.2.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.3.html +471 -220
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +270 -270
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +29 -2
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +2 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +2 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +2 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +2 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +2 -2
- nautobot/project-static/docs/user-guide/index.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +2 -2
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +4 -4
- nautobot/users/api/views.py +1 -1
- nautobot/virtualization/api/serializers.py +4 -4
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/METADATA +5 -4
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/RECORD +392 -393
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/WHEEL +1 -1
- nautobot/core/fixtures/user-data.json +0 -59
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/NOTICE +0 -0
- {nautobot-2.3.15b1.dist-info → nautobot-2.3.16.dist-info}/entry_points.txt +0 -0
|
@@ -138,7 +138,7 @@ class ModularComponentModel(ComponentModel):
|
|
|
138
138
|
@property
|
|
139
139
|
def parent(self):
|
|
140
140
|
"""Device that this component belongs to, walking up module inheritance if necessary."""
|
|
141
|
-
return self.module.device if self.module else self.device
|
|
141
|
+
return self.module.device if self.module else self.device # pylint: disable=no-member
|
|
142
142
|
|
|
143
143
|
def render_name_template(self, save=False):
|
|
144
144
|
"""
|
|
@@ -161,9 +161,9 @@ class ModularComponentModel(ComponentModel):
|
|
|
161
161
|
|
|
162
162
|
The deeply nested interface would be named "A{module.parent}" after calling this method.
|
|
163
163
|
"""
|
|
164
|
-
if self.module and self.module.parent_module_bay and "{module" in self.name:
|
|
164
|
+
if self.module and self.module.parent_module_bay and "{module" in self.name: # pylint: disable=no-member
|
|
165
165
|
name = ""
|
|
166
|
-
module_bay = self.module.parent_module_bay
|
|
166
|
+
module_bay = self.module.parent_module_bay # pylint: disable=no-member
|
|
167
167
|
positions = []
|
|
168
168
|
while module_bay is not None:
|
|
169
169
|
position = getattr(module_bay, "position", None)
|
|
@@ -291,11 +291,11 @@ class PathEndpoint(models.Model):
|
|
|
291
291
|
return []
|
|
292
292
|
|
|
293
293
|
# Construct the complete path
|
|
294
|
-
path = [self, *self._path.get_path()]
|
|
294
|
+
path = [self, *self._path.get_path()] # pylint: disable=no-member
|
|
295
295
|
while (len(path) + 1) % 3:
|
|
296
296
|
# Pad to ensure we have complete three-tuples (e.g. for paths that end at a RearPort)
|
|
297
297
|
path.append(None)
|
|
298
|
-
path.append(self._path.destination)
|
|
298
|
+
path.append(self._path.destination) # pylint: disable=no-member
|
|
299
299
|
|
|
300
300
|
# Return the path as a list of three-tuples (A termination, cable, B termination)
|
|
301
301
|
return list(zip(*[iter(path)] * 3))
|
|
@@ -555,7 +555,7 @@ class BaseInterface(RelationshipModel):
|
|
|
555
555
|
|
|
556
556
|
def clean(self):
|
|
557
557
|
# Remove untagged VLAN assignment for non-802.1Q interfaces
|
|
558
|
-
if not self.mode and self.untagged_vlan is not None:
|
|
558
|
+
if not self.mode and self.untagged_vlan is not None: # pylint: disable=no-member # Intf/VMIntf both have untagged_vlan
|
|
559
559
|
raise ValidationError({"untagged_vlan": "Mode must be set when specifying untagged_vlan"})
|
|
560
560
|
|
|
561
561
|
def save(self, *args, **kwargs):
|
|
@@ -569,8 +569,8 @@ class BaseInterface(RelationshipModel):
|
|
|
569
569
|
self.status = status
|
|
570
570
|
|
|
571
571
|
# Only "tagged" interfaces may have tagged VLANs assigned. ("tagged all" implies all VLANs are assigned.)
|
|
572
|
-
if self.present_in_database and self.mode != InterfaceModeChoices.MODE_TAGGED:
|
|
573
|
-
self.tagged_vlans.clear()
|
|
572
|
+
if self.present_in_database and self.mode != InterfaceModeChoices.MODE_TAGGED: # pylint: disable=no-member
|
|
573
|
+
self.tagged_vlans.clear() # pylint: disable=no-member # Intf/VMIntf both have tagged_vlans
|
|
574
574
|
|
|
575
575
|
return super().save(*args, **kwargs)
|
|
576
576
|
|
|
@@ -710,18 +710,19 @@ class Interface(ModularComponentModel, CableTermination, PathEndpoint, BaseInter
|
|
|
710
710
|
)
|
|
711
711
|
|
|
712
712
|
# An interface's parent must belong to the same device or virtual chassis
|
|
713
|
-
if self.parent and self.parent_interface.parent != self.parent:
|
|
713
|
+
if self.parent and self.parent_interface.parent != self.parent: # pylint: disable=no-member
|
|
714
714
|
if getattr(self.parent, "virtual_chassis", None) is None:
|
|
715
715
|
raise ValidationError(
|
|
716
|
-
{
|
|
717
|
-
"parent_interface": f"The selected parent interface ({self.parent_interface}) belongs
|
|
718
|
-
f"({self.parent_interface.parent})."
|
|
716
|
+
{ # pylint: disable=no-member # false positive on parent_interface.parent
|
|
717
|
+
"parent_interface": f"The selected parent interface ({self.parent_interface}) belongs "
|
|
718
|
+
f"to a different device ({self.parent_interface.parent})."
|
|
719
719
|
}
|
|
720
720
|
)
|
|
721
|
-
elif self.parent_interface.parent.virtual_chassis != self.parent.virtual_chassis:
|
|
721
|
+
elif self.parent_interface.parent.virtual_chassis != self.parent.virtual_chassis: # pylint: disable=no-member
|
|
722
722
|
raise ValidationError(
|
|
723
|
-
{
|
|
724
|
-
"parent_interface": f"The selected parent interface ({self.parent_interface}) belongs
|
|
723
|
+
{ # pylint: disable=no-member # false positive on parent_interface.parent
|
|
724
|
+
"parent_interface": f"The selected parent interface ({self.parent_interface}) belongs "
|
|
725
|
+
f"to {self.parent_interface.parent}, which "
|
|
725
726
|
f"is not part of virtual chassis {self.parent.virtual_chassis}."
|
|
726
727
|
}
|
|
727
728
|
)
|
|
@@ -754,21 +755,22 @@ class Interface(ModularComponentModel, CableTermination, PathEndpoint, BaseInter
|
|
|
754
755
|
raise ValidationError({"bridge": "An interface cannot be bridged to itself."})
|
|
755
756
|
|
|
756
757
|
# A bridged interface belong to the same device or virtual chassis
|
|
757
|
-
if self.parent and self.bridge.parent != self.parent:
|
|
758
|
+
if self.parent and self.bridge.parent != self.parent: # pylint: disable=no-member
|
|
758
759
|
if getattr(self.parent, "virtual_chassis", None) is None:
|
|
759
760
|
raise ValidationError(
|
|
760
761
|
{
|
|
761
762
|
"bridge": (
|
|
763
|
+
# pylint: disable=no-member # false positive on bridge.parent
|
|
762
764
|
f"The selected bridge interface ({self.bridge}) belongs to a different device "
|
|
763
765
|
f"({self.bridge.parent})."
|
|
764
766
|
)
|
|
765
767
|
}
|
|
766
768
|
)
|
|
767
|
-
elif self.bridge.parent.virtual_chassis_id != self.parent.virtual_chassis_id:
|
|
769
|
+
elif self.bridge.parent.virtual_chassis_id != self.parent.virtual_chassis_id: # pylint: disable=no-member
|
|
768
770
|
raise ValidationError(
|
|
769
771
|
{
|
|
770
772
|
"bridge": (
|
|
771
|
-
f"The selected bridge interface ({self.bridge}) belongs to {self.bridge.parent}, which "
|
|
773
|
+
f"The selected bridge interface ({self.bridge}) belongs to {self.bridge.parent}, which " # pylint: disable=no-member
|
|
772
774
|
f"is not part of virtual chassis {self.parent.virtual_chassis}."
|
|
773
775
|
)
|
|
774
776
|
}
|
|
@@ -1084,8 +1086,8 @@ class DeviceBay(ComponentModel):
|
|
|
1084
1086
|
super().clean()
|
|
1085
1087
|
|
|
1086
1088
|
# Validate that the parent Device can have DeviceBays
|
|
1087
|
-
if not self.device.device_type.is_parent_device:
|
|
1088
|
-
raise ValidationError(f"This type of device ({self.device.device_type}) does not support device bays.")
|
|
1089
|
+
if not self.device.device_type.is_parent_device: # pylint: disable=no-member
|
|
1090
|
+
raise ValidationError(f"This type of device ({self.device.device_type}) does not support device bays.") # pylint: disable=no-member
|
|
1089
1091
|
|
|
1090
1092
|
# Cannot install a device into itself, obviously
|
|
1091
1093
|
if self.device == self.installed_device:
|
nautobot/dcim/models/devices.py
CHANGED
|
@@ -1466,7 +1466,7 @@ class ControllerManagedDeviceGroup(TreeModel, PrimaryModel):
|
|
|
1466
1466
|
if self.controller == self._original_controller and self.parent == self._original_parent:
|
|
1467
1467
|
return
|
|
1468
1468
|
|
|
1469
|
-
if self.parent and self.controller and self.controller != self.parent.controller:
|
|
1469
|
+
if self.parent and self.controller and self.controller != self.parent.controller: # pylint: disable=no-member
|
|
1470
1470
|
raise ValidationError(
|
|
1471
1471
|
{"controller": "Controller device group must have the same controller as the parent group."}
|
|
1472
1472
|
)
|
|
@@ -283,7 +283,7 @@ class Location(TreeModel, PrimaryModel):
|
|
|
283
283
|
# We shouldn't have a parent, *unless* our own location type is permitted to be nested.
|
|
284
284
|
if self.parent is not None:
|
|
285
285
|
if self.location_type.nestable:
|
|
286
|
-
if self.parent.location_type != self.location_type:
|
|
286
|
+
if self.parent.location_type != self.location_type: # pylint: disable=no-member
|
|
287
287
|
raise ValidationError(
|
|
288
288
|
{
|
|
289
289
|
"parent": f"A Location of type {self.location_type} may only have "
|
|
@@ -304,7 +304,7 @@ class Location(TreeModel, PrimaryModel):
|
|
|
304
304
|
|
|
305
305
|
# Is the parent location of a correct type?
|
|
306
306
|
if self.location_type.nestable:
|
|
307
|
-
if self.parent.location_type not in (self.location_type, self.location_type.parent):
|
|
307
|
+
if self.parent.location_type not in (self.location_type, self.location_type.parent): # pylint: disable=no-member
|
|
308
308
|
raise ValidationError(
|
|
309
309
|
{
|
|
310
310
|
"parent": f"A Location of type {self.location_type} can only have a Location "
|
|
@@ -312,7 +312,7 @@ class Location(TreeModel, PrimaryModel):
|
|
|
312
312
|
}
|
|
313
313
|
)
|
|
314
314
|
else:
|
|
315
|
-
if self.parent.location_type != self.location_type.parent:
|
|
315
|
+
if self.parent.location_type != self.location_type.parent: # pylint: disable=no-member
|
|
316
316
|
raise ValidationError(
|
|
317
317
|
{
|
|
318
318
|
"parent": f"A Location of type {self.location_type} can only have a Location "
|
nautobot/dcim/models/power.py
CHANGED
|
@@ -73,11 +73,11 @@ class PowerPanel(PrimaryModel):
|
|
|
73
73
|
if self.rack_group:
|
|
74
74
|
if (
|
|
75
75
|
self.location is not None
|
|
76
|
-
and self.rack_group.location is not None
|
|
77
|
-
and self.rack_group.location not in self.location.ancestors(include_self=True)
|
|
76
|
+
and self.rack_group.location is not None # pylint: disable=no-member
|
|
77
|
+
and self.rack_group.location not in self.location.ancestors(include_self=True) # pylint: disable=no-member
|
|
78
78
|
):
|
|
79
79
|
raise ValidationError(
|
|
80
|
-
{
|
|
80
|
+
{ # pylint: disable=no-member # false positive on rack_group.location
|
|
81
81
|
"rack_group": f'Rack group "{self.rack_group}" belongs to a location '
|
|
82
82
|
f'("{self.rack_group.location}") that does not contain "{self.location}".'
|
|
83
83
|
}
|
|
@@ -151,9 +151,10 @@ class PowerFeed(PrimaryModel, PathEndpoint, CableTermination):
|
|
|
151
151
|
super().clean()
|
|
152
152
|
|
|
153
153
|
# Rack must belong to same Location as PowerPanel
|
|
154
|
-
if self.rack and self.rack.location != self.power_panel.location:
|
|
154
|
+
if self.rack and self.rack.location != self.power_panel.location: # pylint: disable=no-member
|
|
155
155
|
raise ValidationError(
|
|
156
|
-
f"Rack {self.rack} ({self.rack.location}) and
|
|
156
|
+
f"Rack {self.rack} ({self.rack.location}) and " # pylint: disable=no-member
|
|
157
|
+
f"power panel {self.power_panel} ({self.power_panel.location}) are in different locations"
|
|
157
158
|
)
|
|
158
159
|
|
|
159
160
|
# AC voltage cannot be negative
|
nautobot/dcim/models/racks.py
CHANGED
|
@@ -77,11 +77,11 @@ class RackGroup(TreeModel, OrganizationalModel):
|
|
|
77
77
|
# Parent RackGroup (if any) must belong to the same or ancestor Location
|
|
78
78
|
if (
|
|
79
79
|
self.parent is not None
|
|
80
|
-
and self.parent.location is not None
|
|
81
|
-
and self.parent.location not in self.location.ancestors(include_self=True)
|
|
80
|
+
and self.parent.location is not None # pylint: disable=no-member
|
|
81
|
+
and self.parent.location not in self.location.ancestors(include_self=True) # pylint: disable=no-member
|
|
82
82
|
):
|
|
83
83
|
raise ValidationError(
|
|
84
|
-
{
|
|
84
|
+
{ # pylint: disable=no-member # false positive on parent.location
|
|
85
85
|
"location": f'Location "{self.location}" is not descended from '
|
|
86
86
|
f'parent rack group "{self.parent}" location "{self.parent.location}".'
|
|
87
87
|
}
|
|
@@ -296,7 +296,7 @@ class Rack(PrimaryModel):
|
|
|
296
296
|
# Determine which devices the user has permission to view
|
|
297
297
|
permitted_device_ids = []
|
|
298
298
|
if user is not None:
|
|
299
|
-
permitted_device_ids = self.devices.restrict(user, "view").values_list("pk", flat=True)
|
|
299
|
+
permitted_device_ids = self.devices.restrict(user, "view").values_list("pk", flat=True) # pylint: disable=no-member
|
|
300
300
|
|
|
301
301
|
for device in queryset:
|
|
302
302
|
if expand_devices:
|
nautobot/dcim/tables/__init__.py
CHANGED
|
@@ -143,7 +143,7 @@ class ConsoleConnectionTable(BaseTable):
|
|
|
143
143
|
linkify=True,
|
|
144
144
|
verbose_name="Port",
|
|
145
145
|
)
|
|
146
|
-
device = tables.Column(linkify=True, accessor="parent")
|
|
146
|
+
device = tables.Column(linkify=True, accessor="parent", orderable=False)
|
|
147
147
|
name = tables.Column(linkify=True, verbose_name="Console Port")
|
|
148
148
|
reachable = BooleanColumn(accessor=Accessor("_path__is_active"), verbose_name="Reachable")
|
|
149
149
|
|
|
@@ -171,7 +171,7 @@ class PowerConnectionTable(BaseTable):
|
|
|
171
171
|
linkify=True,
|
|
172
172
|
verbose_name="Outlet",
|
|
173
173
|
)
|
|
174
|
-
device = tables.Column(linkify=True, accessor="parent")
|
|
174
|
+
device = tables.Column(linkify=True, accessor="parent", orderable=False)
|
|
175
175
|
name = tables.Column(linkify=True, verbose_name="Power Port")
|
|
176
176
|
reachable = BooleanColumn(accessor=Accessor("_path__is_active"), verbose_name="Reachable")
|
|
177
177
|
|
|
@@ -181,7 +181,7 @@ class PowerConnectionTable(BaseTable):
|
|
|
181
181
|
|
|
182
182
|
|
|
183
183
|
class InterfaceConnectionTable(BaseTable):
|
|
184
|
-
device_a = tables.Column(accessor=Accessor("parent"), linkify=True, verbose_name="Device A")
|
|
184
|
+
device_a = tables.Column(accessor=Accessor("parent"), linkify=True, verbose_name="Device A", orderable=False)
|
|
185
185
|
interface_a = tables.Column(accessor=Accessor("name"), linkify=True, verbose_name="Interface A")
|
|
186
186
|
device_b = tables.Column(
|
|
187
187
|
accessor=Accessor("_path__destination__parent"),
|
|
@@ -253,7 +253,7 @@ class PowerOutletTemplateTable(ComponentTemplateTable):
|
|
|
253
253
|
"name",
|
|
254
254
|
"label",
|
|
255
255
|
"type",
|
|
256
|
-
"
|
|
256
|
+
"power_port_template",
|
|
257
257
|
"feed_leg",
|
|
258
258
|
"description",
|
|
259
259
|
"actions",
|
|
@@ -290,7 +290,7 @@ class FrontPortTemplateTable(ComponentTemplateTable):
|
|
|
290
290
|
"name",
|
|
291
291
|
"label",
|
|
292
292
|
"type",
|
|
293
|
-
"
|
|
293
|
+
"rear_port_template",
|
|
294
294
|
"rear_port_position",
|
|
295
295
|
"description",
|
|
296
296
|
"actions",
|
|
@@ -83,3 +83,55 @@ class GraphQLTestCase(TestCase):
|
|
|
83
83
|
self.assertEqual(
|
|
84
84
|
resp["data"]["devices"][0]["platform"]["network_driver_mappings"]["scrapli"], "cisco_iosxe"
|
|
85
85
|
)
|
|
86
|
+
|
|
87
|
+
with self.subTest("device serial number query"):
|
|
88
|
+
non_empty_serial_device = Device.objects.first()
|
|
89
|
+
non_empty_serial_device.serial = "1234567890abceFGHIJKL"
|
|
90
|
+
non_empty_serial_device.save()
|
|
91
|
+
|
|
92
|
+
# Test device serial query default behavior: serial__ie
|
|
93
|
+
query = 'query { devices (serial: " ") { name serial } }'
|
|
94
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
95
|
+
self.assertFalse(resp["data"].get("error"))
|
|
96
|
+
for device in resp["data"]["devices"]:
|
|
97
|
+
self.assertEqual(device["serial"], "")
|
|
98
|
+
|
|
99
|
+
# Test device serial default filter with non-empty serial number
|
|
100
|
+
query = 'query { devices (serial:"' + non_empty_serial_device.serial.lower() + '") { name serial } }'
|
|
101
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
102
|
+
self.assertFalse(resp["data"].get("error"))
|
|
103
|
+
self.assertEqual(resp["data"]["devices"][0]["serial"], non_empty_serial_device.serial)
|
|
104
|
+
|
|
105
|
+
# Test device serial iexact filter with non-empty serial number
|
|
106
|
+
query = 'query { devices (serial__ie:"' + non_empty_serial_device.serial.upper() + '") { name serial } }'
|
|
107
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
108
|
+
self.assertFalse(resp["data"].get("error"))
|
|
109
|
+
self.assertEqual(resp["data"]["devices"][0]["serial"], non_empty_serial_device.serial)
|
|
110
|
+
|
|
111
|
+
# Test device serial__nie filter with non-empty serial number
|
|
112
|
+
query = 'query { devices (serial__nie:"' + non_empty_serial_device.serial.lower() + '") { name serial } }'
|
|
113
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
114
|
+
self.assertFalse(resp["data"].get("error"))
|
|
115
|
+
for device in resp["data"]["devices"]:
|
|
116
|
+
self.assertNotEqual(device["serial"], non_empty_serial_device.serial)
|
|
117
|
+
|
|
118
|
+
# Test device serial__ie filter with empty serial number
|
|
119
|
+
query = 'query { devices (serial__ie:" ") { name serial } }'
|
|
120
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
121
|
+
self.assertFalse(resp["data"].get("error"))
|
|
122
|
+
for device in resp["data"]["devices"]:
|
|
123
|
+
self.assertEqual(device["serial"], "")
|
|
124
|
+
|
|
125
|
+
# Test device serial__nie filter with empty serial number
|
|
126
|
+
query = 'query { devices (serial__nie:" ") { name serial } }'
|
|
127
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
128
|
+
self.assertFalse(resp["data"].get("error"))
|
|
129
|
+
for device in resp["data"]["devices"]:
|
|
130
|
+
self.assertNotEqual(device["serial"], "")
|
|
131
|
+
|
|
132
|
+
# Test device serial__n filter with empty serial number
|
|
133
|
+
query = 'query { devices (serial__n:" ") { name serial } }'
|
|
134
|
+
resp = execute_query(query, user=self.user).to_dict()
|
|
135
|
+
self.assertFalse(resp["data"].get("error"))
|
|
136
|
+
for device in resp["data"]["devices"]:
|
|
137
|
+
self.assertNotEqual(device["serial"], "")
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations # python 3.8
|
|
2
|
+
|
|
1
3
|
from decimal import Decimal
|
|
2
4
|
|
|
3
5
|
from constance.test import override_config
|
|
4
6
|
from django.contrib.contenttypes.models import ContentType
|
|
5
7
|
from django.core.exceptions import ValidationError
|
|
6
8
|
from django.db import IntegrityError
|
|
9
|
+
from django.db.models import Model
|
|
7
10
|
from django.test import TestCase
|
|
8
11
|
from django.test.utils import override_settings
|
|
9
12
|
|
|
@@ -76,7 +79,7 @@ class ModularDeviceComponentTestCaseMixin:
|
|
|
76
79
|
|
|
77
80
|
# fields required to create instances of the model, with the exception of name, device_field and module_field
|
|
78
81
|
modular_component_create_data = {}
|
|
79
|
-
model
|
|
82
|
+
model: type[Model]
|
|
80
83
|
device_field = "device" # field name for the parent device
|
|
81
84
|
module_field = "module" # field name for the parent module
|
|
82
85
|
|
nautobot/dcim/views.py
CHANGED
|
@@ -699,7 +699,7 @@ class RackReservationEditView(generic.ObjectEditView):
|
|
|
699
699
|
model_form = forms.RackReservationForm
|
|
700
700
|
template_name = "dcim/rackreservation_edit.html"
|
|
701
701
|
|
|
702
|
-
def alter_obj(self, obj, request,
|
|
702
|
+
def alter_obj(self, obj, request, url_args, url_kwargs):
|
|
703
703
|
if not obj.present_in_database:
|
|
704
704
|
if "rack" in request.GET:
|
|
705
705
|
obj.rack = get_object_or_404(Rack, pk=request.GET.get("rack"))
|
|
@@ -42,8 +42,8 @@ class CustomFieldsDataField(Field):
|
|
|
42
42
|
def custom_field_keys(self):
|
|
43
43
|
return CustomField.objects.keys_for_model(self.parent.Meta.model)
|
|
44
44
|
|
|
45
|
-
def to_representation(self,
|
|
46
|
-
return {key:
|
|
45
|
+
def to_representation(self, value):
|
|
46
|
+
return {key: value.get(key) for key in self.custom_field_keys}
|
|
47
47
|
|
|
48
48
|
def to_internal_value(self, data):
|
|
49
49
|
"""Support updates to individual fields on an existing instance without needing to provide the entire dict."""
|