nautobot 2.3.11__py3-none-any.whl → 2.3.13__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/core/api/serializers.py +1 -0
- nautobot/core/celery/log.py +4 -4
- nautobot/core/models/tree_queries.py +5 -2
- nautobot/core/settings.py +26 -0
- nautobot/core/settings.yaml +31 -0
- nautobot/core/tables.py +60 -10
- nautobot/core/templates/generic/object_notes.html +1 -1
- nautobot/core/templates/generic/object_retrieve.html +1 -1
- nautobot/core/templatetags/helpers.py +7 -1
- nautobot/core/testing/api.py +5 -1
- nautobot/core/testing/views.py +15 -4
- nautobot/core/tests/test_api.py +20 -0
- nautobot/core/tests/test_csv.py +25 -3
- nautobot/core/tests/test_utils.py +8 -0
- nautobot/core/utils/lookup.py +11 -8
- nautobot/dcim/api/views.py +3 -0
- nautobot/dcim/choices.py +6 -0
- nautobot/dcim/filters/__init__.py +26 -1
- nautobot/dcim/forms.py +4 -0
- nautobot/dcim/tables/devices.py +2 -6
- nautobot/dcim/templates/dcim/controller_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/device/base.html +1 -1
- nautobot/dcim/tests/test_filters.py +33 -0
- nautobot/dcim/tests/test_views.py +6 -0
- nautobot/extras/api/serializers.py +1 -0
- nautobot/extras/api/views.py +2 -0
- nautobot/extras/forms/forms.py +2 -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 +15 -3
- nautobot/extras/tables.py +1 -0
- nautobot/extras/templates/extras/inc/job_table.html +1 -1
- nautobot/extras/tests/test_views.py +2 -2
- nautobot/extras/views.py +0 -2
- nautobot/ipam/lookups.py +101 -62
- nautobot/ipam/tables.py +22 -15
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +1 -1
- nautobot/ipam/tests/test_querysets.py +49 -1
- nautobot/ipam/utils/__init__.py +24 -0
- nautobot/ipam/views.py +61 -68
- 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 +206 -14
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +10 -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 +25 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +10 -10
- 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 +32 -13
- 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 +623 -188
- 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 +548 -192
- 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 +10 -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/users/api/serializers.py +1 -0
- nautobot/virtualization/filters.py +19 -2
- nautobot/virtualization/forms.py +3 -3
- nautobot/virtualization/templates/virtualization/vminterface.html +4 -0
- nautobot/virtualization/tests/test_filters.py +9 -0
- {nautobot-2.3.11.dist-info → nautobot-2.3.13.dist-info}/METADATA +4 -4
- {nautobot-2.3.11.dist-info → nautobot-2.3.13.dist-info}/RECORD +514 -513
- 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.11.dist-info → nautobot-2.3.13.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.11.dist-info → nautobot-2.3.13.dist-info}/NOTICE +0 -0
- {nautobot-2.3.11.dist-info → nautobot-2.3.13.dist-info}/WHEEL +0 -0
- {nautobot-2.3.11.dist-info → nautobot-2.3.13.dist-info}/entry_points.txt +0 -0
nautobot/dcim/tables/devices.py
CHANGED
|
@@ -220,13 +220,11 @@ class DeviceTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
|
220
220
|
)
|
|
221
221
|
|
|
222
222
|
|
|
223
|
-
class DeviceImportTable(BaseTable):
|
|
223
|
+
class DeviceImportTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
224
224
|
name = tables.TemplateColumn(template_code=DEVICE_LINK)
|
|
225
|
-
status = ColoredLabelColumn()
|
|
226
225
|
tenant = TenantColumn()
|
|
227
226
|
location = tables.Column(linkify=True)
|
|
228
227
|
rack = tables.Column(linkify=True)
|
|
229
|
-
role = tables.Column(verbose_name="Role")
|
|
230
228
|
device_type = tables.Column(verbose_name="Type")
|
|
231
229
|
|
|
232
230
|
class Meta(BaseTable.Meta):
|
|
@@ -1333,15 +1331,13 @@ class SoftwareVersionTable(StatusTableMixin, BaseTable):
|
|
|
1333
1331
|
)
|
|
1334
1332
|
|
|
1335
1333
|
|
|
1336
|
-
class ControllerTable(BaseTable):
|
|
1334
|
+
class ControllerTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
1337
1335
|
"""Table for list view."""
|
|
1338
1336
|
|
|
1339
1337
|
pk = ToggleColumn()
|
|
1340
1338
|
name = tables.Column(linkify=True)
|
|
1341
|
-
status = ColoredLabelColumn()
|
|
1342
1339
|
location = tables.Column(linkify=True)
|
|
1343
1340
|
platform = tables.Column(linkify=True)
|
|
1344
|
-
role = tables.Column(linkify=True)
|
|
1345
1341
|
tenant = TenantColumn()
|
|
1346
1342
|
external_integration = tables.Column(linkify=True)
|
|
1347
1343
|
controller_device = tables.Column(linkify=True)
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<span class="hover_copy">
|
|
59
59
|
<h1>
|
|
60
60
|
<span id="devicename">{% block title %}{{ object }}{% endblock title %}</span>
|
|
61
|
-
<button class="btn btn-xs btn-default hover_copy_button" data-clipboard-
|
|
61
|
+
<button class="btn btn-xs btn-default hover_copy_button" data-clipboard-text="{{ object }}">
|
|
62
62
|
<span class="mdi mdi-content-copy"></span>
|
|
63
63
|
</button>
|
|
64
64
|
</h1>
|
|
@@ -1701,6 +1701,7 @@ class DeviceTestCase(
|
|
|
1701
1701
|
("front_ports", "front_ports__id"),
|
|
1702
1702
|
("interfaces", "interfaces__id"),
|
|
1703
1703
|
("interfaces", "interfaces__name"),
|
|
1704
|
+
("ip_addresses", "interfaces__ip_addresses__id"),
|
|
1704
1705
|
("mac_address", "interfaces__mac_address"),
|
|
1705
1706
|
("manufacturer", "device_type__manufacturer__id"),
|
|
1706
1707
|
("manufacturer", "device_type__manufacturer__name"),
|
|
@@ -1874,6 +1875,14 @@ class DeviceTestCase(
|
|
|
1874
1875
|
Device.objects.filter(primary_ip4__isnull=True, primary_ip6__isnull=True),
|
|
1875
1876
|
)
|
|
1876
1877
|
|
|
1878
|
+
def test_ip_addresses(self):
|
|
1879
|
+
addresses = list(IPAddress.objects.filter(interfaces__isnull=False)[:2])
|
|
1880
|
+
params = {"ip_addresses": [addresses[0].address, addresses[1].id]}
|
|
1881
|
+
self.assertQuerysetEqualAndNotEmpty(
|
|
1882
|
+
self.filterset(params, self.queryset).qs,
|
|
1883
|
+
self.queryset.filter(interfaces__ip_addresses__in=addresses).distinct(),
|
|
1884
|
+
)
|
|
1885
|
+
|
|
1877
1886
|
def test_virtual_chassis_member(self):
|
|
1878
1887
|
# TODO: Not a generic_filter_test because this is a boolean filter but not a RelatedMembershipBooleanFilter
|
|
1879
1888
|
with self.subTest():
|
|
@@ -2168,6 +2177,7 @@ class InterfaceTestCase(PathEndpointModelTestMixin, ModularDeviceComponentTestMi
|
|
|
2168
2177
|
("child_interfaces", "child_interfaces__name"),
|
|
2169
2178
|
("description",),
|
|
2170
2179
|
# ("device", "device__id"), # TODO - InterfaceFilterSet overrides device as a MultiValueCharFilter on name only
|
|
2180
|
+
("ip_addresses", "ip_addresses__id"),
|
|
2171
2181
|
("label",),
|
|
2172
2182
|
("lag", "lag__id"),
|
|
2173
2183
|
("lag", "lag__name"),
|
|
@@ -2413,6 +2423,21 @@ class InterfaceTestCase(PathEndpointModelTestMixin, ModularDeviceComponentTestMi
|
|
|
2413
2423
|
status=interface_statuses[3],
|
|
2414
2424
|
)
|
|
2415
2425
|
|
|
2426
|
+
ipaddr_status = Status.objects.get_for_model(IPAddress).first()
|
|
2427
|
+
prefix_status = Status.objects.get_for_model(Prefix).first()
|
|
2428
|
+
namespace = Namespace.objects.first()
|
|
2429
|
+
Prefix.objects.create(prefix="192.0.2.0/24", namespace=namespace, status=prefix_status)
|
|
2430
|
+
Prefix.objects.create(prefix="2600::/64", namespace=namespace, status=prefix_status)
|
|
2431
|
+
ipaddresses = (
|
|
2432
|
+
IPAddress.objects.create(address="192.0.2.1/24", namespace=namespace, status=ipaddr_status),
|
|
2433
|
+
IPAddress.objects.create(address="192.0.2.2/24", namespace=namespace, status=ipaddr_status),
|
|
2434
|
+
IPAddress.objects.create(address="2600::1/120", namespace=namespace, status=ipaddr_status),
|
|
2435
|
+
IPAddress.objects.create(address="2600::0100/120", namespace=namespace, status=ipaddr_status),
|
|
2436
|
+
)
|
|
2437
|
+
|
|
2438
|
+
cabled_interfaces[0].add_ip_addresses([ipaddresses[0], ipaddresses[2]])
|
|
2439
|
+
cabled_interfaces[1].add_ip_addresses([ipaddresses[1], ipaddresses[3]])
|
|
2440
|
+
|
|
2416
2441
|
def test_enabled(self):
|
|
2417
2442
|
# TODO: Not a generic_filter_test because this is a boolean filter but not a RelatedMembershipBooleanFilter
|
|
2418
2443
|
with self.subTest():
|
|
@@ -2646,6 +2671,14 @@ class InterfaceTestCase(PathEndpointModelTestMixin, ModularDeviceComponentTestMi
|
|
|
2646
2671
|
with self.subTest("device (pk) filter with an invalid uuid"):
|
|
2647
2672
|
self.assertFalse(self.filterset({"device": [uuid.uuid4()]}, self.queryset).is_valid())
|
|
2648
2673
|
|
|
2674
|
+
def test_ip_addresses(self):
|
|
2675
|
+
addresses = list(IPAddress.objects.filter(interfaces__isnull=False)[:2])
|
|
2676
|
+
params = {"ip_addresses": [addresses[0].address, addresses[1].id]}
|
|
2677
|
+
self.assertQuerysetEqualAndNotEmpty(
|
|
2678
|
+
self.filterset(params, self.queryset).qs,
|
|
2679
|
+
self.queryset.filter(ip_addresses__in=addresses).distinct(),
|
|
2680
|
+
)
|
|
2681
|
+
|
|
2649
2682
|
def test_kind(self):
|
|
2650
2683
|
# TODO: Not a generic_filter_test because this is a single-value filter
|
|
2651
2684
|
# 2.0 TODO: Support filtering for multiple values
|
|
@@ -130,6 +130,7 @@ from nautobot.ipam.choices import IPAddressTypeChoices
|
|
|
130
130
|
from nautobot.ipam.models import IPAddress, Namespace, Prefix, VLAN, VLANGroup, VRF
|
|
131
131
|
from nautobot.tenancy.models import Tenant
|
|
132
132
|
from nautobot.users.models import ObjectPermission
|
|
133
|
+
from nautobot.virtualization.models import Cluster, ClusterType
|
|
133
134
|
|
|
134
135
|
# Use the proper swappable User model
|
|
135
136
|
User = get_user_model()
|
|
@@ -2047,6 +2048,9 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2047
2048
|
|
|
2048
2049
|
rack_group = RackGroup.objects.create(location=locations[0], name="Rack Group 1")
|
|
2049
2050
|
|
|
2051
|
+
cluster_type = ClusterType.objects.create(name="Cluster Type 1")
|
|
2052
|
+
cluster = Cluster.objects.create(name="Cluster 1", cluster_type=cluster_type)
|
|
2053
|
+
|
|
2050
2054
|
rack_status = Status.objects.get_for_model(Rack).first()
|
|
2051
2055
|
racks = (
|
|
2052
2056
|
Rack.objects.create(
|
|
@@ -2218,6 +2222,8 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2218
2222
|
"status": statuses[2].pk,
|
|
2219
2223
|
"location": locations[1].pk,
|
|
2220
2224
|
"rack": racks[1].pk,
|
|
2225
|
+
"cluster": cluster.pk,
|
|
2226
|
+
"comments": "An older device",
|
|
2221
2227
|
"position": None,
|
|
2222
2228
|
"face": DeviceFaceChoices.FACE_FRONT,
|
|
2223
2229
|
"secrets_group": secrets_groups[1].pk,
|
|
@@ -270,6 +270,7 @@ class ContactAssociationSerializer(NautobotModelSerializer):
|
|
|
270
270
|
|
|
271
271
|
|
|
272
272
|
class ContentTypeSerializer(BaseModelSerializer):
|
|
273
|
+
id = serializers.IntegerField(read_only=True)
|
|
273
274
|
url = serializers.HyperlinkedIdentityField(view_name="extras-api:contenttype-detail")
|
|
274
275
|
display = serializers.SerializerMethodField()
|
|
275
276
|
|
nautobot/extras/api/views.py
CHANGED
|
@@ -17,6 +17,7 @@ from rest_framework.permissions import IsAuthenticated
|
|
|
17
17
|
from rest_framework.response import Response
|
|
18
18
|
|
|
19
19
|
from nautobot.core.api.authentication import TokenPermissions
|
|
20
|
+
from nautobot.core.api.parsers import NautobotCSVParser
|
|
20
21
|
from nautobot.core.api.utils import get_serializer_for_model
|
|
21
22
|
from nautobot.core.api.views import (
|
|
22
23
|
BulkDestroyModelMixin,
|
|
@@ -484,6 +485,7 @@ class ImageAttachmentViewSet(ModelViewSet):
|
|
|
484
485
|
queryset = ImageAttachment.objects.all()
|
|
485
486
|
serializer_class = serializers.ImageAttachmentSerializer
|
|
486
487
|
filterset_class = filters.ImageAttachmentFilterSet
|
|
488
|
+
parser_classes = [JSONParser, NautobotCSVParser, MultiPartParser]
|
|
487
489
|
|
|
488
490
|
|
|
489
491
|
#
|
nautobot/extras/forms/forms.py
CHANGED
|
@@ -1682,6 +1682,8 @@ class RoleBulkEditForm(NautobotBulkEditForm):
|
|
|
1682
1682
|
|
|
1683
1683
|
pk = forms.ModelMultipleChoiceField(queryset=Role.objects.all(), widget=forms.MultipleHiddenInput)
|
|
1684
1684
|
color = forms.CharField(max_length=6, required=False, widget=ColorSelect())
|
|
1685
|
+
description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
|
|
1686
|
+
weight = forms.IntegerField(required=False)
|
|
1685
1687
|
content_types = MultipleContentTypeField(
|
|
1686
1688
|
queryset=RoleModelsQuery().as_queryset(), required=False, label="Content Type(s)"
|
|
1687
1689
|
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Additional functions to process an OAuth2/OIDC user."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.contrib.auth.models import Group
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
CLAIMS_GROUP_NAME = getattr(settings, "SSO_CLAIMS_GROUP", "groups")
|
|
12
|
+
""" Which claim to look at in the OAuth2/OIDC response
|
|
13
|
+
|
|
14
|
+
For Okta you can look at `Okta -> Authorization Servers -> Claims`. And a reasonable
|
|
15
|
+
default is "groups". For Azure a reasonable default is "roles".
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
SUPERUSER_GROUPS = getattr(settings, "SSO_SUPERUSER_GROUPS", [])
|
|
19
|
+
STAFF_GROUPS = getattr(settings, "SSO_STAFF_GROUPS", [])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def group_sync(uid, user=None, response=None, *args, **kwargs):
|
|
23
|
+
"""Sync the users groups from OAuth2/OIDC auth and set staff/superuser as appropriate."""
|
|
24
|
+
if user and response and CLAIMS_GROUP_NAME and response.get(CLAIMS_GROUP_NAME, False):
|
|
25
|
+
group_memberships = response.get(CLAIMS_GROUP_NAME)
|
|
26
|
+
is_staff = False
|
|
27
|
+
is_superuser = False
|
|
28
|
+
logger.debug(f"User {uid} is a member of {', '.join(group_memberships)}")
|
|
29
|
+
# Make sure all groups exist in Nautobot
|
|
30
|
+
group_ids = []
|
|
31
|
+
for group in group_memberships:
|
|
32
|
+
if group in SUPERUSER_GROUPS:
|
|
33
|
+
is_superuser = True
|
|
34
|
+
if group in STAFF_GROUPS:
|
|
35
|
+
is_staff = True
|
|
36
|
+
group_ids.append(Group.objects.get_or_create(name=group)[0].id)
|
|
37
|
+
user.groups.set(group_ids)
|
|
38
|
+
user.is_superuser = is_superuser
|
|
39
|
+
user.is_staff = is_staff
|
|
40
|
+
user.save()
|
|
41
|
+
else:
|
|
42
|
+
logger.debug(f"Did not receive groups from OAuth2/OIDC, response: {response}")
|
|
@@ -201,6 +201,7 @@ class ObjectMetadata(ChangeLoggedModel, BaseModel):
|
|
|
201
201
|
objects = ObjectMetadataManager()
|
|
202
202
|
natural_key_field_names = ["pk"]
|
|
203
203
|
documentation_static_path = "docs/user-guide/platform-functionality/objectmetadata.html"
|
|
204
|
+
is_metadata_associable_model = False
|
|
204
205
|
|
|
205
206
|
class Meta:
|
|
206
207
|
ordering = ["metadata_type"]
|
nautobot/extras/models/models.py
CHANGED
|
@@ -831,7 +831,7 @@ class Note(ChangeLoggedModel, BaseModel):
|
|
|
831
831
|
unique_together = [["assigned_object_type", "assigned_object_id", "user_name", "created"]]
|
|
832
832
|
|
|
833
833
|
def __str__(self):
|
|
834
|
-
return f"{self.assigned_object} - {self.created.isoformat()}"
|
|
834
|
+
return f"{self.assigned_object} - {self.created.isoformat() if self.created else None}"
|
|
835
835
|
|
|
836
836
|
def save(self, *args, **kwargs):
|
|
837
837
|
# Record the user's name as static strings
|
|
@@ -207,8 +207,9 @@ class NautobotAppConfig(NautobotConfig):
|
|
|
207
207
|
override_views = import_object(f"{self.__module__}.{self.override_views}")
|
|
208
208
|
if override_views is not None:
|
|
209
209
|
for qualified_view_name, view in override_views.items():
|
|
210
|
+
view_class_name = view.view_class.__name__ if hasattr(view, "view_class") else view.cls.__name__
|
|
210
211
|
self.features.setdefault("overridden_views", []).append(
|
|
211
|
-
(qualified_view_name, f"{view.__module__}.{
|
|
212
|
+
(qualified_view_name, f"{view.__module__}.{view_class_name}")
|
|
212
213
|
)
|
|
213
214
|
register_override_views(override_views, self.name)
|
|
214
215
|
|
|
@@ -518,6 +519,7 @@ class TableExtension:
|
|
|
518
519
|
"""
|
|
519
520
|
|
|
520
521
|
model = None
|
|
522
|
+
suffix = None
|
|
521
523
|
table_columns = {}
|
|
522
524
|
add_to_default_columns = ()
|
|
523
525
|
remove_from_default_columns = ()
|
|
@@ -593,7 +595,7 @@ def _add_columns_into_model_table(table_extension, app_name):
|
|
|
593
595
|
logger.error(error)
|
|
594
596
|
return
|
|
595
597
|
|
|
596
|
-
table = get_table_for_model(table_extension.model)
|
|
598
|
+
table = get_table_for_model(table_extension.model, suffix=table_extension.suffix)
|
|
597
599
|
for name, column in table_extension.table_columns.items():
|
|
598
600
|
_validate_table_column_name_is_prefixed_with_app_name(name, app_name)
|
|
599
601
|
_add_column_to_table_base_columns(table, name, column, app_name)
|
|
@@ -628,18 +630,28 @@ def _modify_default_table_columns(table_extension, app_name):
|
|
|
628
630
|
"""Add or remove columns from the table default columns."""
|
|
629
631
|
from nautobot.core.utils.lookup import get_table_for_model
|
|
630
632
|
|
|
631
|
-
table = get_table_for_model(table_extension.model)
|
|
633
|
+
table = get_table_for_model(table_extension.model, suffix=table_extension.suffix)
|
|
632
634
|
message = (
|
|
633
635
|
f"{app_name}: Cannot {{action}} column `{{column_name}}` {{preposition}} the default columns for `{table}`."
|
|
634
636
|
)
|
|
635
637
|
|
|
636
638
|
for column_name in table_extension.add_to_default_columns:
|
|
639
|
+
if not getattr(table.Meta, "default_columns", None):
|
|
640
|
+
logger.warning(
|
|
641
|
+
f"{app_name}: Table `{table}` does not have a `default_columns` attribute. Cannot add column: {column_name}."
|
|
642
|
+
)
|
|
643
|
+
continue
|
|
637
644
|
if column_name in table.base_columns:
|
|
638
645
|
table.Meta.default_columns = (*table.Meta.default_columns, column_name)
|
|
639
646
|
else:
|
|
640
647
|
logger.debug(message.format(action="add", column_name=column_name, preposition="to"))
|
|
641
648
|
|
|
642
649
|
for column_name in table_extension.remove_from_default_columns:
|
|
650
|
+
if not getattr(table.Meta, "default_columns", None):
|
|
651
|
+
logger.warning(
|
|
652
|
+
f"{app_name}: Table `{table}` does not have a `default_columns` attribute. Cannot remove column: {column_name}."
|
|
653
|
+
)
|
|
654
|
+
continue
|
|
643
655
|
if column_name in table.Meta.default_columns:
|
|
644
656
|
table.Meta.default_columns = tuple(name for name in table.Meta.default_columns if name != column_name)
|
|
645
657
|
else:
|
nautobot/extras/tables.py
CHANGED
|
@@ -978,6 +978,7 @@ class MetadataTypeTable(BaseTable):
|
|
|
978
978
|
|
|
979
979
|
class ObjectMetadataTable(BaseTable):
|
|
980
980
|
pk = ToggleColumn()
|
|
981
|
+
# NOTE: there is no identity column in this table; this is intentional as we have no detail view for ObjectMetadata
|
|
981
982
|
metadata_type = tables.Column(linkify=True)
|
|
982
983
|
assigned_object = tables.TemplateColumn(
|
|
983
984
|
template_code=ASSIGNED_OBJECT, verbose_name="Assigned object", orderable=False
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
</th>
|
|
29
29
|
</tr>
|
|
30
30
|
{% endifchanged %}
|
|
31
|
-
<tr class="collapseme-{{ row.record.grouping|slugify }}{% if not perms.extras.run_job or not row.record.runnable %} disabled{% endif %} collapse in" data-parent="#accordion" {{ row.attrs.as_html }}>
|
|
31
|
+
<tr class="{% cycle 'even' 'odd' %} collapseme-{{ row.record.grouping|slugify }}{% if not perms.extras.run_job or not row.record.runnable %} disabled{% endif %} collapse in" data-parent="#accordion" {{ row.attrs.as_html }}>
|
|
32
32
|
{% for column, cell in row.items %}
|
|
33
33
|
<td {{ column.attrs.td.as_html }}>{{ cell }}</td>
|
|
34
34
|
{% endfor %}
|
|
@@ -3033,8 +3033,6 @@ class ObjectChangeTestCase(TestCase):
|
|
|
3033
3033
|
|
|
3034
3034
|
|
|
3035
3035
|
class ObjectMetadataTestCase(
|
|
3036
|
-
ViewTestCases.GetObjectViewTestCase,
|
|
3037
|
-
ViewTestCases.GetObjectChangelogViewTestCase,
|
|
3038
3036
|
ViewTestCases.ListObjectsViewTestCase,
|
|
3039
3037
|
):
|
|
3040
3038
|
model = ObjectMetadata
|
|
@@ -3609,6 +3607,8 @@ class RoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|
|
3609
3607
|
|
|
3610
3608
|
cls.bulk_edit_data = {
|
|
3611
3609
|
"color": "000000",
|
|
3610
|
+
"description": "I used to be a new role object.",
|
|
3611
|
+
"weight": 255,
|
|
3612
3612
|
}
|
|
3613
3613
|
|
|
3614
3614
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
nautobot/extras/views.py
CHANGED
nautobot/ipam/lookups.py
CHANGED
|
@@ -3,7 +3,9 @@ from django.db.models import Lookup, lookups
|
|
|
3
3
|
import netaddr
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def _mysql_varbin_to_broadcast():
|
|
6
|
+
def _mysql_varbin_to_broadcast(alias=None):
|
|
7
|
+
if alias:
|
|
8
|
+
return f"HEX({alias}.broadcast)"
|
|
7
9
|
return "HEX(broadcast)"
|
|
8
10
|
|
|
9
11
|
|
|
@@ -13,11 +15,15 @@ def _mysql_varbin_to_hex(lhs, alias=None):
|
|
|
13
15
|
return f"HEX({lhs})"
|
|
14
16
|
|
|
15
17
|
|
|
16
|
-
def _mysql_varbin_to_network():
|
|
18
|
+
def _mysql_varbin_to_network(alias=None):
|
|
19
|
+
if alias:
|
|
20
|
+
return f"HEX({alias}.network)"
|
|
17
21
|
return "HEX(network)"
|
|
18
22
|
|
|
19
23
|
|
|
20
|
-
def _postgresql_varbin_to_broadcast(length):
|
|
24
|
+
def _postgresql_varbin_to_broadcast(length, alias=None):
|
|
25
|
+
if alias:
|
|
26
|
+
return f"right({alias}.broadcast::text, -1)::varbit::bit({length})"
|
|
21
27
|
return f"right(broadcast::text, -1)::varbit::bit({length})"
|
|
22
28
|
|
|
23
29
|
|
|
@@ -27,8 +33,10 @@ def _postgresql_varbin_to_integer(lhs, length, alias=None):
|
|
|
27
33
|
return f"right({lhs}::text, -1)::varbit::bit({length})"
|
|
28
34
|
|
|
29
35
|
|
|
30
|
-
def _postgresql_varbin_to_network(lhs, length):
|
|
36
|
+
def _postgresql_varbin_to_network(lhs, length, alias=None):
|
|
31
37
|
# convert to bitstring, 0 out everything larger than prefix_length
|
|
38
|
+
if alias:
|
|
39
|
+
return f"lpad(right({alias}.{lhs}::text, -1)::varbit::text, {alias}.prefix_length, '0')::bit({length})"
|
|
32
40
|
return f"lpad(right({lhs}::text, -1)::varbit::text, prefix_length, '0')::bit({length})"
|
|
33
41
|
|
|
34
42
|
|
|
@@ -52,8 +60,8 @@ def get_ip_info(field_name, ip_str, alias=None):
|
|
|
52
60
|
ip_details.rhs = py_to_hex(ip.ip, ip_details.length)
|
|
53
61
|
ip_details.net_addr = f"'{py_to_hex(ip.network, ip_details.length)}'"
|
|
54
62
|
ip_details.bcast_addr = f"'{py_to_hex(ip[-1], ip_details.length)}'"
|
|
55
|
-
ip_details.q_net = _mysql_varbin_to_network()
|
|
56
|
-
ip_details.q_bcast = _mysql_varbin_to_broadcast()
|
|
63
|
+
ip_details.q_net = _mysql_varbin_to_network(alias=alias)
|
|
64
|
+
ip_details.q_bcast = _mysql_varbin_to_broadcast(alias=alias)
|
|
57
65
|
ip_details.q_ip = _mysql_varbin_to_hex(field_name, alias=alias)
|
|
58
66
|
|
|
59
67
|
elif _connection.vendor == "postgresql":
|
|
@@ -61,8 +69,8 @@ def get_ip_info(field_name, ip_str, alias=None):
|
|
|
61
69
|
ip_details.addr_str = f"B'{bin(int(ip_details.addr))[2:].zfill(ip_details.length)}'"
|
|
62
70
|
ip_details.net_addr = f"B'{bin(int(ip.network))[2:].zfill(ip_details.length)}'"
|
|
63
71
|
ip_details.bcast_addr = f"B'{bin(int(ip[-1]))[2:].zfill(ip_details.length)}'"
|
|
64
|
-
ip_details.q_net = _postgresql_varbin_to_network(field_name, ip_details.length)
|
|
65
|
-
ip_details.q_bcast = _postgresql_varbin_to_broadcast(ip_details.length)
|
|
72
|
+
ip_details.q_net = _postgresql_varbin_to_network(field_name, ip_details.length, alias=alias)
|
|
73
|
+
ip_details.q_bcast = _postgresql_varbin_to_broadcast(ip_details.length, alias=alias)
|
|
66
74
|
ip_details.q_ip = _postgresql_varbin_to_integer(field_name, ip_details.length, alias=alias)
|
|
67
75
|
|
|
68
76
|
return ip_details
|
|
@@ -71,25 +79,38 @@ def get_ip_info(field_name, ip_str, alias=None):
|
|
|
71
79
|
class IPDetails:
|
|
72
80
|
"""Class for setting up all details about an IP they may be needed"""
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
q_ip = None
|
|
82
|
+
addr = None # 10.0.0.0
|
|
83
|
+
ip = None # 10.0.0.0/8
|
|
84
|
+
prefix = None # 8
|
|
85
|
+
length = None # 32
|
|
86
|
+
addr_str = None # B'00001010000000000000000000000000'
|
|
87
|
+
rhs = None # 00001010000000000000000000000000
|
|
88
|
+
net_addr = None # B'00001010000000000000000000000000'
|
|
89
|
+
bcast_addr = None # B'00001010111111111111111111111111'
|
|
90
|
+
q_net = None # mysql or postgres specific
|
|
91
|
+
q_bcast = None # mysql or postgres specific
|
|
92
|
+
q_ip = None # mysql or postgres specific
|
|
86
93
|
to_len = {4: 32, 6: 128}
|
|
87
94
|
|
|
95
|
+
def __str__(self):
|
|
96
|
+
return f"""\
|
|
97
|
+
addr: {self.addr}
|
|
98
|
+
ip: {self.ip}
|
|
99
|
+
prefix: {self.prefix}
|
|
100
|
+
length: {self.length}
|
|
101
|
+
addr_str: {self.addr_str}
|
|
102
|
+
rhs: {self.rhs}
|
|
103
|
+
net_addr: {self.net_addr}
|
|
104
|
+
bcast_addr: {self.bcast_addr}
|
|
105
|
+
q_net: {self.q_net}
|
|
106
|
+
q_bcast: {self.q_bcast}
|
|
107
|
+
q_ip: {self.q_ip}"""
|
|
108
|
+
|
|
88
109
|
|
|
89
110
|
class StringMatchMixin:
|
|
90
|
-
def process_lhs(self,
|
|
111
|
+
def process_lhs(self, compiler, connection, lhs=None):
|
|
91
112
|
lhs = lhs or self.lhs
|
|
92
|
-
lhs_string, lhs_params =
|
|
113
|
+
lhs_string, lhs_params = compiler.compile(lhs)
|
|
93
114
|
if connection.vendor == "postgresql":
|
|
94
115
|
raise NotSupportedError("Lookup not supported on postgresql.")
|
|
95
116
|
return f"INET6_NTOA({lhs_string})", lhs_params
|
|
@@ -129,6 +150,7 @@ class IRegex(StringMatchMixin, lookups.IRegex):
|
|
|
129
150
|
|
|
130
151
|
class NetworkFieldMixin:
|
|
131
152
|
def get_prep_lookup(self):
|
|
153
|
+
self.alias = self.lhs.alias
|
|
132
154
|
field_name = self.lhs.field.name
|
|
133
155
|
if field_name not in ["host", "network"]:
|
|
134
156
|
raise NotSupportedError(f"Lookup only provided on the host and network fields, not {field_name}.")
|
|
@@ -139,8 +161,8 @@ class NetworkFieldMixin:
|
|
|
139
161
|
self.ip = get_ip_info(field_name, self.rhs, alias=self.lhs.alias)
|
|
140
162
|
return str(self.ip.ip)
|
|
141
163
|
|
|
142
|
-
def process_rhs(self,
|
|
143
|
-
sql, params = super().process_rhs(
|
|
164
|
+
def process_rhs(self, compiler, connection):
|
|
165
|
+
sql, params = super().process_rhs(compiler, connection)
|
|
144
166
|
params[0] = self.ip.rhs
|
|
145
167
|
return sql, params
|
|
146
168
|
|
|
@@ -148,50 +170,67 @@ class NetworkFieldMixin:
|
|
|
148
170
|
class NetEquals(NetworkFieldMixin, Lookup):
|
|
149
171
|
lookup_name = "net_equals"
|
|
150
172
|
|
|
151
|
-
def as_sql(self,
|
|
152
|
-
_, lhs_params = self.process_lhs(
|
|
153
|
-
rhs, rhs_params = self.process_rhs(
|
|
154
|
-
|
|
173
|
+
def as_sql(self, compiler, connection):
|
|
174
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
175
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
176
|
+
if self.alias:
|
|
177
|
+
query = f"{self.alias}.prefix_length = {self.ip.prefix} AND {rhs} = {self.ip.q_ip}"
|
|
178
|
+
else:
|
|
179
|
+
query = f"prefix_length = {self.ip.prefix} AND {rhs} = {self.ip.q_ip}"
|
|
155
180
|
return query, lhs_params + rhs_params
|
|
156
181
|
|
|
157
182
|
|
|
158
183
|
class NetContainsOrEquals(NetworkFieldMixin, Lookup):
|
|
159
184
|
lookup_name = "net_contains_or_equals"
|
|
160
185
|
|
|
161
|
-
def as_sql(self,
|
|
162
|
-
_, lhs_params = self.process_lhs(
|
|
163
|
-
rhs, rhs_params = self.process_rhs(
|
|
164
|
-
|
|
186
|
+
def as_sql(self, compiler, connection):
|
|
187
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
188
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
189
|
+
if self.alias:
|
|
190
|
+
query = f"{self.alias}.prefix_length <= {self.ip.prefix} AND {rhs} BETWEEN {self.ip.q_net} AND {self.ip.q_bcast}"
|
|
191
|
+
else:
|
|
192
|
+
query = f"prefix_length <= {self.ip.prefix} AND {rhs} BETWEEN {self.ip.q_net} AND {self.ip.q_bcast}"
|
|
165
193
|
return query, lhs_params + rhs_params
|
|
166
194
|
|
|
167
195
|
|
|
168
196
|
class NetContains(NetworkFieldMixin, Lookup):
|
|
169
197
|
lookup_name = "net_contains"
|
|
170
198
|
|
|
171
|
-
def as_sql(self,
|
|
172
|
-
_, lhs_params = self.process_lhs(
|
|
173
|
-
rhs, rhs_params = self.process_rhs(
|
|
174
|
-
|
|
199
|
+
def as_sql(self, compiler, connection):
|
|
200
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
201
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
202
|
+
if self.alias:
|
|
203
|
+
query = (
|
|
204
|
+
f"{self.alias}.prefix_length < {self.ip.prefix} AND {rhs} BETWEEN {self.ip.q_net} AND {self.ip.q_bcast}"
|
|
205
|
+
)
|
|
206
|
+
else:
|
|
207
|
+
query = f"prefix_length < {self.ip.prefix} AND {rhs} BETWEEN {self.ip.q_net} AND {self.ip.q_bcast}"
|
|
175
208
|
return query, lhs_params + rhs_params
|
|
176
209
|
|
|
177
210
|
|
|
178
211
|
class NetContainedOrEqual(NetworkFieldMixin, Lookup):
|
|
179
212
|
lookup_name = "net_contained_or_equal"
|
|
180
213
|
|
|
181
|
-
def as_sql(self,
|
|
182
|
-
_, lhs_params = self.process_lhs(
|
|
183
|
-
rhs, rhs_params = self.process_rhs(
|
|
184
|
-
|
|
214
|
+
def as_sql(self, compiler, connection):
|
|
215
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
216
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
217
|
+
if self.alias:
|
|
218
|
+
query = f"{self.alias}.prefix_length >= {self.ip.prefix} AND {self.ip.q_net} BETWEEN {rhs} AND {self.ip.bcast_addr}"
|
|
219
|
+
else:
|
|
220
|
+
query = f"prefix_length >= {self.ip.prefix} AND {self.ip.q_net} BETWEEN {rhs} AND {self.ip.bcast_addr}"
|
|
185
221
|
return query, lhs_params + rhs_params
|
|
186
222
|
|
|
187
223
|
|
|
188
224
|
class NetContained(NetworkFieldMixin, Lookup):
|
|
189
225
|
lookup_name = "net_contained"
|
|
190
226
|
|
|
191
|
-
def as_sql(self,
|
|
192
|
-
_, lhs_params = self.process_lhs(
|
|
193
|
-
rhs, rhs_params = self.process_rhs(
|
|
194
|
-
|
|
227
|
+
def as_sql(self, compiler, connection):
|
|
228
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
229
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
230
|
+
if self.alias:
|
|
231
|
+
query = f"{self.alias}.prefix_length > {self.ip.prefix} AND {self.ip.q_net} BETWEEN {rhs} AND {self.ip.bcast_addr}"
|
|
232
|
+
else:
|
|
233
|
+
query = f"prefix_length > {self.ip.prefix} AND {self.ip.q_net} BETWEEN {rhs} AND {self.ip.bcast_addr}"
|
|
195
234
|
return query, lhs_params + rhs_params
|
|
196
235
|
|
|
197
236
|
|
|
@@ -205,19 +244,19 @@ class NetHost(Lookup):
|
|
|
205
244
|
self.ip = get_ip_info(field_name, self.rhs, alias=self.lhs.alias)
|
|
206
245
|
return str(self.ip.ip)
|
|
207
246
|
|
|
208
|
-
def process_rhs(self,
|
|
209
|
-
sql, params = super().process_rhs(
|
|
247
|
+
def process_rhs(self, compiler, connection):
|
|
248
|
+
sql, params = super().process_rhs(compiler, connection)
|
|
210
249
|
params[0] = self.ip.rhs
|
|
211
250
|
return sql, params
|
|
212
251
|
|
|
213
|
-
def process_lhs(self,
|
|
252
|
+
def process_lhs(self, compiler, connection, lhs=None):
|
|
214
253
|
lhs = lhs or self.lhs
|
|
215
|
-
_, lhs_params =
|
|
254
|
+
_, lhs_params = compiler.compile(lhs)
|
|
216
255
|
return self.ip.q_ip, lhs_params
|
|
217
256
|
|
|
218
|
-
def as_sql(self,
|
|
219
|
-
lhs, lhs_params = self.process_lhs(
|
|
220
|
-
rhs, rhs_params = self.process_rhs(
|
|
257
|
+
def as_sql(self, compiler, connection):
|
|
258
|
+
lhs, lhs_params = self.process_lhs(compiler, connection)
|
|
259
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
221
260
|
return f"{lhs} = {rhs}", lhs_params + rhs_params
|
|
222
261
|
|
|
223
262
|
|
|
@@ -242,9 +281,9 @@ class NetIn(Lookup):
|
|
|
242
281
|
self.query_starter = "'1' != ANY(%s) AND "
|
|
243
282
|
return self.rhs
|
|
244
283
|
|
|
245
|
-
def as_sql(self,
|
|
246
|
-
_, lhs_params = self.process_lhs(
|
|
247
|
-
_, rhs_params = self.process_rhs(
|
|
284
|
+
def as_sql(self, compiler, connection):
|
|
285
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
286
|
+
_, rhs_params = self.process_rhs(compiler, connection)
|
|
248
287
|
query = self.query_starter
|
|
249
288
|
query += "OR ".join(f"{ip.q_ip} BETWEEN {ip.net_addr} AND {ip.bcast_addr} " for ip in self.ips)
|
|
250
289
|
return query, lhs_params + rhs_params
|
|
@@ -253,9 +292,9 @@ class NetIn(Lookup):
|
|
|
253
292
|
class NetHostContained(NetworkFieldMixin, Lookup):
|
|
254
293
|
lookup_name = "net_host_contained"
|
|
255
294
|
|
|
256
|
-
def as_sql(self,
|
|
257
|
-
_, lhs_params = self.process_lhs(
|
|
258
|
-
rhs, rhs_params = self.process_rhs(
|
|
295
|
+
def as_sql(self, compiler, connection):
|
|
296
|
+
_, lhs_params = self.process_lhs(compiler, connection)
|
|
297
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
259
298
|
query = f"{self.ip.q_ip} BETWEEN {rhs} AND {self.ip.bcast_addr}"
|
|
260
299
|
return query, lhs_params + rhs_params
|
|
261
300
|
|
|
@@ -270,12 +309,12 @@ class NetFamily(Lookup):
|
|
|
270
309
|
self.rhs = 16
|
|
271
310
|
return self.rhs
|
|
272
311
|
|
|
273
|
-
def process_lhs(self,
|
|
312
|
+
def process_lhs(self, compiler, connection, lhs=None):
|
|
274
313
|
lhs = lhs or self.lhs
|
|
275
|
-
lhs_string, lhs_params =
|
|
314
|
+
lhs_string, lhs_params = compiler.compile(lhs)
|
|
276
315
|
return f"LENGTH({lhs_string})", lhs_params
|
|
277
316
|
|
|
278
|
-
def as_sql(self,
|
|
279
|
-
lhs, lhs_params = self.process_lhs(
|
|
280
|
-
rhs, rhs_params = self.process_rhs(
|
|
317
|
+
def as_sql(self, compiler, connection):
|
|
318
|
+
lhs, lhs_params = self.process_lhs(compiler, connection)
|
|
319
|
+
rhs, rhs_params = self.process_rhs(compiler, connection)
|
|
281
320
|
return f"{lhs} = {rhs}", lhs_params + rhs_params
|