nautobot 2.2.0__py3-none-any.whl → 2.2.0b1__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/api.py +2 -1
- nautobot/apps/utils.py +0 -4
- nautobot/apps/views.py +0 -2
- nautobot/circuits/api/urls.py +2 -1
- nautobot/circuits/api/views.py +12 -0
- nautobot/circuits/tests/test_filters.py +1 -1
- nautobot/core/api/routers.py +3 -25
- nautobot/core/api/utils.py +0 -4
- nautobot/core/api/views.py +15 -21
- nautobot/core/filters.py +1 -7
- nautobot/core/management/commands/generate_test_data.py +4 -4
- nautobot/core/settings.py +0 -1
- nautobot/core/tables.py +1 -2
- nautobot/core/templates/admin/base.html +94 -23
- nautobot/core/templates/graphene/graphiql.html +47 -18
- nautobot/core/templates/inc/footer.html +5 -5
- nautobot/core/templates/inc/nav_menu.html +7 -0
- nautobot/core/templates/rest_framework/api.html +5 -12
- nautobot/core/templatetags/helpers.py +2 -2
- nautobot/core/testing/views.py +0 -30
- nautobot/core/tests/test_api.py +6 -13
- nautobot/core/tests/test_csv.py +4 -5
- nautobot/core/tests/test_filters.py +1 -2
- nautobot/core/tests/test_graphql.py +14 -4
- nautobot/core/tests/test_navigations.py +0 -3
- nautobot/core/tests/test_views.py +16 -22
- nautobot/core/utils/lookup.py +0 -124
- nautobot/core/views/__init__.py +7 -3
- nautobot/core/views/generic.py +3 -19
- nautobot/core/views/mixins.py +0 -7
- nautobot/core/views/renderers.py +1 -4
- nautobot/dcim/api/serializers.py +4 -4
- nautobot/dcim/api/urls.py +3 -2
- nautobot/dcim/api/views.py +18 -7
- nautobot/dcim/factory.py +7 -7
- nautobot/dcim/filters/__init__.py +17 -16
- nautobot/dcim/forms.py +45 -61
- nautobot/dcim/homepage.py +3 -11
- nautobot/dcim/migrations/0057_controller_models.py +70 -11
- nautobot/dcim/models/__init__.py +2 -2
- nautobot/dcim/models/devices.py +16 -14
- nautobot/dcim/models/racks.py +3 -1
- nautobot/dcim/navigation.py +31 -23
- nautobot/dcim/signals.py +6 -6
- nautobot/dcim/tables/__init__.py +2 -2
- nautobot/dcim/tables/devices.py +15 -12
- nautobot/dcim/tables/template_code.py +1 -1
- nautobot/dcim/templates/dcim/controller_retrieve.html +18 -35
- nautobot/dcim/templates/dcim/controllerdevicegroup_create.html +43 -0
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +43 -67
- nautobot/dcim/templates/dcim/device.html +2 -10
- nautobot/dcim/templates/dcim/device_edit.html +1 -1
- nautobot/dcim/tests/test_api.py +6 -11
- nautobot/dcim/tests/test_filters.py +81 -92
- nautobot/dcim/tests/test_graphql.py +1 -11
- nautobot/dcim/tests/test_models.py +15 -15
- nautobot/dcim/tests/test_signals.py +0 -2
- nautobot/dcim/tests/test_views.py +12 -24
- nautobot/dcim/urls.py +1 -1
- nautobot/dcim/views.py +15 -19
- nautobot/extras/api/urls.py +2 -1
- nautobot/extras/api/views.py +10 -0
- nautobot/extras/filters/__init__.py +2 -53
- nautobot/extras/forms/contacts.py +0 -7
- nautobot/extras/managers.py +0 -14
- nautobot/extras/navigation.py +65 -71
- nautobot/extras/plugins/views.py +11 -7
- nautobot/extras/tests/test_api.py +0 -2
- nautobot/extras/tests/test_dynamicgroups.py +0 -2
- nautobot/extras/tests/test_filters.py +4 -89
- nautobot/extras/tests/test_models.py +0 -9
- nautobot/extras/tests/test_relationships.py +1 -10
- nautobot/extras/tests/test_views.py +1 -112
- nautobot/extras/views.py +10 -10
- nautobot/ipam/api/urls.py +2 -1
- nautobot/ipam/api/views.py +11 -0
- nautobot/ipam/tables.py +22 -2
- nautobot/ipam/tests/test_graphql.py +3 -2
- nautobot/ipam/tests/test_views.py +0 -1
- nautobot/ipam/views.py +9 -9
- nautobot/project-static/css/base.css +0 -1
- nautobot/project-static/docs/404.html +3 -24
- nautobot/project-static/docs/apps/index.html +3 -24
- nautobot/project-static/docs/apps/nautobot-apps.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +5 -26
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +3 -24
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +3 -242
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +5 -69
- nautobot/project-static/docs/development/apps/api/configuration-view.html +3 -24
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +3 -24
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +3 -24
- nautobot/project-static/docs/development/apps/api/models/global-search.html +3 -24
- nautobot/project-static/docs/development/apps/api/models/graphql.html +3 -24
- nautobot/project-static/docs/development/apps/api/models/index.html +3 -24
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +3 -24
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +3 -24
- nautobot/project-static/docs/development/apps/api/prometheus.html +3 -24
- nautobot/project-static/docs/development/apps/api/setup.html +3 -24
- nautobot/project-static/docs/development/apps/api/testing.html +3 -24
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +3 -24
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +3 -24
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +3 -24
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +3 -24
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/base-template.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +12 -38
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +15 -41
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/index.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/notes.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +3 -24
- nautobot/project-static/docs/development/apps/api/views/urls.html +3 -24
- nautobot/project-static/docs/development/apps/index.html +3 -24
- nautobot/project-static/docs/development/apps/migration/code-updates.html +3 -24
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +3 -24
- nautobot/project-static/docs/development/apps/migration/from-v1.html +3 -24
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +3 -24
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +3 -24
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +3 -24
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +3 -24
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +3 -24
- nautobot/project-static/docs/development/core/application-registry.html +3 -24
- nautobot/project-static/docs/development/core/best-practices.html +3 -24
- nautobot/project-static/docs/development/core/bootstrap-ui.html +3 -24
- nautobot/project-static/docs/development/core/caching.html +3 -24
- nautobot/project-static/docs/development/core/controllers.html +204 -35
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +3 -24
- nautobot/project-static/docs/development/core/extending-models.html +3 -24
- nautobot/project-static/docs/development/core/generic-views.html +3 -24
- nautobot/project-static/docs/development/core/getting-started.html +13 -43
- nautobot/project-static/docs/development/core/homepage.html +3 -24
- nautobot/project-static/docs/development/core/index.html +3 -24
- nautobot/project-static/docs/development/core/model-features.html +3 -24
- nautobot/project-static/docs/development/core/natural-keys.html +3 -24
- nautobot/project-static/docs/development/core/navigation-menu.html +3 -24
- nautobot/project-static/docs/development/core/release-checklist.html +3 -24
- nautobot/project-static/docs/development/core/role-internals.html +3 -24
- nautobot/project-static/docs/development/core/settings.html +3 -24
- nautobot/project-static/docs/development/core/style-guide.html +3 -24
- nautobot/project-static/docs/development/core/templates.html +3 -24
- nautobot/project-static/docs/development/core/testing.html +3 -24
- nautobot/project-static/docs/development/core/user-preferences.html +3 -24
- nautobot/project-static/docs/development/index.html +3 -24
- nautobot/project-static/docs/development/jobs/index.html +3 -24
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +3 -24
- nautobot/project-static/docs/index.html +3 -24
- nautobot/project-static/docs/models/dcim/{controllermanageddevicegroup.html → controllerdevicegroup.html} +3 -3
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.0.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.1.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.2.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.3.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.4.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.5.html +3 -24
- nautobot/project-static/docs/release-notes/version-1.6.html +3 -24
- nautobot/project-static/docs/release-notes/version-2.0.html +3 -24
- nautobot/project-static/docs/release-notes/version-2.1.html +162 -411
- nautobot/project-static/docs/release-notes/version-2.2.html +30 -212
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +255 -260
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +3 -24
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +3 -24
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +6 -31
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/index.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +3 -24
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +6 -27
- nautobot/project-static/docs/user-guide/administration/installation/services.html +3 -24
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +3 -24
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +3 -24
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +3 -24
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +3 -24
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +11 -259
- nautobot/project-static/docs/user-guide/core-data-model/dcim/{controllermanageddevicegroup.html → controllerdevicegroup.html} +17 -107
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +6 -27
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +3 -24
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/{contacts-and-teams.html → contact-and-team.html} +4 -25
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +5 -26
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +5 -26
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +3 -24
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +3 -24
- nautobot/project-static/docs/user-guide/index.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +3 -24
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +3 -24
- nautobot/tenancy/api/urls.py +2 -1
- nautobot/tenancy/api/views.py +12 -0
- nautobot/tenancy/tables.py +1 -1
- nautobot/tenancy/tests/test_views.py +0 -1
- nautobot/users/api/urls.py +2 -1
- nautobot/users/api/views.py +65 -2
- nautobot/users/views.py +8 -8
- nautobot/virtualization/api/urls.py +2 -1
- nautobot/virtualization/api/views.py +12 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/METADATA +3 -3
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/RECORD +356 -361
- nautobot/core/tests/integration/test_view_authentication.py +0 -67
- nautobot/dcim/management/commands/migrate_location_contacts.py +0 -218
- nautobot/dcim/templates/dcim/controller_create.html +0 -70
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +0 -88
- nautobot/ipam/tests/test_tables.py +0 -42
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +0 -8581
- /nautobot/dcim/templates/dcim/{controllermanageddevicegroup_retrieve.html → controllerdevicegroup_retrieve.html} +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/NOTICE +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/WHEEL +0 -0
- {nautobot-2.2.0.dist-info → nautobot-2.2.0b1.dist-info}/entry_points.txt +0 -0
|
@@ -61,7 +61,6 @@ from nautobot.extras.models import (
|
|
|
61
61
|
ComputedField,
|
|
62
62
|
ConfigContext,
|
|
63
63
|
Contact,
|
|
64
|
-
ContactAssociation,
|
|
65
64
|
CustomField,
|
|
66
65
|
CustomFieldChoice,
|
|
67
66
|
CustomLink,
|
|
@@ -458,91 +457,7 @@ class ContentTypeFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
|
458
457
|
)
|
|
459
458
|
|
|
460
459
|
|
|
461
|
-
class
|
|
462
|
-
"""Mixin class to test common filters to both Contact and Team filter sets."""
|
|
463
|
-
|
|
464
|
-
def test_similar_to_location_data(self):
|
|
465
|
-
"""Complex test to test the complex `similar_to_location_data` method filter."""
|
|
466
|
-
ContactAssociation.objects.all().delete()
|
|
467
|
-
self.queryset.delete()
|
|
468
|
-
location_type = LocationType.objects.filter(parent__isnull=True).first()
|
|
469
|
-
location_status = Status.objects.get_for_model(Location).first()
|
|
470
|
-
test_locations = (
|
|
471
|
-
Location.objects.create(
|
|
472
|
-
location_type=location_type,
|
|
473
|
-
name="Filter Test Location 0",
|
|
474
|
-
status=location_status,
|
|
475
|
-
contact_name="match 0",
|
|
476
|
-
),
|
|
477
|
-
Location.objects.create(
|
|
478
|
-
location_type=location_type,
|
|
479
|
-
name="Filter Test Location 1",
|
|
480
|
-
status=location_status,
|
|
481
|
-
contact_email="Test email for location 1 and 2",
|
|
482
|
-
),
|
|
483
|
-
Location.objects.create(
|
|
484
|
-
location_type=location_type,
|
|
485
|
-
name="Filter Test Location 2",
|
|
486
|
-
status=location_status,
|
|
487
|
-
contact_email="TEST EMAIL FOR LOCATION 1 AND 2",
|
|
488
|
-
contact_phone="Test phone for location 2 and 3",
|
|
489
|
-
),
|
|
490
|
-
Location.objects.create(
|
|
491
|
-
location_type=location_type,
|
|
492
|
-
name="Filter Test Location 3",
|
|
493
|
-
status=location_status,
|
|
494
|
-
contact_phone="Test phone for location 2 and 3",
|
|
495
|
-
),
|
|
496
|
-
Location.objects.create(
|
|
497
|
-
location_type=location_type,
|
|
498
|
-
name="Filter Test Location 4",
|
|
499
|
-
status=location_status,
|
|
500
|
-
contact_name="Hopefully this doesn't match any random factory data",
|
|
501
|
-
contact_email="Hopefully this doesn't match any random factory data",
|
|
502
|
-
contact_phone="Hopefully this doesn't match any random factory data",
|
|
503
|
-
physical_address="Hopefully this doesn't match any random factory data",
|
|
504
|
-
shipping_address="Hopefully this doesn't match any random factory data",
|
|
505
|
-
),
|
|
506
|
-
)
|
|
507
|
-
|
|
508
|
-
self.queryset.create(name="match 0")
|
|
509
|
-
self.queryset.create(name="match 1 and 2", email="Test email for location 1 and 2")
|
|
510
|
-
self.queryset.create(name="match 2 and 3", phone="Test phone for location 2 and 3")
|
|
511
|
-
|
|
512
|
-
# These subtests are confusing because we're trying to test the NaturalKeyOrPKMultipleChoiceFilter
|
|
513
|
-
# behavior while also testing the `similar_to_location_data` method filter behavior.
|
|
514
|
-
with self.subTest("Test name match"):
|
|
515
|
-
params = {"similar_to_location_data": [test_locations[0].pk]}
|
|
516
|
-
self.assertQuerysetEqualAndNotEmpty(
|
|
517
|
-
self.filterset(params, self.queryset).qs,
|
|
518
|
-
self.queryset.filter(name__in=["match 0"]),
|
|
519
|
-
)
|
|
520
|
-
with self.subTest("Test email match"):
|
|
521
|
-
params = {"similar_to_location_data": [test_locations[1].pk]}
|
|
522
|
-
self.assertQuerysetEqualAndNotEmpty(
|
|
523
|
-
self.filterset(params, self.queryset).qs,
|
|
524
|
-
self.queryset.filter(name__in=["match 1 and 2"]),
|
|
525
|
-
)
|
|
526
|
-
with self.subTest("Test phone match"):
|
|
527
|
-
params = {"similar_to_location_data": [test_locations[2].pk]}
|
|
528
|
-
self.assertQuerysetEqualAndNotEmpty(
|
|
529
|
-
self.filterset(params, self.queryset).qs,
|
|
530
|
-
self.queryset.filter(name__in=["match 1 and 2", "match 2 and 3"]),
|
|
531
|
-
)
|
|
532
|
-
with self.subTest("Test email and phone match"):
|
|
533
|
-
params = {"similar_to_location_data": [test_locations[1].pk, test_locations[3].name]}
|
|
534
|
-
self.assertQuerysetEqualAndNotEmpty(
|
|
535
|
-
self.filterset(params, self.queryset).qs,
|
|
536
|
-
self.queryset.filter(name__in=["match 1 and 2", "match 2 and 3"]),
|
|
537
|
-
)
|
|
538
|
-
with self.subTest("Test no match"):
|
|
539
|
-
params = {"similar_to_location_data": [test_locations[4].pk]}
|
|
540
|
-
self.assertFalse(self.filterset(params, self.queryset).qs.exists())
|
|
541
|
-
params = {"similar_to_location_data": [test_locations[4].name]}
|
|
542
|
-
self.assertFalse(self.filterset(params, self.queryset).qs.exists())
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
class ContactFilterSetTestCase(ContactAndTeamFilterSetTestCaseMixin, FilterTestCases.FilterTestCase):
|
|
460
|
+
class ContactFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
546
461
|
queryset = Contact.objects.all()
|
|
547
462
|
filterset = ContactFilterSet
|
|
548
463
|
|
|
@@ -1841,7 +1756,7 @@ class TagTestCase(FilterTestCases.NameOnlyFilterTestCase):
|
|
|
1841
1756
|
self.assertEqual(self.filterset(params, self.queryset).qs.values_list("pk", flat=True)[0], value)
|
|
1842
1757
|
|
|
1843
1758
|
|
|
1844
|
-
class TeamFilterSetTestCase(
|
|
1759
|
+
class TeamFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
1845
1760
|
queryset = Team.objects.all()
|
|
1846
1761
|
filterset = TeamFilterSet
|
|
1847
1762
|
|
|
@@ -1923,8 +1838,8 @@ class RoleTestCase(FilterTestCases.NameOnlyFilterTestCase):
|
|
|
1923
1838
|
def test_content_types(self):
|
|
1924
1839
|
device_ct = ContentType.objects.get_for_model(Device)
|
|
1925
1840
|
rack_ct = ContentType.objects.get_for_model(Rack)
|
|
1926
|
-
device_roles = self.queryset.filter(
|
|
1927
|
-
params = {"content_types": ["dcim.device"
|
|
1841
|
+
device_roles = self.queryset.filter(content_types=device_ct)
|
|
1842
|
+
params = {"content_types": ["dcim.device"]}
|
|
1928
1843
|
self.assertQuerysetEqualAndNotEmpty(self.filterset(params, self.queryset).qs, device_roles)
|
|
1929
1844
|
|
|
1930
1845
|
rack_roles = self.queryset.filter(content_types=rack_ct)
|
|
@@ -1810,15 +1810,6 @@ class JobResultTestCase(TestCase):
|
|
|
1810
1810
|
JobResult.objects.create(name="ExampleJob2", user=None, result=lambda: 1)
|
|
1811
1811
|
self.assertEqual(str(err.exception), "Object of type function is not JSON serializable")
|
|
1812
1812
|
|
|
1813
|
-
def test_get_task(self):
|
|
1814
|
-
"""Assert bug fix for `Cannot resolve keyword 'task_id' into field` #5440"""
|
|
1815
|
-
data = {
|
|
1816
|
-
"output": "valid data",
|
|
1817
|
-
}
|
|
1818
|
-
job_result = JobResult.objects.create(name="ExampleJob1", user=None, result=data)
|
|
1819
|
-
|
|
1820
|
-
self.assertEqual(JobResult.objects.get_task(job_result.pk), job_result)
|
|
1821
|
-
|
|
1822
1813
|
|
|
1823
1814
|
class WebhookTest(ModelTestCases.BaseModelTestCase):
|
|
1824
1815
|
model = Webhook
|
|
@@ -15,15 +15,7 @@ from nautobot.core.tables import RelationshipColumn
|
|
|
15
15
|
from nautobot.core.testing import TestCase
|
|
16
16
|
from nautobot.core.testing.models import ModelTestCases
|
|
17
17
|
from nautobot.core.utils.lookup import get_route_for_model
|
|
18
|
-
from nautobot.dcim.models import
|
|
19
|
-
Controller,
|
|
20
|
-
Device,
|
|
21
|
-
DeviceTypeToSoftwareImageFile,
|
|
22
|
-
Location,
|
|
23
|
-
LocationType,
|
|
24
|
-
Platform,
|
|
25
|
-
Rack,
|
|
26
|
-
)
|
|
18
|
+
from nautobot.dcim.models import Device, DeviceTypeToSoftwareImageFile, Location, LocationType, Platform, Rack
|
|
27
19
|
from nautobot.dcim.tables import LocationTable
|
|
28
20
|
from nautobot.dcim.tests.test_views import create_test_device
|
|
29
21
|
from nautobot.extras.choices import RelationshipRequiredSideChoices, RelationshipSideChoices, RelationshipTypeChoices
|
|
@@ -1173,7 +1165,6 @@ class RequiredRelationshipTestMixin:
|
|
|
1173
1165
|
# Protected FK to SoftwareImageFile prevents deletion
|
|
1174
1166
|
DeviceTypeToSoftwareImageFile.objects.all().delete()
|
|
1175
1167
|
# Protected FK to SoftwareVersion prevents deletion
|
|
1176
|
-
Controller.objects.all().delete()
|
|
1177
1168
|
Device.objects.all().update(software_version=None)
|
|
1178
1169
|
|
|
1179
1170
|
# Create required relationships:
|
|
@@ -17,21 +17,11 @@ from nautobot.core.choices import ColorChoices
|
|
|
17
17
|
from nautobot.core.models.fields import slugify_dashes_to_underscores
|
|
18
18
|
from nautobot.core.testing import extract_form_failures, extract_page_body, TestCase, ViewTestCases
|
|
19
19
|
from nautobot.core.testing.utils import disable_warnings, post_data
|
|
20
|
-
from nautobot.dcim.models import
|
|
21
|
-
ConsolePort,
|
|
22
|
-
Controller,
|
|
23
|
-
Device,
|
|
24
|
-
DeviceType,
|
|
25
|
-
Interface,
|
|
26
|
-
Location,
|
|
27
|
-
LocationType,
|
|
28
|
-
Manufacturer,
|
|
29
|
-
)
|
|
20
|
+
from nautobot.dcim.models import ConsolePort, Device, DeviceType, Interface, Location, LocationType, Manufacturer
|
|
30
21
|
from nautobot.dcim.tests import test_views
|
|
31
22
|
from nautobot.extras.choices import (
|
|
32
23
|
CustomFieldTypeChoices,
|
|
33
24
|
JobExecutionType,
|
|
34
|
-
LogLevelChoices,
|
|
35
25
|
ObjectChangeActionChoices,
|
|
36
26
|
SecretsGroupAccessTypeChoices,
|
|
37
27
|
SecretsGroupSecretTypeChoices,
|
|
@@ -53,7 +43,6 @@ from nautobot.extras.models import (
|
|
|
53
43
|
GraphQLQuery,
|
|
54
44
|
Job,
|
|
55
45
|
JobButton,
|
|
56
|
-
JobLogEntry,
|
|
57
46
|
JobResult,
|
|
58
47
|
Note,
|
|
59
48
|
ObjectChange,
|
|
@@ -792,49 +781,6 @@ class DynamicGroupTestCase(
|
|
|
792
781
|
"dynamic_group_memberships-MAX_NUM_FORMS": "1000",
|
|
793
782
|
}
|
|
794
783
|
|
|
795
|
-
def test_get_object_dynamic_groups_anonymous(self):
|
|
796
|
-
url = reverse("dcim:device_dynamicgroups", kwargs={"pk": Device.objects.first().pk})
|
|
797
|
-
self.client.logout()
|
|
798
|
-
response = self.client.get(url, follow=True)
|
|
799
|
-
self.assertHttpStatus(response, 200)
|
|
800
|
-
self.assertRedirects(response, f"/login/?next={url}")
|
|
801
|
-
|
|
802
|
-
def test_get_object_dynamic_groups_without_permission(self):
|
|
803
|
-
url = reverse("dcim:device_dynamicgroups", kwargs={"pk": Device.objects.first().pk})
|
|
804
|
-
response = self.client.get(url)
|
|
805
|
-
self.assertHttpStatus(response, [403, 404])
|
|
806
|
-
|
|
807
|
-
def test_get_object_dynamic_groups_with_permission(self):
|
|
808
|
-
url = reverse("dcim:device_dynamicgroups", kwargs={"pk": Device.objects.first().pk})
|
|
809
|
-
self.add_permissions("dcim.view_device", "extras.view_dynamicgroup")
|
|
810
|
-
response = self.client.get(url)
|
|
811
|
-
self.assertHttpStatus(response, 200)
|
|
812
|
-
response_body = response.content.decode(response.charset)
|
|
813
|
-
self.assertIn("DG 1", response_body, msg=response_body)
|
|
814
|
-
self.assertIn("DG 2", response_body, msg=response_body)
|
|
815
|
-
self.assertIn("DG 3", response_body, msg=response_body)
|
|
816
|
-
|
|
817
|
-
def test_get_object_dynamic_groups_with_constrained_permission(self):
|
|
818
|
-
self.add_permissions("extras.view_dynamicgroup")
|
|
819
|
-
obj_perm = ObjectPermission(
|
|
820
|
-
name="View a device",
|
|
821
|
-
constraints={"pk": Device.objects.first().pk},
|
|
822
|
-
actions=["view"],
|
|
823
|
-
)
|
|
824
|
-
obj_perm.save()
|
|
825
|
-
obj_perm.users.add(self.user)
|
|
826
|
-
obj_perm.object_types.add(ContentType.objects.get_for_model(Device))
|
|
827
|
-
|
|
828
|
-
url = reverse("dcim:device_dynamicgroups", kwargs={"pk": Device.objects.first().pk})
|
|
829
|
-
response = self.client.get(url)
|
|
830
|
-
self.assertHttpStatus(response, 200)
|
|
831
|
-
response_body = response.content.decode(response.charset)
|
|
832
|
-
self.assertIn("DG 1", response_body, msg=response_body)
|
|
833
|
-
|
|
834
|
-
url = reverse("dcim:device_dynamicgroups", kwargs={"pk": Device.objects.last().pk})
|
|
835
|
-
response = self.client.get(url)
|
|
836
|
-
self.assertHttpStatus(response, 404)
|
|
837
|
-
|
|
838
784
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
839
785
|
def test_edit_saved_filter(self):
|
|
840
786
|
"""Test that editing a filter works using the edit view."""
|
|
@@ -990,34 +936,6 @@ class GitRepositoryTestCase(
|
|
|
990
936
|
self.form_data = form_data
|
|
991
937
|
super().test_edit_object_with_constrained_permission()
|
|
992
938
|
|
|
993
|
-
def test_post_sync_repo_anonymous(self):
|
|
994
|
-
self.client.logout()
|
|
995
|
-
url = reverse("extras:gitrepository_sync", kwargs={"pk": self._get_queryset().first().pk})
|
|
996
|
-
response = self.client.post(url, follow=True)
|
|
997
|
-
self.assertHttpStatus(response, 200)
|
|
998
|
-
self.assertRedirects(response, f"/login/?next={url}")
|
|
999
|
-
|
|
1000
|
-
def test_post_sync_repo_without_permission(self):
|
|
1001
|
-
url = reverse("extras:gitrepository_sync", kwargs={"pk": self._get_queryset().first().pk})
|
|
1002
|
-
response = self.client.post(url)
|
|
1003
|
-
self.assertHttpStatus(response, [403, 404])
|
|
1004
|
-
|
|
1005
|
-
# TODO: mock/stub out `enqueue_pull_git_repository_and_refresh_data` and test successful POST with permissions
|
|
1006
|
-
|
|
1007
|
-
def test_post_dryrun_repo_anonymous(self):
|
|
1008
|
-
self.client.logout()
|
|
1009
|
-
url = reverse("extras:gitrepository_dryrun", kwargs={"pk": self._get_queryset().first().pk})
|
|
1010
|
-
response = self.client.post(url, follow=True)
|
|
1011
|
-
self.assertHttpStatus(response, 200)
|
|
1012
|
-
self.assertRedirects(response, f"/login/?next={url}")
|
|
1013
|
-
|
|
1014
|
-
def test_post_dryrun_repo_without_permission(self):
|
|
1015
|
-
url = reverse("extras:gitrepository_dryrun", kwargs={"pk": self._get_queryset().first().pk})
|
|
1016
|
-
response = self.client.post(url)
|
|
1017
|
-
self.assertHttpStatus(response, [403, 404])
|
|
1018
|
-
|
|
1019
|
-
# TODO: mock/stub out `enqueue_git_repository_diff_origin_and_local` and test successful POST with permissions
|
|
1020
|
-
|
|
1021
939
|
|
|
1022
940
|
class NoteTestCase(
|
|
1023
941
|
ViewTestCases.CreateObjectViewTestCase,
|
|
@@ -1718,34 +1636,6 @@ class JobResultTestCase(
|
|
|
1718
1636
|
def setUpTestData(cls):
|
|
1719
1637
|
JobResult.objects.create(name="pass.TestPass")
|
|
1720
1638
|
JobResult.objects.create(name="fail.TestFail")
|
|
1721
|
-
JobLogEntry.objects.create(
|
|
1722
|
-
log_level=LogLevelChoices.LOG_INFO,
|
|
1723
|
-
job_result=JobResult.objects.first(),
|
|
1724
|
-
grouping="run",
|
|
1725
|
-
message="This is a test",
|
|
1726
|
-
)
|
|
1727
|
-
|
|
1728
|
-
def test_get_joblogentrytable_anonymous(self):
|
|
1729
|
-
url = reverse("extras:jobresult_log-table", kwargs={"pk": JobResult.objects.first().pk})
|
|
1730
|
-
self.client.logout()
|
|
1731
|
-
response = self.client.get(url, follow=True)
|
|
1732
|
-
self.assertHttpStatus(response, 200)
|
|
1733
|
-
self.assertRedirects(response, f"/login/?next={url}")
|
|
1734
|
-
|
|
1735
|
-
def test_get_joblogentrytable_without_permission(self):
|
|
1736
|
-
url = reverse("extras:jobresult_log-table", kwargs={"pk": JobResult.objects.first().pk})
|
|
1737
|
-
response = self.client.get(url)
|
|
1738
|
-
self.assertHttpStatus(response, [403, 404])
|
|
1739
|
-
|
|
1740
|
-
def test_get_joblogentrytable_with_permission(self):
|
|
1741
|
-
url = reverse("extras:jobresult_log-table", kwargs={"pk": JobResult.objects.first().pk})
|
|
1742
|
-
self.add_permissions("extras.view_jobresult", "extras.view_joblogentry")
|
|
1743
|
-
response = self.client.get(url)
|
|
1744
|
-
self.assertHttpStatus(response, 200)
|
|
1745
|
-
response_body = response.content.decode(response.charset)
|
|
1746
|
-
self.assertIn("This is a test", response_body)
|
|
1747
|
-
|
|
1748
|
-
# TODO test with constrained permissions on both JobResult and JobLogEntry records
|
|
1749
1639
|
|
|
1750
1640
|
|
|
1751
1641
|
class JobTestCase(
|
|
@@ -2598,7 +2488,6 @@ class RelationshipTestCase(
|
|
|
2598
2488
|
)
|
|
2599
2489
|
|
|
2600
2490
|
# Try deleting all devices and then editing the 6 VLANs (fails):
|
|
2601
|
-
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
2602
2491
|
Device.objects.all().delete()
|
|
2603
2492
|
response = self.client.post(
|
|
2604
2493
|
reverse("ipam:vlan_bulk_edit"), data={"pk": [str(vlan.id) for vlan in vlans], "_apply": [""]}
|
nautobot/extras/views.py
CHANGED
|
@@ -917,7 +917,7 @@ class DynamicGroupBulkDeleteView(generic.BulkDeleteView):
|
|
|
917
917
|
filterset = filters.DynamicGroupFilterSet
|
|
918
918
|
|
|
919
919
|
|
|
920
|
-
class ObjectDynamicGroupsView(
|
|
920
|
+
class ObjectDynamicGroupsView(View):
|
|
921
921
|
"""
|
|
922
922
|
Present a list of dynamic groups associated to a particular object.
|
|
923
923
|
base_template: The name of the template to extend. If not provided, "<app>/<model>.html" will be used.
|
|
@@ -1116,18 +1116,18 @@ def check_and_call_git_repository_function(request, pk, func):
|
|
|
1116
1116
|
messages.error(request, "Unable to run job: Celery worker process not running.")
|
|
1117
1117
|
return redirect(request.get_full_path(), permanent=False)
|
|
1118
1118
|
else:
|
|
1119
|
-
repository = get_object_or_404(GitRepository
|
|
1119
|
+
repository = get_object_or_404(GitRepository, pk=pk)
|
|
1120
1120
|
job_result = func(repository, request.user)
|
|
1121
1121
|
|
|
1122
1122
|
return redirect(job_result.get_absolute_url())
|
|
1123
1123
|
|
|
1124
1124
|
|
|
1125
|
-
class GitRepositorySyncView(
|
|
1125
|
+
class GitRepositorySyncView(View):
|
|
1126
1126
|
def post(self, request, pk):
|
|
1127
1127
|
return check_and_call_git_repository_function(request, pk, enqueue_pull_git_repository_and_refresh_data)
|
|
1128
1128
|
|
|
1129
1129
|
|
|
1130
|
-
class GitRepositoryDryRunView(
|
|
1130
|
+
class GitRepositoryDryRunView(View):
|
|
1131
1131
|
def post(self, request, pk):
|
|
1132
1132
|
return check_and_call_git_repository_function(request, pk, enqueue_git_repository_diff_origin_and_local)
|
|
1133
1133
|
|
|
@@ -1806,7 +1806,7 @@ class JobResultView(generic.ObjectView):
|
|
|
1806
1806
|
}
|
|
1807
1807
|
|
|
1808
1808
|
|
|
1809
|
-
class JobLogEntryTableView(
|
|
1809
|
+
class JobLogEntryTableView(View):
|
|
1810
1810
|
"""
|
|
1811
1811
|
Display a table of `JobLogEntry` objects for a given `JobResult` instance.
|
|
1812
1812
|
"""
|
|
@@ -1814,7 +1814,7 @@ class JobLogEntryTableView(generic.GenericView):
|
|
|
1814
1814
|
queryset = JobResult.objects.all()
|
|
1815
1815
|
|
|
1816
1816
|
def get(self, request, pk=None):
|
|
1817
|
-
instance =
|
|
1817
|
+
instance = self.queryset.get(pk=pk)
|
|
1818
1818
|
filter_q = request.GET.get("q")
|
|
1819
1819
|
if filter_q:
|
|
1820
1820
|
queryset = instance.job_log_entries.filter(
|
|
@@ -1893,7 +1893,7 @@ class ObjectChangeView(generic.ObjectView):
|
|
|
1893
1893
|
}
|
|
1894
1894
|
|
|
1895
1895
|
|
|
1896
|
-
class ObjectChangeLogView(
|
|
1896
|
+
class ObjectChangeLogView(View):
|
|
1897
1897
|
"""
|
|
1898
1898
|
Present a history of changes made to a particular object.
|
|
1899
1899
|
base_template: The name of the template to extend. If not provided, "<app>/<model>.html" will be used.
|
|
@@ -1979,7 +1979,7 @@ class NoteDeleteView(generic.ObjectDeleteView):
|
|
|
1979
1979
|
queryset = Note.objects.all()
|
|
1980
1980
|
|
|
1981
1981
|
|
|
1982
|
-
class ObjectNotesView(
|
|
1982
|
+
class ObjectNotesView(View):
|
|
1983
1983
|
"""
|
|
1984
1984
|
Present a list of notes associated to a particular object.
|
|
1985
1985
|
base_template: The name of the template to extend. If not provided, "<app>/<model>.html" will be used.
|
|
@@ -2000,7 +2000,7 @@ class ObjectNotesView(generic.GenericView):
|
|
|
2000
2000
|
"assigned_object_id": obj.pk,
|
|
2001
2001
|
}
|
|
2002
2002
|
)
|
|
2003
|
-
notes_table = tables.NoteTable(obj.notes
|
|
2003
|
+
notes_table = tables.NoteTable(obj.notes)
|
|
2004
2004
|
|
|
2005
2005
|
# Apply the request context
|
|
2006
2006
|
paginate = {
|
|
@@ -2241,7 +2241,7 @@ class SecretView(generic.ObjectView):
|
|
|
2241
2241
|
}
|
|
2242
2242
|
|
|
2243
2243
|
|
|
2244
|
-
class SecretProviderParametersFormView(
|
|
2244
|
+
class SecretProviderParametersFormView(View):
|
|
2245
2245
|
"""
|
|
2246
2246
|
Helper view to SecretView; retrieve the HTML form appropriate for entering parameters for a given SecretsProvider.
|
|
2247
2247
|
"""
|
nautobot/ipam/api/urls.py
CHANGED
|
@@ -2,7 +2,8 @@ from nautobot.core.api.routers import OrderedDefaultRouter
|
|
|
2
2
|
|
|
3
3
|
from . import views
|
|
4
4
|
|
|
5
|
-
router = OrderedDefaultRouter(
|
|
5
|
+
router = OrderedDefaultRouter()
|
|
6
|
+
router.APIRootView = views.IPAMRootView
|
|
6
7
|
|
|
7
8
|
# Namespaces
|
|
8
9
|
router.register("namespaces", views.NamespaceViewSet)
|
nautobot/ipam/api/views.py
CHANGED
|
@@ -6,6 +6,7 @@ from rest_framework import status
|
|
|
6
6
|
from rest_framework.decorators import action
|
|
7
7
|
from rest_framework.exceptions import APIException
|
|
8
8
|
from rest_framework.response import Response
|
|
9
|
+
from rest_framework.routers import APIRootView
|
|
9
10
|
|
|
10
11
|
from nautobot.core.models.querysets import count_related
|
|
11
12
|
from nautobot.core.utils.config import get_settings_or_config
|
|
@@ -31,6 +32,16 @@ from nautobot.ipam.models import (
|
|
|
31
32
|
|
|
32
33
|
from . import serializers
|
|
33
34
|
|
|
35
|
+
|
|
36
|
+
class IPAMRootView(APIRootView):
|
|
37
|
+
"""
|
|
38
|
+
IPAM API root view
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def get_view_name(self):
|
|
42
|
+
return "IPAM"
|
|
43
|
+
|
|
44
|
+
|
|
34
45
|
#
|
|
35
46
|
# Namespace
|
|
36
47
|
#
|
nautobot/ipam/tables.py
CHANGED
|
@@ -42,10 +42,28 @@ UTILIZATION_GRAPH = """
|
|
|
42
42
|
{% if record.present_in_database %}{% utilization_graph record.get_utilization %}{% else %}—{% endif %}
|
|
43
43
|
"""
|
|
44
44
|
|
|
45
|
+
PREFIX_LINK = """
|
|
46
|
+
{% load helpers %}
|
|
47
|
+
{% for i in record.ancestors.count|as_range %}
|
|
48
|
+
<i class="mdi mdi-circle-small"></i>
|
|
49
|
+
{% endfor %}
|
|
50
|
+
<a href="\
|
|
51
|
+
{% if record.present_in_database %}\
|
|
52
|
+
{% url 'ipam:prefix' pk=record.pk %}\
|
|
53
|
+
{% else %}\
|
|
54
|
+
{% url 'ipam:prefix_add' %}\
|
|
55
|
+
?prefix={{ record }}&namespace={{ object.namespace.pk }}\
|
|
56
|
+
{% for loc in object.locations.all %}&locations={{ loc.pk }}{% endfor %}\
|
|
57
|
+
{% if object.tenant %}&tenant_group={{ object.tenant.tenant_group.pk }}&tenant={{ object.tenant.pk }}{% endif %}\
|
|
58
|
+
{% endif %}\
|
|
59
|
+
">{{ record.prefix }}</a>
|
|
60
|
+
"""
|
|
45
61
|
|
|
46
62
|
PREFIX_COPY_LINK = """
|
|
47
63
|
{% load helpers %}
|
|
48
|
-
{%
|
|
64
|
+
{% for i in record.ancestors.count|as_range %}
|
|
65
|
+
<i class="mdi mdi-circle-small"></i>
|
|
66
|
+
{% endfor %}
|
|
49
67
|
<span class="hover_copy">
|
|
50
68
|
<a href="\
|
|
51
69
|
{% if record.present_in_database %}\
|
|
@@ -161,6 +179,7 @@ VLAN_LINK = """
|
|
|
161
179
|
{% url 'ipam:vlan_add' %}\
|
|
162
180
|
?vid={{ record.vid }}&vlan_group={{ vlan_group.pk }}\
|
|
163
181
|
{% if vlan_group.location %}&location={{ vlan_group.location.pk }}{% endif %}\
|
|
182
|
+
{% if vlan_group.location %}&location={{ vlan_group.location.pk }}{% endif %}\
|
|
164
183
|
" class="btn btn-xs btn-success">{{ record.available }} VLAN{{ record.available|pluralize }} available</a>\
|
|
165
184
|
{% else %}
|
|
166
185
|
{{ record.available }} VLAN{{ record.available|pluralize }} available
|
|
@@ -350,7 +369,7 @@ class PrefixTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
|
350
369
|
namespace = tables.Column(linkify=True)
|
|
351
370
|
vlan = tables.Column(linkify=True, verbose_name="VLAN")
|
|
352
371
|
rir = tables.Column(linkify=True)
|
|
353
|
-
children = tables.Column(accessor="descendants_count"
|
|
372
|
+
children = tables.Column(accessor="descendants_count")
|
|
354
373
|
date_allocated = tables.DateTimeColumn()
|
|
355
374
|
location_count = LinkedCountColumn(
|
|
356
375
|
viewname="dcim:location_list", url_params={"prefixes": "pk"}, verbose_name="Locations"
|
|
@@ -358,6 +377,7 @@ class PrefixTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
|
358
377
|
|
|
359
378
|
class Meta(BaseTable.Meta):
|
|
360
379
|
model = Prefix
|
|
380
|
+
orderable = False
|
|
361
381
|
fields = (
|
|
362
382
|
"pk",
|
|
363
383
|
"prefix",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from django.test import override_settings
|
|
1
2
|
from django.urls import reverse
|
|
2
3
|
from rest_framework import status
|
|
3
4
|
|
|
@@ -8,8 +9,8 @@ class TestPrefix(APITestCase):
|
|
|
8
9
|
def setUp(self):
|
|
9
10
|
super().setUp()
|
|
10
11
|
self.api_url = reverse("graphql-api")
|
|
11
|
-
self.add_permissions("ipam.view_prefix")
|
|
12
12
|
|
|
13
|
+
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
13
14
|
def test_prefix_ip_version(self):
|
|
14
15
|
"""Test ip_version is available for a Prefix via GraphQL."""
|
|
15
16
|
get_prefixes_query = """
|
|
@@ -22,7 +23,7 @@ class TestPrefix(APITestCase):
|
|
|
22
23
|
}
|
|
23
24
|
"""
|
|
24
25
|
payload = {"query": get_prefixes_query}
|
|
25
|
-
response = self.client.post(self.api_url, payload, format="json"
|
|
26
|
+
response = self.client.post(self.api_url, payload, format="json")
|
|
26
27
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
27
28
|
prefixes = response.data["data"]["prefixes"]
|
|
28
29
|
self.assertIsInstance(prefixes, list)
|
|
@@ -126,7 +126,6 @@ class RIRTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|
|
126
126
|
|
|
127
127
|
class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase, ViewTestCases.ListObjectsViewTestCase):
|
|
128
128
|
model = Prefix
|
|
129
|
-
filter_on_field = "prefix_length"
|
|
130
129
|
|
|
131
130
|
@classmethod
|
|
132
131
|
def setUpTestData(cls):
|
nautobot/ipam/views.py
CHANGED
|
@@ -793,7 +793,7 @@ class IPAddressEditView(generic.ObjectEditView):
|
|
|
793
793
|
_, error_msg = retrieve_interface_or_vminterface_from_request(request)
|
|
794
794
|
if error_msg:
|
|
795
795
|
messages.warning(request, error_msg)
|
|
796
|
-
return redirect(self.get_return_url(request, default_return_url="ipam:ipaddress_add")
|
|
796
|
+
return redirect(self.get_return_url(request), default_return_url="ipam:ipaddress_add")
|
|
797
797
|
|
|
798
798
|
return super().dispatch(request, *args, **kwargs)
|
|
799
799
|
|
|
@@ -876,17 +876,17 @@ class IPAddressAssignView(view_mixins.GetReturnURLMixin, generic.ObjectView):
|
|
|
876
876
|
"""
|
|
877
877
|
|
|
878
878
|
queryset = IPAddress.objects.all()
|
|
879
|
+
default_return_url = "ipam:ipaddress_add"
|
|
879
880
|
|
|
880
881
|
def dispatch(self, request, *args, **kwargs):
|
|
881
|
-
if
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
return redirect(self.get_return_url(request, default_return_url="ipam:ipaddress_add"))
|
|
882
|
+
# Redirect user if an interface has not been provided
|
|
883
|
+
if "interface" not in request.GET and "vminterface" not in request.GET:
|
|
884
|
+
return redirect(self.get_return_url(request))
|
|
885
885
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
886
|
+
_, error_msg = retrieve_interface_or_vminterface_from_request(request)
|
|
887
|
+
if error_msg:
|
|
888
|
+
messages.warning(request, error_msg)
|
|
889
|
+
return redirect(self.get_return_url(request))
|
|
890
890
|
|
|
891
891
|
return super().dispatch(request, *args, **kwargs)
|
|
892
892
|
|
|
@@ -673,27 +673,6 @@
|
|
|
673
673
|
|
|
674
674
|
|
|
675
675
|
|
|
676
|
-
<li class="md-nav__item">
|
|
677
|
-
<a href="/projects/core/en/stable/user-guide/administration/installation/health-checks.html" class="md-nav__link">
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
<span class="md-ellipsis">
|
|
681
|
-
Health Checks
|
|
682
|
-
</span>
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
</a>
|
|
686
|
-
</li>
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
676
|
<li class="md-nav__item">
|
|
698
677
|
<a href="/projects/core/en/stable/user-guide/administration/installation/selinux-troubleshooting.html" class="md-nav__link">
|
|
699
678
|
|
|
@@ -1899,7 +1878,7 @@
|
|
|
1899
1878
|
|
|
1900
1879
|
|
|
1901
1880
|
<li class="md-nav__item">
|
|
1902
|
-
<a href="/projects/core/en/stable/user-guide/feature-guides/
|
|
1881
|
+
<a href="/projects/core/en/stable/user-guide/feature-guides/contact-and-team.html" class="md-nav__link">
|
|
1903
1882
|
|
|
1904
1883
|
|
|
1905
1884
|
<span class="md-ellipsis">
|
|
@@ -3164,11 +3143,11 @@
|
|
|
3164
3143
|
|
|
3165
3144
|
|
|
3166
3145
|
<li class="md-nav__item">
|
|
3167
|
-
<a href="/projects/core/en/stable/user-guide/core-data-model/dcim/
|
|
3146
|
+
<a href="/projects/core/en/stable/user-guide/core-data-model/dcim/controllerdevicegroup.html" class="md-nav__link">
|
|
3168
3147
|
|
|
3169
3148
|
|
|
3170
3149
|
<span class="md-ellipsis">
|
|
3171
|
-
Controller
|
|
3150
|
+
Controller Device Group
|
|
3172
3151
|
</span>
|
|
3173
3152
|
|
|
3174
3153
|
|
|
@@ -686,27 +686,6 @@
|
|
|
686
686
|
|
|
687
687
|
|
|
688
688
|
|
|
689
|
-
<li class="md-nav__item">
|
|
690
|
-
<a href="../user-guide/administration/installation/health-checks.html" class="md-nav__link">
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
<span class="md-ellipsis">
|
|
694
|
-
Health Checks
|
|
695
|
-
</span>
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
</a>
|
|
699
|
-
</li>
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
689
|
<li class="md-nav__item">
|
|
711
690
|
<a href="../user-guide/administration/installation/selinux-troubleshooting.html" class="md-nav__link">
|
|
712
691
|
|
|
@@ -1912,7 +1891,7 @@
|
|
|
1912
1891
|
|
|
1913
1892
|
|
|
1914
1893
|
<li class="md-nav__item">
|
|
1915
|
-
<a href="../user-guide/feature-guides/
|
|
1894
|
+
<a href="../user-guide/feature-guides/contact-and-team.html" class="md-nav__link">
|
|
1916
1895
|
|
|
1917
1896
|
|
|
1918
1897
|
<span class="md-ellipsis">
|
|
@@ -3177,11 +3156,11 @@
|
|
|
3177
3156
|
|
|
3178
3157
|
|
|
3179
3158
|
<li class="md-nav__item">
|
|
3180
|
-
<a href="../user-guide/core-data-model/dcim/
|
|
3159
|
+
<a href="../user-guide/core-data-model/dcim/controllerdevicegroup.html" class="md-nav__link">
|
|
3181
3160
|
|
|
3182
3161
|
|
|
3183
3162
|
<span class="md-ellipsis">
|
|
3184
|
-
Controller
|
|
3163
|
+
Controller Device Group
|
|
3185
3164
|
</span>
|
|
3186
3165
|
|
|
3187
3166
|
|