nautobot 2.3.10__py3-none-any.whl → 2.3.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/utils.py +2 -0
- nautobot/cloud/tables.py +1 -0
- nautobot/core/forms/forms.py +5 -1
- nautobot/core/settings.py +26 -0
- nautobot/core/settings.yaml +31 -0
- nautobot/core/tables.py +88 -22
- nautobot/core/templates/generic/object_bulk_destroy.html +12 -3
- nautobot/core/templates/generic/object_bulk_update.html +4 -2
- nautobot/core/templates/generic/object_create.html +1 -1
- nautobot/core/templates/generic/object_notes.html +1 -1
- nautobot/core/templates/generic/object_retrieve.html +1 -1
- nautobot/core/templates/rest_framework/api.html +3 -0
- nautobot/core/testing/api.py +3 -1
- nautobot/core/testing/integration.py +64 -0
- nautobot/core/testing/views.py +48 -31
- nautobot/core/tests/integration/test_app_navbar.py +3 -3
- nautobot/core/tests/integration/test_navbar.py +1 -1
- nautobot/core/tests/test_csv.py +3 -0
- nautobot/core/tests/test_utils.py +25 -5
- nautobot/core/utils/lookup.py +35 -0
- nautobot/core/views/generic.py +50 -39
- nautobot/core/views/mixins.py +97 -43
- nautobot/core/views/renderers.py +8 -5
- nautobot/dcim/choices.py +6 -0
- nautobot/dcim/tables/devices.py +5 -6
- nautobot/dcim/templates/dcim/controller_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/device/base.html +1 -1
- nautobot/dcim/templates/dcim/device_component_add.html +8 -8
- nautobot/dcim/templates/dcim/virtualchassis_add_member.html +2 -2
- nautobot/dcim/templates/dcim/virtualchassis_edit.html +2 -2
- nautobot/dcim/tests/integration/test_create_device.py +86 -0
- nautobot/extras/group_sync.py +42 -0
- nautobot/extras/models/metadata.py +1 -0
- nautobot/extras/models/models.py +1 -1
- nautobot/extras/plugins/__init__.py +2 -1
- nautobot/extras/tables.py +1 -0
- nautobot/extras/templates/extras/inc/job_table.html +1 -1
- nautobot/extras/tests/test_relationships.py +1 -0
- nautobot/extras/tests/test_views.py +0 -2
- nautobot/extras/views.py +1 -2
- nautobot/ipam/factory.py +3 -0
- nautobot/ipam/filters.py +5 -0
- nautobot/ipam/forms.py +17 -0
- nautobot/ipam/models.py +2 -1
- nautobot/ipam/signals.py +2 -2
- nautobot/ipam/tables.py +6 -13
- nautobot/ipam/templates/ipam/ipaddress_assign.html +2 -2
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +1 -1
- nautobot/ipam/tests/test_models.py +113 -1
- nautobot/ipam/tests/test_views.py +39 -5
- nautobot/project-static/docs/404.html +10 -10
- nautobot/project-static/docs/additional-features/caching.html +1 -2
- nautobot/project-static/docs/additional-features/change-logging.html +1 -2
- nautobot/project-static/docs/additional-features/config-contexts.html +1 -2
- nautobot/project-static/docs/additional-features/healthcheck.html +1 -2
- nautobot/project-static/docs/additional-features/jobs.html +1 -2
- nautobot/project-static/docs/additional-features/prometheus-metrics.html +1 -2
- nautobot/project-static/docs/administration/celery-queues.html +1 -2
- nautobot/project-static/docs/administration/nautobot-server.html +1 -2
- nautobot/project-static/docs/administration/nautobot-shell.html +1 -2
- nautobot/project-static/docs/administration/permissions.html +1 -2
- nautobot/project-static/docs/administration/replicating-nautobot.html +1 -2
- nautobot/project-static/docs/apps/index.html +10 -10
- nautobot/project-static/docs/apps/migrating-jobs-from-nautobot-v1.html +1 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +10 -10
- nautobot/project-static/docs/assets/stylesheets/main.6f8fc17f.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.6f8fc17f.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +141 -16
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +185 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +10 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +104 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +14 -14
- nautobot/project-static/docs/configuration/authentication/ldap.html +1 -2
- nautobot/project-static/docs/configuration/authentication/remote.html +1 -2
- nautobot/project-static/docs/configuration/authentication/sso.html +1 -2
- nautobot/project-static/docs/configuration/index.html +1 -2
- nautobot/project-static/docs/configuration/optional-settings.html +1 -2
- nautobot/project-static/docs/configuration/required-settings.html +1 -2
- nautobot/project-static/docs/core-functionality/circuits.html +1 -2
- nautobot/project-static/docs/core-functionality/device-types.html +1 -2
- nautobot/project-static/docs/core-functionality/devices.html +1 -2
- nautobot/project-static/docs/core-functionality/ipam.html +1 -2
- nautobot/project-static/docs/core-functionality/power.html +1 -2
- nautobot/project-static/docs/core-functionality/secrets.html +1 -2
- nautobot/project-static/docs/core-functionality/services.html +1 -2
- nautobot/project-static/docs/core-functionality/sites-and-racks.html +1 -2
- nautobot/project-static/docs/core-functionality/tenancy.html +1 -2
- nautobot/project-static/docs/core-functionality/virtualization.html +1 -2
- nautobot/project-static/docs/core-functionality/vlans.html +1 -2
- nautobot/project-static/docs/development/application-registry.html +1 -2
- nautobot/project-static/docs/development/apps/api/configuration-view.html +10 -10
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +10 -10
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +10 -10
- nautobot/project-static/docs/development/apps/api/models/global-search.html +10 -10
- nautobot/project-static/docs/development/apps/api/models/graphql.html +10 -10
- nautobot/project-static/docs/development/apps/api/models/index.html +10 -10
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +10 -10
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +10 -10
- nautobot/project-static/docs/development/apps/api/prometheus.html +10 -10
- nautobot/project-static/docs/development/apps/api/setup.html +10 -10
- nautobot/project-static/docs/development/apps/api/testing.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +1 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +10 -10
- nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +1 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/index.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/notes.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/urls.html +10 -10
- nautobot/project-static/docs/development/apps/api/views/view-overrides.html +1 -2
- nautobot/project-static/docs/development/apps/index.html +10 -10
- nautobot/project-static/docs/development/apps/migration/code-updates.html +10 -10
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +10 -10
- nautobot/project-static/docs/development/apps/migration/from-v1.html +10 -10
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +10 -10
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +10 -10
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +10 -10
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +10 -10
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +10 -10
- nautobot/project-static/docs/development/best-practices.html +1 -2
- nautobot/project-static/docs/development/core/application-registry.html +10 -10
- nautobot/project-static/docs/development/core/best-practices.html +10 -10
- nautobot/project-static/docs/development/core/bootstrap-ui.html +10 -10
- nautobot/project-static/docs/development/core/caching.html +10 -10
- nautobot/project-static/docs/development/core/controllers.html +10 -10
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +10 -10
- nautobot/project-static/docs/development/core/extending-models.html +1 -2
- nautobot/project-static/docs/development/core/generic-views.html +10 -10
- nautobot/project-static/docs/development/core/getting-started.html +10 -10
- nautobot/project-static/docs/development/core/homepage.html +10 -10
- nautobot/project-static/docs/development/core/index.html +10 -10
- nautobot/project-static/docs/development/core/model-checklist.html +10 -10
- nautobot/project-static/docs/development/core/model-features.html +10 -10
- nautobot/project-static/docs/development/core/natural-keys.html +10 -10
- nautobot/project-static/docs/development/core/navigation-menu.html +10 -10
- nautobot/project-static/docs/development/core/react-ui.html +1 -2
- nautobot/project-static/docs/development/core/release-checklist.html +10 -10
- nautobot/project-static/docs/development/core/role-internals.html +10 -10
- nautobot/project-static/docs/development/core/settings.html +10 -10
- nautobot/project-static/docs/development/core/style-guide.html +10 -10
- nautobot/project-static/docs/development/core/templates.html +10 -10
- nautobot/project-static/docs/development/core/testing.html +12 -12
- nautobot/project-static/docs/development/core/user-preferences.html +10 -10
- nautobot/project-static/docs/development/docker-compose-advanced-use-cases.html +1 -2
- nautobot/project-static/docs/development/extending-models.html +1 -2
- nautobot/project-static/docs/development/generic-views.html +1 -2
- nautobot/project-static/docs/development/getting-started.html +1 -2
- nautobot/project-static/docs/development/homepage.html +1 -2
- nautobot/project-static/docs/development/index.html +10 -10
- nautobot/project-static/docs/development/jobs/index.html +10 -10
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +10 -10
- nautobot/project-static/docs/development/model-features.html +1 -2
- nautobot/project-static/docs/development/natural-keys.html +1 -2
- nautobot/project-static/docs/development/navigation-menu.html +1 -2
- nautobot/project-static/docs/development/react-ui.html +1 -2
- nautobot/project-static/docs/development/release-checklist.html +1 -2
- nautobot/project-static/docs/development/role-internals.html +1 -2
- nautobot/project-static/docs/development/style-guide.html +1 -2
- nautobot/project-static/docs/development/templates.html +1 -2
- nautobot/project-static/docs/development/testing.html +1 -2
- nautobot/project-static/docs/development/user-preferences.html +1 -2
- nautobot/project-static/docs/docker/index.html +1 -2
- nautobot/project-static/docs/index.html +10 -10
- nautobot/project-static/docs/installation/centos.html +1 -2
- nautobot/project-static/docs/installation/external-authentication.html +1 -2
- nautobot/project-static/docs/installation/http-server.html +1 -2
- nautobot/project-static/docs/installation/index.html +1 -2
- nautobot/project-static/docs/installation/migrating-from-netbox.html +1 -2
- nautobot/project-static/docs/installation/migrating-from-postgresql.html +1 -2
- nautobot/project-static/docs/installation/nautobot.html +1 -2
- nautobot/project-static/docs/installation/region-and-site-data-migration-guide.html +1 -2
- nautobot/project-static/docs/installation/selinux-troubleshooting.html +1 -2
- nautobot/project-static/docs/installation/services.html +1 -2
- nautobot/project-static/docs/installation/ubuntu.html +1 -2
- nautobot/project-static/docs/installation/upgrading-from-nautobot-v1.html +1 -2
- nautobot/project-static/docs/installation/upgrading.html +1 -2
- nautobot/project-static/docs/models/circuits/circuit.html +1 -2
- nautobot/project-static/docs/models/circuits/circuittermination.html +1 -2
- nautobot/project-static/docs/models/circuits/circuittype.html +1 -2
- nautobot/project-static/docs/models/circuits/provider.html +1 -2
- nautobot/project-static/docs/models/circuits/providernetwork.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudaccount.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudnetwork.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudnetworkprefixassignment.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudresourcetype.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudservice.html +1 -2
- nautobot/project-static/docs/models/cloud/cloudservicenetworkassignment.html +1 -2
- nautobot/project-static/docs/models/dcim/cable.html +1 -2
- nautobot/project-static/docs/models/dcim/consoleport.html +1 -2
- nautobot/project-static/docs/models/dcim/consoleporttemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/consoleserverport.html +1 -2
- nautobot/project-static/docs/models/dcim/consoleserverporttemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/controller.html +1 -2
- nautobot/project-static/docs/models/dcim/controllermanageddevicegroup.html +1 -2
- nautobot/project-static/docs/models/dcim/device.html +1 -2
- nautobot/project-static/docs/models/dcim/devicebay.html +1 -2
- nautobot/project-static/docs/models/dcim/devicebaytemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/devicefamily.html +1 -2
- nautobot/project-static/docs/models/dcim/deviceredundancygroup.html +1 -2
- nautobot/project-static/docs/models/dcim/devicetype.html +1 -2
- nautobot/project-static/docs/models/dcim/frontport.html +1 -2
- nautobot/project-static/docs/models/dcim/frontporttemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/interface.html +1 -2
- nautobot/project-static/docs/models/dcim/interfacetemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/inventoryitem.html +1 -2
- nautobot/project-static/docs/models/dcim/location.html +1 -2
- nautobot/project-static/docs/models/dcim/locationtype.html +1 -2
- nautobot/project-static/docs/models/dcim/manufacturer.html +1 -2
- nautobot/project-static/docs/models/dcim/module.html +1 -2
- nautobot/project-static/docs/models/dcim/modulebay.html +1 -2
- nautobot/project-static/docs/models/dcim/modulebaytemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/moduletype.html +1 -2
- nautobot/project-static/docs/models/dcim/platform.html +1 -2
- nautobot/project-static/docs/models/dcim/powerfeed.html +1 -2
- nautobot/project-static/docs/models/dcim/poweroutlet.html +1 -2
- nautobot/project-static/docs/models/dcim/poweroutlettemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/powerpanel.html +1 -2
- nautobot/project-static/docs/models/dcim/powerport.html +1 -2
- nautobot/project-static/docs/models/dcim/powerporttemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/rack.html +1 -2
- nautobot/project-static/docs/models/dcim/rackgroup.html +1 -2
- nautobot/project-static/docs/models/dcim/rackreservation.html +1 -2
- nautobot/project-static/docs/models/dcim/rearport.html +1 -2
- nautobot/project-static/docs/models/dcim/rearporttemplate.html +1 -2
- nautobot/project-static/docs/models/dcim/softwareimagefile.html +1 -2
- nautobot/project-static/docs/models/dcim/softwareversion.html +1 -2
- nautobot/project-static/docs/models/dcim/virtualchassis.html +1 -2
- nautobot/project-static/docs/models/extras/computedfield.html +1 -2
- nautobot/project-static/docs/models/extras/configcontext.html +1 -2
- nautobot/project-static/docs/models/extras/configcontextschema.html +1 -2
- nautobot/project-static/docs/models/extras/contact.html +1 -2
- nautobot/project-static/docs/models/extras/customfield.html +1 -2
- nautobot/project-static/docs/models/extras/customlink.html +1 -2
- nautobot/project-static/docs/models/extras/dynamicgroup.html +1 -2
- nautobot/project-static/docs/models/extras/exporttemplate.html +1 -2
- nautobot/project-static/docs/models/extras/gitrepository.html +1 -2
- nautobot/project-static/docs/models/extras/jobhook.html +1 -2
- nautobot/project-static/docs/models/extras/joblogentry.html +1 -2
- nautobot/project-static/docs/models/extras/jobresult.html +1 -2
- nautobot/project-static/docs/models/extras/metadatachoice.html +1 -2
- nautobot/project-static/docs/models/extras/metadatatype.html +1 -2
- nautobot/project-static/docs/models/extras/objectmetadata.html +1 -2
- nautobot/project-static/docs/models/extras/role.html +1 -2
- nautobot/project-static/docs/models/extras/savedview.html +1 -2
- nautobot/project-static/docs/models/extras/secret.html +1 -2
- nautobot/project-static/docs/models/extras/secretsgroup.html +1 -2
- nautobot/project-static/docs/models/extras/staticgroupassociation.html +1 -2
- nautobot/project-static/docs/models/extras/status.html +1 -2
- nautobot/project-static/docs/models/extras/team.html +1 -2
- nautobot/project-static/docs/models/ipam/ipaddress.html +1 -2
- nautobot/project-static/docs/models/ipam/prefix.html +1 -2
- nautobot/project-static/docs/models/ipam/rir.html +1 -2
- nautobot/project-static/docs/models/ipam/routetarget.html +1 -2
- nautobot/project-static/docs/models/ipam/service.html +1 -2
- nautobot/project-static/docs/models/ipam/vlan.html +1 -2
- nautobot/project-static/docs/models/ipam/vlangroup.html +1 -2
- nautobot/project-static/docs/models/ipam/vrf.html +1 -2
- nautobot/project-static/docs/models/tenancy/tenant.html +1 -2
- nautobot/project-static/docs/models/tenancy/tenantgroup.html +1 -2
- nautobot/project-static/docs/models/virtualization/cluster.html +1 -2
- nautobot/project-static/docs/models/virtualization/clustergroup.html +1 -2
- nautobot/project-static/docs/models/virtualization/clustertype.html +1 -2
- nautobot/project-static/docs/models/virtualization/virtualmachine.html +1 -2
- nautobot/project-static/docs/models/virtualization/vminterface.html +1 -2
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +10 -10
- nautobot/project-static/docs/overview/design_philosophy.html +10 -10
- nautobot/project-static/docs/overview/index.html +1 -2
- nautobot/project-static/docs/plugins/development.html +1 -2
- nautobot/project-static/docs/plugins/index.html +1 -2
- nautobot/project-static/docs/plugins/porting-from-netbox.html +1 -2
- nautobot/project-static/docs/release-notes/index.html +15 -15
- nautobot/project-static/docs/release-notes/version-1.0.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.1.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.2.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.3.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.4.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.5.html +10 -10
- nautobot/project-static/docs/release-notes/version-1.6.html +10 -10
- nautobot/project-static/docs/release-notes/version-2.0.html +10 -10
- nautobot/project-static/docs/release-notes/version-2.1.html +10 -10
- nautobot/project-static/docs/release-notes/version-2.2.html +10 -10
- nautobot/project-static/docs/release-notes/version-2.3.html +491 -182
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/rest-api/overview.html +1 -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 +10 -10
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +10 -10
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +65 -12
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +10 -10
- nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +1 -2
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +1 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +10 -10
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +1 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +122 -10
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +1 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +1 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +49 -10
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +10 -10
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +1 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +1 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/index.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +1 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +10 -10
- nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +1 -2
- nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +1 -2
- nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +1 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +10 -10
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +10 -10
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +10 -10
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +10 -10
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +10 -10
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +10 -10
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +10 -10
- nautobot/project-static/docs/user-guide/index.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +10 -10
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +10 -10
- nautobot/project-static/docs/user-guides/custom-fields.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/creating-devices.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/index.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/interfaces.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/ipam.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/platforms.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/search-bar.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/tenants.html +1 -2
- nautobot/project-static/docs/user-guides/getting-started/vlans-and-vlan-groups.html +1 -2
- nautobot/project-static/docs/user-guides/git-data-source.html +1 -2
- nautobot/project-static/docs/user-guides/graphql.html +1 -2
- nautobot/project-static/docs/user-guides/ip-address-merge-tool.html +1 -2
- nautobot/project-static/docs/user-guides/relationships.html +1 -2
- nautobot/project-static/docs/user-guides/s3-django-storage.html +1 -2
- nautobot/project-static/js/forms.js +10 -0
- nautobot/virtualization/forms.py +24 -0
- nautobot/virtualization/templates/virtualization/vminterface.html +4 -0
- nautobot/virtualization/templates/virtualization/vminterface_edit.html +1 -0
- nautobot/virtualization/tests/test_views.py +7 -2
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/METADATA +2 -2
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/RECORD +522 -520
- nautobot/project-static/docs/assets/stylesheets/main.0253249f.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.0253249f.min.css.map +0 -1
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/NOTICE +0 -0
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/WHEEL +0 -0
- {nautobot-2.3.10.dist-info → nautobot-2.3.12.dist-info}/entry_points.txt +0 -0
nautobot/apps/utils.py
CHANGED
|
@@ -30,6 +30,7 @@ from nautobot.core.utils.lookup import (
|
|
|
30
30
|
get_form_for_model,
|
|
31
31
|
get_model_from_name,
|
|
32
32
|
get_related_class_for_model,
|
|
33
|
+
get_related_field_for_models,
|
|
33
34
|
get_route_for_model,
|
|
34
35
|
get_table_for_model,
|
|
35
36
|
get_url_for_url_pattern,
|
|
@@ -111,6 +112,7 @@ __all__ = (
|
|
|
111
112
|
"get_only_new_ui_ready_routes",
|
|
112
113
|
"get_permission_for_model",
|
|
113
114
|
"get_related_class_for_model",
|
|
115
|
+
"get_related_field_for_models",
|
|
114
116
|
"get_route_for_model",
|
|
115
117
|
"get_settings_or_config",
|
|
116
118
|
"get_table_for_model",
|
nautobot/cloud/tables.py
CHANGED
|
@@ -55,6 +55,7 @@ class CloudNetworkTable(BaseTable):
|
|
|
55
55
|
circuit_count = LinkedCountColumn(
|
|
56
56
|
viewname="circuits:circuit_list",
|
|
57
57
|
url_params={"cloud_network": "name"},
|
|
58
|
+
# lookup="circuit_terminations__circuit", # TODO: not currently supported
|
|
58
59
|
verbose_name="Circuits",
|
|
59
60
|
reverse_lookup="circuit_terminations__cloud_network",
|
|
60
61
|
)
|
nautobot/core/forms/forms.py
CHANGED
|
@@ -113,7 +113,7 @@ class BulkEditForm(forms.Form):
|
|
|
113
113
|
a more powerful subclass and should be used instead of directly inheriting from this class.
|
|
114
114
|
"""
|
|
115
115
|
|
|
116
|
-
def __init__(self, model, *args, **kwargs):
|
|
116
|
+
def __init__(self, model, *args, edit_all=False, **kwargs):
|
|
117
117
|
super().__init__(*args, **kwargs)
|
|
118
118
|
self.model = model
|
|
119
119
|
self.nullable_fields = []
|
|
@@ -122,6 +122,10 @@ class BulkEditForm(forms.Form):
|
|
|
122
122
|
if hasattr(self.Meta, "nullable_fields"):
|
|
123
123
|
self.nullable_fields = self.Meta.nullable_fields
|
|
124
124
|
|
|
125
|
+
if edit_all:
|
|
126
|
+
self.fields["pk"].required = False
|
|
127
|
+
self.fields["_all"] = forms.BooleanField(widget=forms.HiddenInput(), required=True, initial=True)
|
|
128
|
+
|
|
125
129
|
|
|
126
130
|
class BulkRenameForm(forms.Form):
|
|
127
131
|
"""
|
nautobot/core/settings.py
CHANGED
|
@@ -212,6 +212,32 @@ SOCIAL_AUTH_POSTGRES_JSONFIELD = False
|
|
|
212
212
|
# Nautobot related - May be overridden if using custom social auth backend
|
|
213
213
|
SOCIAL_AUTH_BACKEND_PREFIX = "social_core.backends"
|
|
214
214
|
|
|
215
|
+
# Enables adding the OAuth2/OIDC group sync module to the authentication pipeline
|
|
216
|
+
SSO_ENABLE_GROUP_SYNC = is_truthy(os.getenv("NAUTOBOT_SSO_ENABLE_GROUP_SYNC", "false"))
|
|
217
|
+
if SSO_ENABLE_GROUP_SYNC:
|
|
218
|
+
SOCIAL_AUTH_PIPELINE = (
|
|
219
|
+
"social_core.pipeline.social_auth.social_details",
|
|
220
|
+
"social_core.pipeline.social_auth.social_uid",
|
|
221
|
+
"social_core.pipeline.social_auth.auth_allowed",
|
|
222
|
+
"social_core.pipeline.social_auth.social_user",
|
|
223
|
+
"social_core.pipeline.user.get_username",
|
|
224
|
+
"social_core.pipeline.user.create_user",
|
|
225
|
+
"social_core.pipeline.social_auth.associate_user",
|
|
226
|
+
"social_core.pipeline.social_auth.load_extra_data",
|
|
227
|
+
"social_core.pipeline.user.user_details",
|
|
228
|
+
"nautobot.extras.group_sync",
|
|
229
|
+
)
|
|
230
|
+
# OAuth2/OIDC claim where the list of groups the authenticating user is a part of
|
|
231
|
+
SSO_CLAIMS_GROUP = os.getenv("NAUTOBOT_SSO_CLAIMS_GROUP", "groups")
|
|
232
|
+
# list of groups that an authenticating user can be a part of to get the Django staff permission
|
|
233
|
+
SSO_STAFF_GROUPS = [
|
|
234
|
+
group for group in os.getenv("NAUTOBOT_SSO_STAFF_GROUPS", "").split(_CONFIG_SETTING_SEPARATOR) if group != ""
|
|
235
|
+
]
|
|
236
|
+
# list of groups that an authenticating user can be a part of to be a Django super user
|
|
237
|
+
SSO_SUPERUSER_GROUPS = [
|
|
238
|
+
group for group in os.getenv("NAUTOBOT_SSO_SUPERUSER_GROUPS", "").split(_CONFIG_SETTING_SEPARATOR) if group != ""
|
|
239
|
+
]
|
|
240
|
+
|
|
215
241
|
# Job log entry sanitization and similar
|
|
216
242
|
SANITIZER_PATTERNS = [
|
|
217
243
|
# General removal of username-like and password-like tokens
|
nautobot/core/settings.yaml
CHANGED
|
@@ -1705,6 +1705,37 @@ properties:
|
|
|
1705
1705
|
"Single Sign On": "./authentication/sso.md"
|
|
1706
1706
|
"`social-auth-app-django`": "https://python-social-auth.readthedocs.io/en/latest/configuration/django.html"
|
|
1707
1707
|
type: "string"
|
|
1708
|
+
SSO_CLAIMS_GROUP:
|
|
1709
|
+
default: "groups"
|
|
1710
|
+
description: "OAuth2/OIDC claim which will contain the groups which the authenticated user is a member of."
|
|
1711
|
+
environment_variable: "NAUTOBOT_SSO_CLAIMS_GROUP"
|
|
1712
|
+
see_also:
|
|
1713
|
+
"Single Sign On": "./authentication/sso.md"
|
|
1714
|
+
SSO_ENABLE_GROUP_SYNC:
|
|
1715
|
+
default: false
|
|
1716
|
+
type: "boolean"
|
|
1717
|
+
description: "Enables the group syncing authentication module."
|
|
1718
|
+
environment_variable: "NAUTOBOT_SSO_ENABLE_GROUP_SYNC"
|
|
1719
|
+
see_also:
|
|
1720
|
+
"Single Sign On": "./authentication/sso.md"
|
|
1721
|
+
SSO_STAFF_GROUPS:
|
|
1722
|
+
default: []
|
|
1723
|
+
description: "List of groups that a user can be a member of to get the Django Staff permission."
|
|
1724
|
+
environment_variable: "NAUTOBOT_SSO_STAFF_GROUPS"
|
|
1725
|
+
see_also:
|
|
1726
|
+
"Single Sign On": "./authentication/sso.md"
|
|
1727
|
+
items:
|
|
1728
|
+
type: "string"
|
|
1729
|
+
type: "array"
|
|
1730
|
+
SSO_SUPERUSER_GROUPS:
|
|
1731
|
+
default: []
|
|
1732
|
+
description: "List of groups that a user can be a member of to be a Django Super User."
|
|
1733
|
+
environment_variable: "NAUTOBOT_SSO_SUPERUSER_GROUPS"
|
|
1734
|
+
see_also:
|
|
1735
|
+
"Single Sign On": "./authentication/sso.md"
|
|
1736
|
+
items:
|
|
1737
|
+
type: "string"
|
|
1738
|
+
type: "array"
|
|
1708
1739
|
STATIC_ROOT:
|
|
1709
1740
|
"$ref": "#/definitions/absolute_path"
|
|
1710
1741
|
default: "~/.nautobot/static"
|
nautobot/core/tables.py
CHANGED
|
@@ -5,10 +5,12 @@ from django.contrib.auth.models import AnonymousUser
|
|
|
5
5
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
6
6
|
from django.core.exceptions import FieldDoesNotExist, FieldError
|
|
7
7
|
from django.db import NotSupportedError
|
|
8
|
+
from django.db.models import Prefetch
|
|
8
9
|
from django.db.models.fields.related import ForeignKey, RelatedField
|
|
9
10
|
from django.db.models.fields.reverse_related import ManyToOneRel
|
|
10
11
|
from django.urls import reverse
|
|
11
12
|
from django.utils.html import escape, format_html, format_html_join
|
|
13
|
+
from django.utils.http import urlencode
|
|
12
14
|
from django.utils.safestring import mark_safe
|
|
13
15
|
from django.utils.text import Truncator
|
|
14
16
|
import django_tables2
|
|
@@ -18,7 +20,7 @@ from tree_queries.models import TreeNode
|
|
|
18
20
|
|
|
19
21
|
from nautobot.core.models.querysets import count_related
|
|
20
22
|
from nautobot.core.templatetags import helpers
|
|
21
|
-
from nautobot.core.utils import
|
|
23
|
+
from nautobot.core.utils.lookup import get_model_for_view_name, get_related_field_for_models, get_route_for_model
|
|
22
24
|
from nautobot.extras import choices, models
|
|
23
25
|
|
|
24
26
|
logger = logging.getLogger(__name__)
|
|
@@ -154,12 +156,25 @@ class BaseTable(django_tables2.Table):
|
|
|
154
156
|
if not column.visible:
|
|
155
157
|
continue
|
|
156
158
|
if isinstance(column.column, LinkedCountColumn):
|
|
157
|
-
column_model =
|
|
159
|
+
column_model = get_model_for_view_name(column.column.viewname)
|
|
158
160
|
if column_model is None:
|
|
159
161
|
logger.error("Couldn't find model for %s", column.column.viewname)
|
|
160
162
|
continue
|
|
161
163
|
reverse_lookup = column.column.reverse_lookup or next(iter(column.column.url_params.keys()))
|
|
162
164
|
count_fields.append((column.name, column_model, reverse_lookup))
|
|
165
|
+
try:
|
|
166
|
+
lookup = column.column.lookup or get_related_field_for_models(model, column_model).name
|
|
167
|
+
# For some reason get_related_field_for_models(Tag, DynamicGroup) gives a M2M with the name
|
|
168
|
+
# `dynamicgroup`, which isn't actually a field on Tag. May be a django-taggit issue?
|
|
169
|
+
# Workaround for now: make sure the field actually exists on the model under this name:
|
|
170
|
+
getattr(model, lookup)
|
|
171
|
+
except AttributeError:
|
|
172
|
+
lookup = None
|
|
173
|
+
if lookup is not None:
|
|
174
|
+
# Also attempt to prefetch the first matching record for display - see LinkedCountColumn
|
|
175
|
+
prefetch_fields.append(
|
|
176
|
+
Prefetch(lookup, column_model.objects.all()[:1], to_attr=f"{lookup}_list")
|
|
177
|
+
)
|
|
163
178
|
continue
|
|
164
179
|
|
|
165
180
|
column_model = model
|
|
@@ -233,7 +248,7 @@ class BaseTable(django_tables2.Table):
|
|
|
233
248
|
# Belt and suspenders - we should have avoided any error cases above, but be safe anyway:
|
|
234
249
|
try:
|
|
235
250
|
queryset = queryset.prefetch_related(*prefetch_fields)
|
|
236
|
-
except (TypeError, ValueError, NotSupportedError) as exc:
|
|
251
|
+
except (AttributeError, TypeError, ValueError, NotSupportedError) as exc:
|
|
237
252
|
logger.warning(
|
|
238
253
|
"Unexpected error when trying to .prefetch_related() on %s QuerySet: %s",
|
|
239
254
|
model.__name__,
|
|
@@ -395,9 +410,9 @@ class ButtonsColumn(django_tables2.TemplateColumn):
|
|
|
395
410
|
self.template_code = prepend_template + self.template_code
|
|
396
411
|
|
|
397
412
|
app_label = model._meta.app_label
|
|
398
|
-
changelog_route =
|
|
399
|
-
edit_route =
|
|
400
|
-
delete_route =
|
|
413
|
+
changelog_route = get_route_for_model(model, "changelog")
|
|
414
|
+
edit_route = get_route_for_model(model, "edit")
|
|
415
|
+
delete_route = get_route_for_model(model, "delete")
|
|
401
416
|
|
|
402
417
|
template_code = self.template_code.format(
|
|
403
418
|
app_label=app_label,
|
|
@@ -462,29 +477,80 @@ class ColoredLabelColumn(django_tables2.TemplateColumn):
|
|
|
462
477
|
|
|
463
478
|
class LinkedCountColumn(django_tables2.Column):
|
|
464
479
|
"""
|
|
465
|
-
Render a count of related objects linked to a filtered URL.
|
|
466
|
-
|
|
467
|
-
:
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
480
|
+
Render a count of related objects linked to a filtered URL, or if a single related object is present, the object.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
viewname (str): The list view name to use for URL resolution, for example `"dcim:location_list"`
|
|
484
|
+
url_params (dict, optional): Query parameters to apply to filter the list URL (e.g. `{"vlans": "pk"}` will add
|
|
485
|
+
`?vlans=<record.pk>` to the linked list URL)
|
|
486
|
+
view_kwargs (dict, optional): Additional kwargs to pass to `reverse()` for list URL resolution. Rarely used.
|
|
487
|
+
lookup (str, optional): The field name on the base record that can be used to query the related objects.
|
|
488
|
+
If not specified, `nautobot.core.utils.lookup.get_related_field_for_models()` will be called at render time
|
|
489
|
+
to attempt to intelligently find the appropriate field.
|
|
490
|
+
TODO: this currently does *not* support nested lookups via `__`. That may be solvable in the future.
|
|
491
|
+
reverse_lookup (str, optional): The reverse lookup parameter to use to derive the count.
|
|
492
|
+
If not specified, the first key in `url_params` will be implicitly used as the `reverse_lookup` value.
|
|
493
|
+
**kwargs (dict, optional): As the parent Column class.
|
|
494
|
+
|
|
495
|
+
Examples:
|
|
496
|
+
```py
|
|
497
|
+
class VLANTable(..., BaseTable):
|
|
498
|
+
...
|
|
499
|
+
location_count = LinkedCountColumn(
|
|
500
|
+
# Link for N related locations will be reverse("dcim:location_list") + "?vlans=<record.pk>"
|
|
501
|
+
viewname="dcim:location_list",
|
|
502
|
+
url_params={"vlans": "pk"},
|
|
503
|
+
verbose_name="Locations",
|
|
504
|
+
)
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
```py
|
|
508
|
+
class CloudNetworkTable(BaseTable):
|
|
509
|
+
...
|
|
510
|
+
circuit_count = LinkedCountColumn(
|
|
511
|
+
# Link for N related circuits will be reverse("circuits:circuit_list") + "?cloud_network=<record.name>"
|
|
512
|
+
viewname="circuits:circuit_list",
|
|
513
|
+
url_params={"cloud_network": "name"},
|
|
514
|
+
# We'd like to do the below but this module isn't currently smart enough to build the right Prefetch()
|
|
515
|
+
# for a nested lookup:
|
|
516
|
+
# lookup="circuit_terminations__circuit",
|
|
517
|
+
# For the count, .annotate(circuit_count=count_related(Circuit, "circuit_terminations__cloud_network"))
|
|
518
|
+
reverse_lookup="circuit_terminations__cloud_network",
|
|
519
|
+
verbose_name="Circuits",
|
|
520
|
+
)
|
|
521
|
+
```
|
|
472
522
|
"""
|
|
473
523
|
|
|
474
|
-
def __init__(
|
|
524
|
+
def __init__(
|
|
525
|
+
self, viewname, *args, view_kwargs=None, url_params=None, lookup=None, reverse_lookup=None, default=0, **kwargs
|
|
526
|
+
):
|
|
475
527
|
self.viewname = viewname
|
|
528
|
+
self.lookup = lookup
|
|
476
529
|
self.view_kwargs = view_kwargs or {}
|
|
477
530
|
self.url_params = url_params
|
|
478
|
-
self.reverse_lookup = reverse_lookup
|
|
531
|
+
self.reverse_lookup = reverse_lookup or next(iter(url_params.keys()))
|
|
532
|
+
self.model = get_model_for_view_name(self.viewname)
|
|
479
533
|
super().__init__(*args, default=default, **kwargs)
|
|
480
534
|
|
|
481
|
-
def render(self, record, value): # pylint: disable=arguments-differ
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
535
|
+
def render(self, bound_column, record, value): # pylint: disable=arguments-differ
|
|
536
|
+
related_record = None
|
|
537
|
+
try:
|
|
538
|
+
lookup = self.lookup or get_related_field_for_models(bound_column._table._meta.model, self.model).name
|
|
539
|
+
except AttributeError:
|
|
540
|
+
lookup = None
|
|
541
|
+
if lookup:
|
|
542
|
+
if related_records := getattr(record, f"{lookup}_list", None):
|
|
543
|
+
related_record = related_records[0]
|
|
544
|
+
url = reverse(self.viewname, kwargs=self.view_kwargs)
|
|
545
|
+
if self.url_params:
|
|
546
|
+
url += "?" + urlencode({k: getattr(record, v) for k, v in self.url_params.items()})
|
|
547
|
+
if value > 1:
|
|
548
|
+
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
549
|
+
if related_record is not None:
|
|
550
|
+
return helpers.hyperlinked_object(related_record)
|
|
551
|
+
if value == 1:
|
|
552
|
+
return format_html('<a href="{}" class="badge">{}</a>', url, value)
|
|
553
|
+
return helpers.placeholder(value)
|
|
488
554
|
|
|
489
555
|
|
|
490
556
|
class TagColumn(django_tables2.TemplateColumn):
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
{% load helpers %}
|
|
3
3
|
{% load render_table from django_tables2 %}
|
|
4
4
|
|
|
5
|
-
{% block title %}Delete {{
|
|
5
|
+
{% block title %}Delete {{ total_objs_to_delete }} {{ obj_type_plural|bettertitle }}?{% endblock %}
|
|
6
6
|
|
|
7
7
|
{% block content %}
|
|
8
8
|
<div class="row">
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
<div class="panel panel-danger">
|
|
11
11
|
<div class="panel-heading"><strong>Confirm Bulk Deletion</strong></div>
|
|
12
12
|
<div class="panel-body">
|
|
13
|
-
<p><strong>Warning:</strong> The following operation will delete {{
|
|
13
|
+
<p><strong>Warning:</strong> The following operation will delete {{ total_objs_to_delete }} {{ obj_type_plural }}. {% if not delete_all %}Please carefully review the {{ obj_type_plural }} to be deleted and confirm below.{% endif %}</p>
|
|
14
14
|
{% block message_extra %}{% endblock %}
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
18
|
</div>
|
|
19
|
+
|
|
20
|
+
{% if table %}
|
|
19
21
|
<div class="row">
|
|
20
22
|
<div class="col-md-8 col-md-offset-2">
|
|
21
23
|
<div class="panel panel-default">
|
|
@@ -25,15 +27,22 @@
|
|
|
25
27
|
</div>
|
|
26
28
|
</div>
|
|
27
29
|
</div>
|
|
30
|
+
{% endif %}
|
|
31
|
+
|
|
28
32
|
<div class="row">
|
|
29
33
|
<div class="col-md-6 col-md-offset-3">
|
|
30
34
|
<form action="" method="post" class="form">
|
|
35
|
+
|
|
31
36
|
{% csrf_token %}
|
|
37
|
+
{% if delete_all %}
|
|
38
|
+
<input type="hidden" name="_all" value="true" />
|
|
39
|
+
{% endif %}
|
|
32
40
|
{% for field in form.hidden_fields %}
|
|
33
41
|
{{ field }}
|
|
34
42
|
{% endfor %}
|
|
43
|
+
|
|
35
44
|
<div class="text-center">
|
|
36
|
-
<button type="submit" name="_confirm" class="btn btn-danger">Delete these {{
|
|
45
|
+
<button type="submit" name="_confirm" class="btn btn-danger">Delete these {{ total_objs_to_delete }} {{ obj_type_plural }}</button>
|
|
37
46
|
<a href="{{ return_url }}" class="btn btn-default">Cancel</a>
|
|
38
47
|
</div>
|
|
39
48
|
</form>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{% load render_table from django_tables2 %}
|
|
5
5
|
|
|
6
6
|
{% block content %}
|
|
7
|
-
<h1>{% block title %}Editing {{
|
|
7
|
+
<h1>{% block title %}Editing {{ objs_count }} {{ obj_type_plural|bettertitle }}{% endblock %}</h1>
|
|
8
8
|
{% if form.errors %}
|
|
9
9
|
<div class="panel panel-danger">
|
|
10
10
|
<div class="panel-heading"><strong>Errors</strong></div>
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
{{ field }}
|
|
28
28
|
{% endfor %}
|
|
29
29
|
<div class="row">
|
|
30
|
+
{% if table %}
|
|
30
31
|
<div class="col-md-8">
|
|
31
32
|
<div class="panel panel-default">
|
|
32
33
|
<div class="table-responsive">
|
|
@@ -34,7 +35,8 @@
|
|
|
34
35
|
</div>
|
|
35
36
|
</div>
|
|
36
37
|
</div>
|
|
37
|
-
|
|
38
|
+
{% endif %}
|
|
39
|
+
<div class="{% if table %} col-md-4 {% else %} col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 {% endif %}">
|
|
38
40
|
<div class="panel panel-default">
|
|
39
41
|
<div class="panel-heading"><strong>{% block form_title %}Attributes{% endblock %}</strong></div>
|
|
40
42
|
<div class="panel-body">
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
</div>
|
|
52
52
|
<div class="row">
|
|
53
|
-
<div class="col-md-
|
|
53
|
+
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-right">
|
|
54
54
|
{% block buttons %}
|
|
55
55
|
{% if editing %}
|
|
56
56
|
<button type="submit" name="_update" class="btn btn-primary">Update</button>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
</div>
|
|
23
23
|
<div class="col-md-6 col-md-offset-3 text-right" style="margin-bottom: 20px;">
|
|
24
|
-
<button type="submit" class="btn btn-primary">Create</button>
|
|
24
|
+
<button id="createNote" type="submit" class="btn btn-primary">Create</button>
|
|
25
25
|
<a href="{{ object.get_absolute_url }}" class="btn btn-default">Cancel</a>
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
<h1>
|
|
55
55
|
<span class="hover_copy">
|
|
56
56
|
<span id="copy_title">{% block title %}{{object.display|default:object}}{% endblock %}</span>
|
|
57
|
-
<button type="button" class="btn btn-inline btn-default hover_copy_button" data-clipboard-
|
|
57
|
+
<button type="button" class="btn btn-inline btn-default hover_copy_button" data-clipboard-text="{{ object.display | default:object }}">
|
|
58
58
|
<span class="mdi mdi-content-copy"></span>
|
|
59
59
|
</button>
|
|
60
60
|
</span>
|
nautobot/core/testing/api.py
CHANGED
|
@@ -699,13 +699,15 @@ class APIViewTestCases:
|
|
|
699
699
|
serializer_class = get_serializer_for_model(self.model)
|
|
700
700
|
old_serializer = serializer_class(instance, context={"request": None})
|
|
701
701
|
old_data = old_serializer.data
|
|
702
|
+
# save the pk because .delete() will clear it, making the test below always pass
|
|
703
|
+
orig_pk = instance.pk
|
|
702
704
|
instance.delete()
|
|
703
705
|
|
|
704
706
|
response = self.client.post(self._get_list_url(), csv_data, content_type="text/csv", **self.header)
|
|
705
707
|
self.assertHttpStatus(response, status.HTTP_201_CREATED, csv_data)
|
|
706
708
|
# Note that create via CSV is always treated as a bulk-create, and so the response is always a list of dicts
|
|
707
709
|
new_instance = self._get_queryset().get(pk=response.data[0]["id"])
|
|
708
|
-
self.assertNotEqual(new_instance.pk,
|
|
710
|
+
self.assertNotEqual(new_instance.pk, orig_pk)
|
|
709
711
|
|
|
710
712
|
new_serializer = serializer_class(new_instance, context={"request": None})
|
|
711
713
|
new_data = new_serializer.data
|
|
@@ -5,6 +5,7 @@ from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
|
|
5
5
|
from django.test import override_settings, tag
|
|
6
6
|
from django.urls import reverse
|
|
7
7
|
from django.utils.functional import classproperty
|
|
8
|
+
from selenium.webdriver.common.keys import Keys
|
|
8
9
|
from splinter.browser import Browser
|
|
9
10
|
|
|
10
11
|
from nautobot.core import testing
|
|
@@ -74,3 +75,66 @@ class SeleniumTestCase(StaticLiveServerTestCase, testing.NautobotTestCaseMixin):
|
|
|
74
75
|
|
|
75
76
|
def logout(self):
|
|
76
77
|
self.browser.visit(f"{self.live_server_url}/logout")
|
|
78
|
+
|
|
79
|
+
def click_navbar_entry(self, parent_menu_name, child_menu_name):
|
|
80
|
+
"""
|
|
81
|
+
Helper function to click on a parent menu and child menu in the navigation bar.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
parent_menu_xpath = f"//*[@id='navbar']//a[@class='dropdown-toggle' and normalize-space()='{parent_menu_name}']"
|
|
85
|
+
parent_menu = self.browser.find_by_xpath(parent_menu_xpath, wait_time=5)
|
|
86
|
+
if not parent_menu["aria-expanded"] == "true":
|
|
87
|
+
parent_menu.click()
|
|
88
|
+
child_menu_xpath = f"{parent_menu_xpath}/following-sibling::ul//li[.//a[normalize-space()='{child_menu_name}']]"
|
|
89
|
+
child_menu = self.browser.find_by_xpath(child_menu_xpath, wait_time=5)
|
|
90
|
+
child_menu.click()
|
|
91
|
+
|
|
92
|
+
# Wait for body element to appear
|
|
93
|
+
self.assertTrue(self.browser.is_element_present_by_tag("body", wait_time=5), "Page failed to load")
|
|
94
|
+
|
|
95
|
+
def click_list_view_add_button(self):
|
|
96
|
+
"""
|
|
97
|
+
Helper function to click the "Add" button on a list view.
|
|
98
|
+
"""
|
|
99
|
+
add_button = self.browser.find_by_xpath("//a[@id='add-button']", wait_time=5)
|
|
100
|
+
add_button.click()
|
|
101
|
+
|
|
102
|
+
# Wait for body element to appear
|
|
103
|
+
self.assertTrue(self.browser.is_element_present_by_tag("body", wait_time=5), "Page failed to load")
|
|
104
|
+
|
|
105
|
+
def click_edit_form_create_button(self):
|
|
106
|
+
"""
|
|
107
|
+
Helper function to click the "Create" button on a form.
|
|
108
|
+
"""
|
|
109
|
+
add_button = self.browser.find_by_xpath("//button[@name='_create']", wait_time=5)
|
|
110
|
+
add_button.click()
|
|
111
|
+
|
|
112
|
+
# Wait for body element to appear
|
|
113
|
+
self.assertTrue(self.browser.is_element_present_by_tag("body", wait_time=5), "Page failed to load")
|
|
114
|
+
|
|
115
|
+
def fill_select2_field(self, field_name, value):
|
|
116
|
+
"""
|
|
117
|
+
Helper function to fill a Select2 single selection field.
|
|
118
|
+
"""
|
|
119
|
+
self.browser.find_by_xpath(f"//select[@id='id_{field_name}']//following-sibling::span").click()
|
|
120
|
+
search_box = self.browser.find_by_xpath(
|
|
121
|
+
"//*[@class='select2-search select2-search--dropdown']//input", wait_time=5
|
|
122
|
+
)
|
|
123
|
+
for _ in search_box.first.type(value, slowly=True):
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
# wait for "searching" to disappear
|
|
127
|
+
self.browser.is_element_not_present_by_css(".loading-results", wait_time=5)
|
|
128
|
+
search_box.first.type(Keys.ENTER)
|
|
129
|
+
|
|
130
|
+
def fill_select2_multiselect_field(self, field_name, value):
|
|
131
|
+
"""
|
|
132
|
+
Helper function to fill a Select2 multi-selection field.
|
|
133
|
+
"""
|
|
134
|
+
search_box = self.browser.find_by_xpath(f"//select[@id='id_{field_name}']//following-sibling::span//input")
|
|
135
|
+
for _ in search_box.first.type(value, slowly=True):
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
# wait for "searching" to disappear
|
|
139
|
+
self.browser.is_element_not_present_by_css(".loading-results", wait_time=5)
|
|
140
|
+
search_box.first.type(Keys.ENTER)
|