nautobot 2.2.0__py3-none-any.whl → 2.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/__init__.py +31 -0
- nautobot/circuits/apps.py +1 -1
- nautobot/core/api/routers.py +25 -0
- nautobot/core/cli/__init__.py +18 -11
- nautobot/core/constants.py +85 -0
- nautobot/core/forms/widgets.py +1 -2
- nautobot/core/graphql/schema.py +1 -0
- nautobot/core/models/__init__.py +1 -0
- nautobot/core/settings.py +23 -3
- nautobot/core/settings.yaml +20 -0
- nautobot/core/signals.py +1 -0
- nautobot/core/templates/generic/object_retrieve.html +2 -2
- nautobot/core/templates/inc/javascript.html +4 -4
- nautobot/core/templates/inc/media.html +2 -2
- nautobot/core/templates/nautobot_config.py.j2 +14 -1
- nautobot/core/testing/__init__.py +1 -1
- nautobot/core/testing/filters.py +1 -1
- nautobot/core/tests/integration/test_view_authentication.py +1 -0
- nautobot/core/tests/test_views.py +22 -0
- nautobot/core/utils/data.py +1 -2
- nautobot/core/utils/lookup.py +2 -0
- nautobot/core/views/generic.py +1 -3
- nautobot/core/views/mixins.py +0 -1
- nautobot/core/views/renderers.py +7 -5
- nautobot/dcim/apps.py +8 -4
- nautobot/dcim/elevations.py +5 -1
- nautobot/dcim/tables/devices.py +1 -1
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +12 -4
- nautobot/dcim/templates/dcim/device.html +1 -1
- nautobot/dcim/templates/dcim/devicefamily_retrieve.html +4 -0
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +1 -1
- nautobot/dcim/tests/test_api.py +36 -0
- nautobot/dcim/tests/test_signals.py +1 -1
- nautobot/dcim/views.py +6 -0
- nautobot/extras/api/serializers.py +20 -1
- nautobot/extras/apps.py +7 -0
- nautobot/extras/context_managers.py +15 -4
- nautobot/extras/filters/customfields.py +14 -9
- nautobot/extras/filters/mixins.py +6 -1
- nautobot/extras/health_checks.py +1 -0
- nautobot/extras/jobs.py +1 -0
- nautobot/extras/managers.py +1 -2
- nautobot/extras/models/contacts.py +1 -0
- nautobot/extras/models/customfields.py +25 -2
- nautobot/extras/models/datasources.py +1 -0
- nautobot/extras/models/mixins.py +1 -0
- nautobot/extras/plugins/__init__.py +2 -1
- nautobot/extras/querysets.py +1 -2
- nautobot/extras/secrets/providers.py +1 -0
- nautobot/extras/signals.py +15 -5
- nautobot/extras/tasks.py +70 -17
- nautobot/extras/tests/test_api.py +0 -4
- nautobot/extras/tests/test_customfields.py +72 -9
- nautobot/extras/views.py +8 -7
- nautobot/ipam/api/serializers.py +10 -0
- nautobot/ipam/apps.py +3 -2
- nautobot/project-static/docs/404.html +102 -70
- nautobot/project-static/docs/apps/index.html +103 -68
- nautobot/project-static/docs/apps/nautobot-apps.html +103 -68
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js → bundle.bd41221c.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js.map → bundle.bd41221c.min.js.map} +3 -3
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +141 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +141 -69
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +104 -69
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +103 -68
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +103 -68
- nautobot/project-static/docs/development/apps/api/configuration-view.html +103 -68
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +103 -68
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +103 -68
- nautobot/project-static/docs/development/apps/api/models/global-search.html +103 -68
- nautobot/project-static/docs/development/apps/api/models/graphql.html +103 -68
- nautobot/project-static/docs/development/apps/api/models/index.html +103 -68
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +103 -68
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +103 -68
- nautobot/project-static/docs/development/apps/api/prometheus.html +103 -68
- nautobot/project-static/docs/development/apps/api/setup.html +103 -68
- nautobot/project-static/docs/development/apps/api/testing.html +103 -68
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +103 -68
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +103 -68
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +103 -68
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +103 -68
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/base-template.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/index.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/notes.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +103 -68
- nautobot/project-static/docs/development/apps/api/views/urls.html +103 -68
- nautobot/project-static/docs/development/apps/index.html +103 -68
- nautobot/project-static/docs/development/apps/migration/code-updates.html +103 -68
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +103 -68
- nautobot/project-static/docs/development/apps/migration/from-v1.html +103 -68
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +103 -68
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +103 -68
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +103 -68
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +103 -68
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +103 -68
- nautobot/project-static/docs/development/core/application-registry.html +103 -68
- nautobot/project-static/docs/development/core/best-practices.html +121 -76
- nautobot/project-static/docs/development/core/bootstrap-ui.html +103 -68
- nautobot/project-static/docs/development/core/caching.html +103 -68
- nautobot/project-static/docs/development/core/controllers.html +106 -71
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +103 -68
- nautobot/project-static/docs/development/core/extending-models.html +13 -8187
- nautobot/project-static/docs/development/core/generic-views.html +118 -83
- nautobot/project-static/docs/development/core/getting-started.html +103 -68
- nautobot/project-static/docs/development/core/homepage.html +121 -86
- nautobot/project-static/docs/development/core/index.html +103 -68
- nautobot/project-static/docs/development/core/model-checklist.html +8354 -0
- nautobot/project-static/docs/development/core/model-features.html +106 -71
- nautobot/project-static/docs/development/core/natural-keys.html +103 -68
- nautobot/project-static/docs/development/core/navigation-menu.html +103 -68
- nautobot/project-static/docs/development/core/release-checklist.html +103 -68
- nautobot/project-static/docs/development/core/role-internals.html +103 -68
- nautobot/project-static/docs/development/core/settings.html +103 -68
- nautobot/project-static/docs/development/core/style-guide.html +103 -68
- nautobot/project-static/docs/development/core/templates.html +103 -68
- nautobot/project-static/docs/development/core/testing.html +103 -68
- nautobot/project-static/docs/development/core/user-preferences.html +103 -68
- nautobot/project-static/docs/development/extending-models.html +3 -3
- nautobot/project-static/docs/development/index.html +103 -68
- nautobot/project-static/docs/development/jobs/index.html +104 -69
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +103 -68
- nautobot/project-static/docs/index.html +102 -70
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.0.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.1.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.2.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.3.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.4.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.5.html +103 -68
- nautobot/project-static/docs/release-notes/version-1.6.html +103 -68
- nautobot/project-static/docs/release-notes/version-2.0.html +103 -68
- nautobot/project-static/docs/release-notes/version-2.1.html +103 -68
- nautobot/project-static/docs/release-notes/version-2.2.html +334 -97
- nautobot/project-static/docs/requirements.txt +3 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +258 -258
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +103 -68
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +103 -68
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +103 -68
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +103 -68
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +168 -68
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +103 -68
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +107 -68
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +103 -68
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +106 -71
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/index.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +103 -68
- nautobot/project-static/docs/user-guide/administration/installation/services.html +103 -68
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +103 -68
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +103 -68
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +103 -68
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +103 -68
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +114 -68
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +114 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +103 -68
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +103 -68
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +103 -68
- nautobot/project-static/docs/user-guide/index.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +103 -68
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +103 -68
- nautobot/project-static/jquery/jquery-3.7.1.min.js +2 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_444444_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_555555_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777620_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777777_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_cc0000_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_ffffff_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.css +7 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.js +6 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.structure.min.css +5 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/jquery-ui.theme.min.css +1 -1
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/METADATA +22 -22
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/RECORD +339 -338
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css.map +0 -1
- nautobot/project-static/jquery/jquery-3.6.0.min.js +0 -2
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.css +0 -7
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.js +0 -6
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.structure.min.css +0 -5
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/NOTICE +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/WHEEL +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.1.dist-info}/entry_points.txt +0 -0
nautobot/dcim/apps.py
CHANGED
|
@@ -5,14 +5,18 @@ class DCIMConfig(NautobotConfig):
|
|
|
5
5
|
name = "nautobot.dcim"
|
|
6
6
|
verbose_name = "DCIM"
|
|
7
7
|
searchable_models = [
|
|
8
|
+
"cable",
|
|
9
|
+
"controller",
|
|
10
|
+
"device",
|
|
11
|
+
"devicefamily",
|
|
12
|
+
"deviceredundancygroup",
|
|
13
|
+
"devicetype",
|
|
8
14
|
"location",
|
|
15
|
+
"powerfeed",
|
|
9
16
|
"rack",
|
|
10
17
|
"rackgroup",
|
|
11
|
-
"
|
|
12
|
-
"device",
|
|
18
|
+
"softwareversion",
|
|
13
19
|
"virtualchassis",
|
|
14
|
-
"cable",
|
|
15
|
-
"powerfeed",
|
|
16
20
|
]
|
|
17
21
|
|
|
18
22
|
def ready(self):
|
nautobot/dcim/elevations.py
CHANGED
|
@@ -3,6 +3,8 @@ from django.urls import reverse
|
|
|
3
3
|
from django.utils.http import urlencode
|
|
4
4
|
import svgwrite
|
|
5
5
|
|
|
6
|
+
from nautobot.core.utils.config import get_settings_or_config
|
|
7
|
+
|
|
6
8
|
from .choices import DeviceFaceChoices
|
|
7
9
|
from .constants import RACK_ELEVATION_BORDER_WIDTH
|
|
8
10
|
|
|
@@ -233,7 +235,9 @@ class RackElevationSVG:
|
|
|
233
235
|
start_y + unit_height / 2 + RACK_ELEVATION_BORDER_WIDTH,
|
|
234
236
|
)
|
|
235
237
|
unit = ru + 1 if self.rack.desc_units else self.rack.u_height - ru
|
|
236
|
-
|
|
238
|
+
unit_two_digit_format = get_settings_or_config("RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT")
|
|
239
|
+
unit_display = f"{unit:02d}" if unit_two_digit_format else str(unit)
|
|
240
|
+
drawing.add(drawing.text(unit_display, position_coordinates, class_="unit"))
|
|
237
241
|
|
|
238
242
|
for unit in self.merge_elevations(face):
|
|
239
243
|
# Loop through all units in the elevation
|
nautobot/dcim/tables/devices.py
CHANGED
|
@@ -919,7 +919,7 @@ class VirtualChassisTable(BaseTable):
|
|
|
919
919
|
master = tables.Column(linkify=True)
|
|
920
920
|
member_count = LinkedCountColumn(
|
|
921
921
|
viewname="dcim:device_list",
|
|
922
|
-
url_params={"
|
|
922
|
+
url_params={"virtual_chassis": "pk"},
|
|
923
923
|
verbose_name="Members",
|
|
924
924
|
)
|
|
925
925
|
tags = TagColumn(url_name="dcim:virtualchassis_list")
|
|
@@ -64,6 +64,13 @@ var ready = (callback) => {
|
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
+
function getAttribute(node, querySelector, attribute) {
|
|
68
|
+
if (node === null or node.querySelector(querySelector) === null) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
return node.querySelector(querySelector).getAttribute(attribute) || "";
|
|
72
|
+
}
|
|
73
|
+
|
|
67
74
|
ready(() => {
|
|
68
75
|
fetch("{% url 'dcim-api:device-napalm' pk=object.pk %}?method=get_lldp_neighbors_detail")
|
|
69
76
|
.then((response) => {
|
|
@@ -80,10 +87,10 @@ ready(() => {
|
|
|
80
87
|
// var row = $('*[data-interface-name="' + iface.split(".")[0].replace(/([\/:])/g, "\\$1") + '"]');
|
|
81
88
|
|
|
82
89
|
// Glean configured hostnames/interfaces from the DOM
|
|
83
|
-
const configured_device = row
|
|
84
|
-
const configured_chassis = row
|
|
85
|
-
const configured_interface = row
|
|
86
|
-
const configured_mac_address = row
|
|
90
|
+
const configured_device = getAttribute(row, 'td.configured_device', 'data');
|
|
91
|
+
const configured_chassis = getAttribute(row, 'td.configured_device', 'data-chassis');
|
|
92
|
+
const configured_interface = getAttribute(row, 'td.configured_interface', 'data-interface-name').toLowerCase();
|
|
93
|
+
const configured_mac_address = getAttribute(row, 'td.configured_mac', 'data-mac-address').toLowerCase();
|
|
87
94
|
let configured_interface_short = null;
|
|
88
95
|
if (configured_interface) {
|
|
89
96
|
// Match long-form IOS names against short ones (e.g. Gi0/1 == GigabitEthernet0/1).
|
|
@@ -122,5 +129,6 @@ ready(() => {
|
|
|
122
129
|
}
|
|
123
130
|
});
|
|
124
131
|
});
|
|
132
|
+
|
|
125
133
|
</script>
|
|
126
134
|
{% endblock %}
|
|
@@ -360,7 +360,7 @@
|
|
|
360
360
|
</div>
|
|
361
361
|
</div>
|
|
362
362
|
</div>
|
|
363
|
-
{% if
|
|
363
|
+
{% if object.is_contact_associable_model %}
|
|
364
364
|
<div id="contacts" role="tabpanel" class="tab-pane {% if request.GET.tab == 'contacts' %}active{% else %}fade{% endif %}">
|
|
365
365
|
<div class="row">
|
|
366
366
|
<div class="col-md-12">
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
<td>Device Types</td>
|
|
19
19
|
<td><a href="{% url 'dcim:devicetype_list' %}?device_family={{ object.name }}">{{ object.device_type_count }}</a></td>
|
|
20
20
|
</tr>
|
|
21
|
+
<tr>
|
|
22
|
+
<td>Total Devices</td>
|
|
23
|
+
<td>{{ total_devices }}</td>
|
|
24
|
+
</tr>
|
|
21
25
|
</table>
|
|
22
26
|
</div>
|
|
23
27
|
{% endblock %}
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
</div>
|
|
170
170
|
</div>
|
|
171
171
|
</div>
|
|
172
|
-
{% if
|
|
172
|
+
{% if object.is_contact_associable_model %}
|
|
173
173
|
<div id="contacts" role="tabpanel" class="tab-pane {% if request.GET.tab == 'contacts' %}active{% else %}fade{% endif %}">
|
|
174
174
|
<div class="row">
|
|
175
175
|
<div class="col-md-12">
|
nautobot/dcim/tests/test_api.py
CHANGED
|
@@ -618,6 +618,42 @@ class RackTest(APIViewTestCases.APIViewTestCase):
|
|
|
618
618
|
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
619
619
|
self.assertIn(b'class="slot" height="19" width="190"', response.content)
|
|
620
620
|
|
|
621
|
+
@override_settings(
|
|
622
|
+
RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=False,
|
|
623
|
+
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT=22,
|
|
624
|
+
RACK_ELEVATION_DEFAULT_UNIT_WIDTH=230,
|
|
625
|
+
)
|
|
626
|
+
@override_config(RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=True)
|
|
627
|
+
def test_get_rack_elevation_unit_svg_settings_overridden(self):
|
|
628
|
+
"""
|
|
629
|
+
GET a single rack elevation in SVG format, with Django settings specifying the default RU display format
|
|
630
|
+
"""
|
|
631
|
+
rack = Rack.objects.first()
|
|
632
|
+
self.add_permissions("dcim.view_rack")
|
|
633
|
+
reverse_url = reverse("dcim-api:rack-elevation", kwargs={"pk": rack.pk})
|
|
634
|
+
url = f"{reverse_url}?render=svg"
|
|
635
|
+
|
|
636
|
+
response = self.client.get(url, **self.header)
|
|
637
|
+
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
638
|
+
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
639
|
+
self.assertIn(b'<text class="unit" x="15.0" y="915.0">1</text>', response.content)
|
|
640
|
+
|
|
641
|
+
@override_settings(RACK_ELEVATION_DEFAULT_UNIT_HEIGHT=22, RACK_ELEVATION_DEFAULT_UNIT_WIDTH=230)
|
|
642
|
+
@override_config(RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=True)
|
|
643
|
+
def test_get_rack_elevation_unit_svg_config_overridden(self):
|
|
644
|
+
"""
|
|
645
|
+
GET a single rack elevation in SVG format, with Constance config specifying the 2-digit RU display format
|
|
646
|
+
"""
|
|
647
|
+
rack = Rack.objects.first()
|
|
648
|
+
self.add_permissions("dcim.view_rack")
|
|
649
|
+
reverse_url = reverse("dcim-api:rack-elevation", kwargs={"pk": rack.pk})
|
|
650
|
+
url = f"{reverse_url}?render=svg"
|
|
651
|
+
|
|
652
|
+
response = self.client.get(url, **self.header)
|
|
653
|
+
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
654
|
+
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
655
|
+
self.assertIn(b'<text class="unit" x="15.0" y="915.0">01</text>', response.content)
|
|
656
|
+
|
|
621
657
|
def test_detail_view_schema(self):
|
|
622
658
|
url = self._get_detail_url(self._get_queryset().first())
|
|
623
659
|
response = self.client.options(url, **self.header)
|
nautobot/dcim/views.py
CHANGED
|
@@ -2978,6 +2978,12 @@ class DeviceFamilyUIViewSet(NautobotUIViewSet):
|
|
|
2978
2978
|
RequestConfig(request, paginate).configure(device_type_table)
|
|
2979
2979
|
|
|
2980
2980
|
context["device_type_table"] = device_type_table
|
|
2981
|
+
|
|
2982
|
+
total_devices = 0
|
|
2983
|
+
for device_type in device_types:
|
|
2984
|
+
total_devices += device_type.device_count
|
|
2985
|
+
context["total_devices"] = total_devices
|
|
2986
|
+
|
|
2981
2987
|
return context
|
|
2982
2988
|
|
|
2983
2989
|
|
|
@@ -193,10 +193,18 @@ class ContactSerializer(NautobotModelSerializer):
|
|
|
193
193
|
class Meta:
|
|
194
194
|
model = Contact
|
|
195
195
|
fields = "__all__"
|
|
196
|
+
# https://www.django-rest-framework.org/api-guide/validators/#optional-fields
|
|
197
|
+
validators = []
|
|
198
|
+
extra_kwargs = {
|
|
199
|
+
"email": {"default": ""},
|
|
200
|
+
"phone": {"default": ""},
|
|
201
|
+
}
|
|
196
202
|
|
|
197
203
|
def validate(self, data):
|
|
198
204
|
attrs = data.copy()
|
|
199
205
|
attrs.pop("teams", None)
|
|
206
|
+
validator = UniqueTogetherValidator(queryset=Contact.objects.all(), fields=("name", "phone", "email"))
|
|
207
|
+
validator(attrs, self)
|
|
200
208
|
super().validate(attrs)
|
|
201
209
|
return data
|
|
202
210
|
|
|
@@ -946,7 +954,18 @@ class TeamSerializer(NautobotModelSerializer):
|
|
|
946
954
|
class Meta:
|
|
947
955
|
model = Team
|
|
948
956
|
fields = "__all__"
|
|
949
|
-
extra_kwargs = {
|
|
957
|
+
extra_kwargs = {
|
|
958
|
+
"contacts": {"required": False},
|
|
959
|
+
"email": {"default": ""},
|
|
960
|
+
"phone": {"default": ""},
|
|
961
|
+
}
|
|
962
|
+
# https://www.django-rest-framework.org/api-guide/validators/#optional-fields
|
|
963
|
+
validators = []
|
|
964
|
+
|
|
965
|
+
def validate(self, data):
|
|
966
|
+
validator = UniqueTogetherValidator(queryset=Team.objects.all(), fields=("name", "phone", "email"))
|
|
967
|
+
validator(data, self)
|
|
968
|
+
return super().validate(data)
|
|
950
969
|
|
|
951
970
|
|
|
952
971
|
#
|
nautobot/extras/apps.py
CHANGED
|
@@ -12,6 +12,13 @@ logger = logging.getLogger(__name__)
|
|
|
12
12
|
|
|
13
13
|
class ExtrasConfig(NautobotConfig):
|
|
14
14
|
name = "nautobot.extras"
|
|
15
|
+
searchable_models = [
|
|
16
|
+
"contact",
|
|
17
|
+
"dynamicgroup",
|
|
18
|
+
"externalintegration",
|
|
19
|
+
"gitrepository",
|
|
20
|
+
"team",
|
|
21
|
+
]
|
|
15
22
|
|
|
16
23
|
def ready(self):
|
|
17
24
|
super().ready()
|
|
@@ -7,7 +7,7 @@ from django.test.client import RequestFactory
|
|
|
7
7
|
|
|
8
8
|
from nautobot.extras.choices import ObjectChangeEventContextChoices
|
|
9
9
|
from nautobot.extras.models import ObjectChange
|
|
10
|
-
from nautobot.extras.signals import change_context_state
|
|
10
|
+
from nautobot.extras.signals import change_context_state, get_user_if_authenticated
|
|
11
11
|
from nautobot.extras.webhooks import enqueue_webhooks
|
|
12
12
|
|
|
13
13
|
|
|
@@ -46,11 +46,22 @@ class ChangeContext:
|
|
|
46
46
|
if self.change_id is None:
|
|
47
47
|
self.change_id = uuid.uuid4()
|
|
48
48
|
|
|
49
|
-
def get_user(self):
|
|
49
|
+
def get_user(self, instance=None):
|
|
50
50
|
"""Return self.user if set, otherwise return self.request.user"""
|
|
51
51
|
if self.user is not None:
|
|
52
|
-
return self.user
|
|
53
|
-
return self.request.user
|
|
52
|
+
return get_user_if_authenticated(self.user, instance)
|
|
53
|
+
return get_user_if_authenticated(self.request.user, instance)
|
|
54
|
+
|
|
55
|
+
def as_dict(self, instance=None):
|
|
56
|
+
"""
|
|
57
|
+
Return ChangeContext attributes in dictionary format
|
|
58
|
+
"""
|
|
59
|
+
context = {
|
|
60
|
+
"user": self.get_user(instance),
|
|
61
|
+
"change_id": self.change_id,
|
|
62
|
+
"context": self.context,
|
|
63
|
+
}
|
|
64
|
+
return context
|
|
54
65
|
|
|
55
66
|
|
|
56
67
|
class JobChangeContext(ChangeContext):
|
|
@@ -8,8 +8,9 @@ from nautobot.core.filters import (
|
|
|
8
8
|
MultiValueNumberFilter,
|
|
9
9
|
)
|
|
10
10
|
from nautobot.core.forms import NullableDateField
|
|
11
|
-
from nautobot.core.
|
|
11
|
+
from nautobot.core.utils.data import is_uuid
|
|
12
12
|
from nautobot.extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices
|
|
13
|
+
from nautobot.extras.models import CustomFieldChoice
|
|
13
14
|
|
|
14
15
|
EXACT_FILTER_TYPES = (
|
|
15
16
|
CustomFieldTypeChoices.TYPE_BOOLEAN,
|
|
@@ -71,19 +72,23 @@ class CustomFieldJSONFilter(CustomFieldFilterMixin, django_filters.Filter):
|
|
|
71
72
|
"""Custom field single value filter for backwards compatibility"""
|
|
72
73
|
|
|
73
74
|
|
|
74
|
-
class
|
|
75
|
-
"""
|
|
75
|
+
class CustomFieldSelectFilter(CustomFieldFilterMixin, MultiValueCharFilter):
|
|
76
|
+
"""Filter for custom fields of type TYPE_SELECT."""
|
|
76
77
|
|
|
77
|
-
def
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
def get_filter_predicate(self, v):
|
|
79
|
+
if is_uuid(v):
|
|
80
|
+
try:
|
|
81
|
+
v = self.custom_field.custom_field_choices.get(pk=v).value
|
|
82
|
+
except CustomFieldChoice.DoesNotExist:
|
|
83
|
+
v = ""
|
|
84
|
+
return super().get_filter_predicate(v)
|
|
80
85
|
|
|
81
86
|
|
|
82
|
-
class
|
|
83
|
-
"""
|
|
87
|
+
class CustomFieldMultiSelectFilter(CustomFieldSelectFilter):
|
|
88
|
+
"""Filter for custom fields of type TYPE_MULTISELECT."""
|
|
84
89
|
|
|
85
90
|
def __init__(self, *args, **kwargs):
|
|
86
|
-
|
|
91
|
+
kwargs.setdefault("lookup_expr", "contains")
|
|
87
92
|
super().__init__(*args, **kwargs)
|
|
88
93
|
|
|
89
94
|
|
|
@@ -27,6 +27,7 @@ from nautobot.extras.filters.customfields import (
|
|
|
27
27
|
CustomFieldMultiValueDateFilter,
|
|
28
28
|
CustomFieldMultiValueNumberFilter,
|
|
29
29
|
CustomFieldNumberFilter,
|
|
30
|
+
CustomFieldSelectFilter,
|
|
30
31
|
)
|
|
31
32
|
from nautobot.extras.models import (
|
|
32
33
|
ConfigContextSchema,
|
|
@@ -61,12 +62,16 @@ class CustomFieldModelFilterSetMixin(django_filters.FilterSet):
|
|
|
61
62
|
super().__init__(*args, **kwargs)
|
|
62
63
|
|
|
63
64
|
custom_field_filter_classes = {
|
|
65
|
+
# Here, for the "base" filters for each custom field, for backwards compatibility, use single-value filters.
|
|
66
|
+
# For the "extended" filters, see below, we use multi-value filters.
|
|
67
|
+
# 3.0 TODO: switch the "base" filters to multi-value filters as well.
|
|
64
68
|
CustomFieldTypeChoices.TYPE_DATE: CustomFieldDateFilter,
|
|
65
69
|
CustomFieldTypeChoices.TYPE_BOOLEAN: CustomFieldBooleanFilter,
|
|
66
70
|
CustomFieldTypeChoices.TYPE_INTEGER: CustomFieldNumberFilter,
|
|
67
71
|
CustomFieldTypeChoices.TYPE_JSON: CustomFieldJSONFilter,
|
|
72
|
+
# The below are multi-value filters already:
|
|
68
73
|
CustomFieldTypeChoices.TYPE_MULTISELECT: CustomFieldMultiSelectFilter,
|
|
69
|
-
CustomFieldTypeChoices.TYPE_SELECT:
|
|
74
|
+
CustomFieldTypeChoices.TYPE_SELECT: CustomFieldSelectFilter,
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
custom_fields = CustomField.objects.get_for_model(self._meta.model, exclude_filter_disabled=True)
|
nautobot/extras/health_checks.py
CHANGED
nautobot/extras/jobs.py
CHANGED
nautobot/extras/managers.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from celery import states
|
|
2
2
|
from django.utils import timezone
|
|
3
|
-
from django_celery_beat.managers import ExtendedManager
|
|
4
3
|
from django_celery_results.managers import TaskResultManager, transaction_retry
|
|
5
4
|
|
|
6
5
|
from nautobot.core.models import BaseManager
|
|
@@ -136,5 +135,5 @@ class JobResultManager(BaseManager.from_queryset(RestrictedQuerySet), TaskResult
|
|
|
136
135
|
return obj
|
|
137
136
|
|
|
138
137
|
|
|
139
|
-
class ScheduledJobsManager(BaseManager.from_queryset(RestrictedQuerySet)
|
|
138
|
+
class ScheduledJobsManager(BaseManager.from_queryset(RestrictedQuerySet)):
|
|
140
139
|
pass
|
|
@@ -724,7 +724,16 @@ class CustomField(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
724
724
|
|
|
725
725
|
super().delete(*args, **kwargs)
|
|
726
726
|
|
|
727
|
-
|
|
727
|
+
# Circular Import
|
|
728
|
+
from nautobot.extras.signals import change_context_state
|
|
729
|
+
|
|
730
|
+
change_context = change_context_state.get()
|
|
731
|
+
if change_context is None:
|
|
732
|
+
context = None
|
|
733
|
+
else:
|
|
734
|
+
context = change_context.as_dict(instance=self)
|
|
735
|
+
context["context_detail"] = "delete custom field data"
|
|
736
|
+
delete_custom_field_data.delay(self.key, content_types, context)
|
|
728
737
|
|
|
729
738
|
def add_prefix_to_cf_key(self):
|
|
730
739
|
return "cf_" + str(self.key)
|
|
@@ -783,8 +792,22 @@ class CustomFieldChoice(BaseModel, ChangeLoggedModel):
|
|
|
783
792
|
super().save(*args, **kwargs)
|
|
784
793
|
|
|
785
794
|
if self.value != database_object.value:
|
|
795
|
+
# Circular Import
|
|
796
|
+
from nautobot.extras.signals import change_context_state
|
|
797
|
+
|
|
798
|
+
change_context = change_context_state.get()
|
|
799
|
+
if change_context is None:
|
|
800
|
+
context = None
|
|
801
|
+
else:
|
|
802
|
+
context = change_context.as_dict(instance=self)
|
|
803
|
+
context["context_detail"] = "update custom field choice data"
|
|
786
804
|
transaction.on_commit(
|
|
787
|
-
lambda: update_custom_field_choice_data.delay(
|
|
805
|
+
lambda: update_custom_field_choice_data.delay(
|
|
806
|
+
self.custom_field.pk,
|
|
807
|
+
database_object.value,
|
|
808
|
+
self.value,
|
|
809
|
+
context,
|
|
810
|
+
)
|
|
788
811
|
)
|
|
789
812
|
|
|
790
813
|
def delete(self, *args, **kwargs):
|
nautobot/extras/models/mixins.py
CHANGED
|
@@ -4,6 +4,7 @@ from importlib import import_module
|
|
|
4
4
|
import inspect
|
|
5
5
|
from logging import getLogger
|
|
6
6
|
|
|
7
|
+
from django.conf import settings
|
|
7
8
|
from django.core.exceptions import ValidationError
|
|
8
9
|
from django.template.loader import get_template
|
|
9
10
|
from django.urls import get_resolver, URLPattern
|
|
@@ -147,7 +148,7 @@ class NautobotAppConfig(NautobotConfig):
|
|
|
147
148
|
|
|
148
149
|
# Import metrics (if present)
|
|
149
150
|
metrics = import_object(f"{self.__module__}.{self.metrics}")
|
|
150
|
-
if metrics is not None:
|
|
151
|
+
if metrics is not None and self.name not in settings.METRICS_DISABLED_APPS:
|
|
151
152
|
register_metrics(metrics)
|
|
152
153
|
self.features["metrics"] = [] # Initialize as empty, to be filled by the signal handler
|
|
153
154
|
# Inject the metrics to discover into the signal handler.
|
nautobot/extras/querysets.py
CHANGED
|
@@ -3,7 +3,6 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
3
3
|
from django.core.cache import cache
|
|
4
4
|
from django.db.models import F, Model, OuterRef, Q, Subquery
|
|
5
5
|
from django.db.models.functions import JSONObject
|
|
6
|
-
from django_celery_beat.managers import ExtendedQuerySet
|
|
7
6
|
|
|
8
7
|
from nautobot.core.models.query_functions import EmptyGroupByJSONBAgg
|
|
9
8
|
from nautobot.core.models.querysets import RestrictedQuerySet
|
|
@@ -272,7 +271,7 @@ class JobQuerySet(RestrictedQuerySet):
|
|
|
272
271
|
)
|
|
273
272
|
|
|
274
273
|
|
|
275
|
-
class ScheduledJobExtendedQuerySet(RestrictedQuerySet
|
|
274
|
+
class ScheduledJobExtendedQuerySet(RestrictedQuerySet):
|
|
276
275
|
"""
|
|
277
276
|
Base queryset used for the ScheduledJob class
|
|
278
277
|
"""
|
nautobot/extras/signals.py
CHANGED
|
@@ -52,7 +52,7 @@ logger = logging.getLogger(__name__)
|
|
|
52
52
|
#
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
def
|
|
55
|
+
def get_user_if_authenticated(user, instance):
|
|
56
56
|
"""Return the user object associated with the request if the user is defined.
|
|
57
57
|
|
|
58
58
|
If the user is not defined, log a warning to indicate that the user couldn't be retrived from the request
|
|
@@ -119,7 +119,7 @@ def _handle_changed_object(sender, instance, raw=False, **kwargs):
|
|
|
119
119
|
|
|
120
120
|
# Record an ObjectChange if applicable
|
|
121
121
|
if hasattr(instance, "to_objectchange"):
|
|
122
|
-
user =
|
|
122
|
+
user = change_context_state.get().get_user(instance)
|
|
123
123
|
# save a copy of this instance's field cache so it can be restored after serialization
|
|
124
124
|
# to prevent unexpected behavior when chaining multiple signal handlers
|
|
125
125
|
original_cache = instance._state.fields_cache.copy()
|
|
@@ -186,7 +186,7 @@ def _handle_deleted_object(sender, instance, **kwargs):
|
|
|
186
186
|
|
|
187
187
|
# Record an ObjectChange if applicable
|
|
188
188
|
if hasattr(instance, "to_objectchange"):
|
|
189
|
-
user =
|
|
189
|
+
user = change_context_state.get().get_user(instance)
|
|
190
190
|
|
|
191
191
|
# save a copy of this instance's field cache so it can be restored after serialization
|
|
192
192
|
# to prevent unexpected behavior when chaining multiple signal handlers
|
|
@@ -238,13 +238,23 @@ def handle_cf_removed_obj_types(instance, action, pk_set, **kwargs):
|
|
|
238
238
|
"""
|
|
239
239
|
Handle the cleanup of old custom field data when a CustomField is removed from one or more ContentTypes.
|
|
240
240
|
"""
|
|
241
|
+
|
|
242
|
+
change_context = change_context_state.get()
|
|
243
|
+
if change_context is None:
|
|
244
|
+
context = None
|
|
245
|
+
else:
|
|
246
|
+
context = change_context.as_dict(instance=instance)
|
|
241
247
|
if action == "post_remove":
|
|
242
248
|
# Existing content types have been removed from the custom field, delete their data
|
|
243
|
-
|
|
249
|
+
if context:
|
|
250
|
+
context["context_detail"] = "delete custom field data from existing content types"
|
|
251
|
+
transaction.on_commit(lambda: delete_custom_field_data.delay(instance.key, pk_set, context))
|
|
244
252
|
|
|
245
253
|
elif action == "post_add":
|
|
246
254
|
# New content types have been added to the custom field, provision them
|
|
247
|
-
|
|
255
|
+
if context:
|
|
256
|
+
context["context_detail"] = "provision custom field data for new content types"
|
|
257
|
+
transaction.on_commit(lambda: provision_field.delay(instance.pk, pk_set, context))
|
|
248
258
|
|
|
249
259
|
|
|
250
260
|
m2m_changed.connect(handle_cf_removed_obj_types, sender=CustomField.content_types.through)
|