nautobot 2.2.0b1__py3-none-any.whl → 2.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/__init__.py +31 -0
- nautobot/apps/api.py +1 -2
- nautobot/apps/utils.py +4 -0
- nautobot/apps/views.py +2 -0
- nautobot/circuits/api/urls.py +1 -2
- nautobot/circuits/api/views.py +0 -12
- nautobot/circuits/apps.py +1 -1
- nautobot/circuits/tests/test_filters.py +1 -1
- nautobot/core/api/routers.py +50 -3
- nautobot/core/api/utils.py +4 -0
- nautobot/core/api/views.py +21 -15
- nautobot/core/cli/__init__.py +18 -11
- nautobot/core/constants.py +85 -0
- nautobot/core/filters.py +7 -1
- nautobot/core/forms/widgets.py +1 -2
- nautobot/core/graphql/schema.py +1 -0
- nautobot/core/management/commands/generate_test_data.py +4 -4
- nautobot/core/models/__init__.py +1 -0
- nautobot/core/settings.py +24 -3
- nautobot/core/settings.yaml +20 -0
- nautobot/core/signals.py +1 -0
- nautobot/core/tables.py +2 -1
- nautobot/core/templates/admin/base.html +23 -94
- nautobot/core/templates/generic/object_retrieve.html +2 -2
- nautobot/core/templates/graphene/graphiql.html +18 -47
- nautobot/core/templates/inc/footer.html +5 -5
- nautobot/core/templates/inc/javascript.html +4 -4
- nautobot/core/templates/inc/media.html +2 -2
- nautobot/core/templates/inc/nav_menu.html +0 -7
- nautobot/core/templates/nautobot_config.py.j2 +14 -1
- nautobot/core/templates/rest_framework/api.html +12 -5
- nautobot/core/templatetags/helpers.py +2 -2
- nautobot/core/testing/__init__.py +1 -1
- nautobot/core/testing/filters.py +1 -1
- nautobot/core/testing/views.py +30 -0
- nautobot/core/tests/integration/test_view_authentication.py +68 -0
- nautobot/core/tests/test_api.py +13 -6
- nautobot/core/tests/test_csv.py +5 -4
- nautobot/core/tests/test_filters.py +2 -1
- nautobot/core/tests/test_graphql.py +4 -14
- nautobot/core/tests/test_navigations.py +3 -0
- nautobot/core/tests/test_views.py +45 -16
- nautobot/core/utils/data.py +1 -2
- nautobot/core/utils/lookup.py +126 -0
- nautobot/core/views/__init__.py +3 -7
- nautobot/core/views/generic.py +24 -10
- nautobot/core/views/mixins.py +11 -4
- nautobot/core/views/renderers.py +11 -6
- nautobot/core/wsgi.py +9 -2
- nautobot/dcim/api/serializers.py +4 -4
- nautobot/dcim/api/urls.py +2 -3
- nautobot/dcim/api/views.py +7 -18
- nautobot/dcim/apps.py +8 -4
- nautobot/dcim/elevations.py +5 -1
- nautobot/dcim/factory.py +7 -7
- nautobot/dcim/filters/__init__.py +16 -17
- nautobot/dcim/forms.py +69 -48
- nautobot/dcim/homepage.py +11 -3
- nautobot/dcim/management/commands/migrate_location_contacts.py +218 -0
- nautobot/dcim/migrations/0057_controller_models.py +11 -70
- nautobot/dcim/models/__init__.py +2 -2
- nautobot/dcim/models/devices.py +14 -16
- nautobot/dcim/models/racks.py +1 -3
- nautobot/dcim/navigation.py +23 -31
- nautobot/dcim/signals.py +6 -6
- nautobot/dcim/tables/__init__.py +2 -2
- nautobot/dcim/tables/devices.py +13 -16
- nautobot/dcim/tables/template_code.py +1 -1
- nautobot/dcim/templates/dcim/controller_create.html +70 -0
- nautobot/dcim/templates/dcim/controller_retrieve.html +35 -18
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +88 -0
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +74 -42
- nautobot/dcim/templates/dcim/device.html +11 -3
- nautobot/dcim/templates/dcim/device_edit.html +1 -1
- nautobot/dcim/templates/dcim/devicefamily_retrieve.html +4 -0
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +1 -1
- nautobot/dcim/tests/test_api.py +47 -6
- nautobot/dcim/tests/test_filters.py +92 -81
- nautobot/dcim/tests/test_forms.py +49 -2
- nautobot/dcim/tests/test_graphql.py +11 -1
- nautobot/dcim/tests/test_models.py +15 -15
- nautobot/dcim/tests/test_signals.py +3 -1
- nautobot/dcim/tests/test_views.py +24 -12
- nautobot/dcim/urls.py +1 -1
- nautobot/dcim/views.py +25 -15
- nautobot/extras/api/serializers.py +20 -1
- nautobot/extras/api/urls.py +1 -2
- nautobot/extras/api/views.py +0 -10
- nautobot/extras/apps.py +7 -0
- nautobot/extras/context_managers.py +71 -4
- nautobot/extras/filters/__init__.py +53 -2
- nautobot/extras/filters/customfields.py +14 -9
- nautobot/extras/filters/mixins.py +6 -1
- nautobot/extras/forms/contacts.py +7 -0
- nautobot/extras/health_checks.py +1 -0
- nautobot/extras/jobs.py +1 -0
- nautobot/extras/managers.py +15 -2
- nautobot/extras/models/contacts.py +1 -0
- nautobot/extras/models/customfields.py +25 -2
- nautobot/extras/models/datasources.py +1 -0
- nautobot/extras/models/mixins.py +1 -0
- nautobot/extras/navigation.py +71 -65
- nautobot/extras/plugins/__init__.py +2 -1
- nautobot/extras/plugins/views.py +7 -11
- nautobot/extras/querysets.py +1 -2
- nautobot/extras/secrets/providers.py +1 -0
- nautobot/extras/signals.py +95 -51
- nautobot/extras/tasks.py +70 -17
- nautobot/extras/tests/test_api.py +2 -4
- nautobot/extras/tests/test_context_managers.py +98 -1
- nautobot/extras/tests/test_customfields.py +72 -9
- nautobot/extras/tests/test_dynamicgroups.py +2 -0
- nautobot/extras/tests/test_filters.py +89 -4
- nautobot/extras/tests/test_models.py +9 -0
- nautobot/extras/tests/test_relationships.py +10 -1
- nautobot/extras/tests/test_views.py +112 -1
- nautobot/extras/utils.py +37 -0
- nautobot/extras/views.py +18 -17
- nautobot/ipam/api/serializers.py +10 -0
- nautobot/ipam/api/urls.py +1 -2
- nautobot/ipam/api/views.py +0 -11
- nautobot/ipam/apps.py +3 -2
- nautobot/ipam/tables.py +3 -23
- nautobot/ipam/tests/test_graphql.py +2 -3
- nautobot/ipam/tests/test_tables.py +42 -0
- nautobot/ipam/tests/test_views.py +1 -0
- nautobot/ipam/views.py +9 -9
- nautobot/project-static/css/base.css +1 -0
- nautobot/project-static/docs/404.html +126 -73
- nautobot/project-static/docs/apps/index.html +127 -71
- nautobot/project-static/docs/apps/nautobot-apps.html +127 -71
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js → bundle.bd41221c.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.8fd75fb4.min.js.map → bundle.bd41221c.min.js.map} +3 -3
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +167 -73
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +165 -72
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +128 -72
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +127 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +345 -71
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +172 -73
- nautobot/project-static/docs/development/apps/api/configuration-view.html +127 -71
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/global-search.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/graphql.html +127 -71
- nautobot/project-static/docs/development/apps/api/models/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +127 -71
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +127 -71
- nautobot/project-static/docs/development/apps/api/prometheus.html +127 -71
- nautobot/project-static/docs/development/apps/api/setup.html +127 -71
- nautobot/project-static/docs/development/apps/api/testing.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +127 -71
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/base-template.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +141 -80
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +144 -83
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/index.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/notes.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +127 -71
- nautobot/project-static/docs/development/apps/api/views/urls.html +127 -71
- nautobot/project-static/docs/development/apps/index.html +127 -71
- nautobot/project-static/docs/development/apps/migration/code-updates.html +127 -71
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +127 -71
- nautobot/project-static/docs/development/apps/migration/from-v1.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +127 -71
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +127 -71
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +127 -71
- nautobot/project-static/docs/development/core/application-registry.html +127 -71
- nautobot/project-static/docs/development/core/best-practices.html +145 -79
- nautobot/project-static/docs/development/core/bootstrap-ui.html +127 -71
- nautobot/project-static/docs/development/core/caching.html +127 -71
- nautobot/project-static/docs/development/core/controllers.html +141 -275
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +127 -71
- nautobot/project-static/docs/development/core/extending-models.html +13 -8166
- nautobot/project-static/docs/development/core/generic-views.html +142 -86
- nautobot/project-static/docs/development/core/getting-started.html +146 -81
- nautobot/project-static/docs/development/core/homepage.html +145 -89
- nautobot/project-static/docs/development/core/index.html +127 -71
- nautobot/project-static/docs/development/core/model-checklist.html +8354 -0
- nautobot/project-static/docs/development/core/model-features.html +130 -74
- nautobot/project-static/docs/development/core/natural-keys.html +127 -71
- nautobot/project-static/docs/development/core/navigation-menu.html +127 -71
- nautobot/project-static/docs/development/core/release-checklist.html +127 -71
- nautobot/project-static/docs/development/core/role-internals.html +127 -71
- nautobot/project-static/docs/development/core/settings.html +127 -71
- nautobot/project-static/docs/development/core/style-guide.html +127 -71
- nautobot/project-static/docs/development/core/templates.html +127 -71
- nautobot/project-static/docs/development/core/testing.html +127 -71
- nautobot/project-static/docs/development/core/user-preferences.html +127 -71
- nautobot/project-static/docs/development/extending-models.html +3 -3
- nautobot/project-static/docs/development/index.html +127 -71
- nautobot/project-static/docs/development/jobs/index.html +128 -72
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +127 -71
- nautobot/project-static/docs/index.html +126 -73
- nautobot/project-static/docs/models/dcim/{controllerdevicegroup.html → controllermanageddevicegroup.html} +3 -3
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.0.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.1.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.2.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.3.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.4.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.5.html +127 -71
- nautobot/project-static/docs/release-notes/version-1.6.html +663 -304
- nautobot/project-static/docs/release-notes/version-2.0.html +127 -71
- nautobot/project-static/docs/release-notes/version-2.1.html +538 -254
- nautobot/project-static/docs/release-notes/version-2.2.html +711 -125
- nautobot/project-static/docs/requirements.txt +3 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +264 -259
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +192 -71
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +127 -71
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +131 -71
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +127 -71
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +130 -74
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +134 -74
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +8616 -0
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +127 -71
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +130 -74
- nautobot/project-static/docs/user-guide/administration/installation/services.html +127 -71
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +127 -71
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +127 -71
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +127 -71
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +127 -71
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +362 -79
- nautobot/project-static/docs/user-guide/core-data-model/dcim/{controllerdevicegroup.html → controllermanageddevicegroup.html} +210 -85
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +130 -74
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +138 -71
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +138 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +127 -71
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/{contact-and-team.html → contacts-and-teams.html} +128 -72
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +129 -73
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +129 -73
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +127 -71
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +127 -71
- nautobot/project-static/docs/user-guide/index.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +127 -71
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +127 -71
- nautobot/project-static/jquery/jquery-3.7.1.min.js +2 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_444444_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_555555_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777620_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_777777_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_cc0000_256x240.png +0 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/images/ui-icons_ffffff_256x240.png +0 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.css +7 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.min.js +6 -0
- nautobot/project-static/jquery-ui-1.13.2/jquery-ui.structure.min.css +5 -0
- nautobot/project-static/{jquery-ui-1.13.1 → jquery-ui-1.13.2}/jquery-ui.theme.min.css +1 -1
- nautobot/tenancy/api/urls.py +1 -2
- nautobot/tenancy/api/views.py +0 -12
- nautobot/tenancy/tables.py +1 -1
- nautobot/tenancy/tests/test_views.py +1 -0
- nautobot/users/api/urls.py +1 -2
- nautobot/users/api/views.py +2 -65
- nautobot/users/views.py +8 -8
- nautobot/virtualization/api/urls.py +1 -2
- nautobot/virtualization/api/views.py +0 -12
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/METADATA +24 -24
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/RECORD +422 -416
- nautobot/dcim/templates/dcim/controllerdevicegroup_create.html +0 -43
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.f2e4d321.min.css.map +0 -1
- nautobot/project-static/jquery/jquery-3.6.0.min.js +0 -2
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.css +0 -7
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.min.js +0 -6
- nautobot/project-static/jquery-ui-1.13.1/jquery-ui.structure.min.css +0 -5
- /nautobot/dcim/templates/dcim/{controllerdevicegroup_retrieve.html → controllermanageddevicegroup_retrieve.html} +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/NOTICE +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/WHEEL +0 -0
- {nautobot-2.2.0b1.dist-info → nautobot-2.2.2.dist-info}/entry_points.txt +0 -0
nautobot/dcim/tests/test_api.py
CHANGED
|
@@ -26,7 +26,7 @@ from nautobot.dcim.models import (
|
|
|
26
26
|
ConsoleServerPort,
|
|
27
27
|
ConsoleServerPortTemplate,
|
|
28
28
|
Controller,
|
|
29
|
-
|
|
29
|
+
ControllerManagedDeviceGroup,
|
|
30
30
|
Device,
|
|
31
31
|
DeviceBay,
|
|
32
32
|
DeviceBayTemplate,
|
|
@@ -618,6 +618,42 @@ class RackTest(APIViewTestCases.APIViewTestCase):
|
|
|
618
618
|
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
619
619
|
self.assertIn(b'class="slot" height="19" width="190"', response.content)
|
|
620
620
|
|
|
621
|
+
@override_settings(
|
|
622
|
+
RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=False,
|
|
623
|
+
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT=22,
|
|
624
|
+
RACK_ELEVATION_DEFAULT_UNIT_WIDTH=230,
|
|
625
|
+
)
|
|
626
|
+
@override_config(RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=True)
|
|
627
|
+
def test_get_rack_elevation_unit_svg_settings_overridden(self):
|
|
628
|
+
"""
|
|
629
|
+
GET a single rack elevation in SVG format, with Django settings specifying the default RU display format
|
|
630
|
+
"""
|
|
631
|
+
rack = Rack.objects.first()
|
|
632
|
+
self.add_permissions("dcim.view_rack")
|
|
633
|
+
reverse_url = reverse("dcim-api:rack-elevation", kwargs={"pk": rack.pk})
|
|
634
|
+
url = f"{reverse_url}?render=svg"
|
|
635
|
+
|
|
636
|
+
response = self.client.get(url, **self.header)
|
|
637
|
+
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
638
|
+
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
639
|
+
self.assertIn(b'<text class="unit" x="15.0" y="915.0">1</text>', response.content)
|
|
640
|
+
|
|
641
|
+
@override_settings(RACK_ELEVATION_DEFAULT_UNIT_HEIGHT=22, RACK_ELEVATION_DEFAULT_UNIT_WIDTH=230)
|
|
642
|
+
@override_config(RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT=True)
|
|
643
|
+
def test_get_rack_elevation_unit_svg_config_overridden(self):
|
|
644
|
+
"""
|
|
645
|
+
GET a single rack elevation in SVG format, with Constance config specifying the 2-digit RU display format
|
|
646
|
+
"""
|
|
647
|
+
rack = Rack.objects.first()
|
|
648
|
+
self.add_permissions("dcim.view_rack")
|
|
649
|
+
reverse_url = reverse("dcim-api:rack-elevation", kwargs={"pk": rack.pk})
|
|
650
|
+
url = f"{reverse_url}?render=svg"
|
|
651
|
+
|
|
652
|
+
response = self.client.get(url, **self.header)
|
|
653
|
+
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
654
|
+
self.assertEqual(response.get("Content-Type"), "image/svg+xml")
|
|
655
|
+
self.assertIn(b'<text class="unit" x="15.0" y="915.0">01</text>', response.content)
|
|
656
|
+
|
|
621
657
|
def test_detail_view_schema(self):
|
|
622
658
|
url = self._get_detail_url(self._get_queryset().first())
|
|
623
659
|
response = self.client.options(url, **self.header)
|
|
@@ -771,6 +807,7 @@ class ManufacturerTest(APIViewTestCases.APIViewTestCase):
|
|
|
771
807
|
# FIXME: This has to be replaced with# `get_deletable_object` and
|
|
772
808
|
# `get_deletable_object_pks` but this is a workaround just so all of these objects are
|
|
773
809
|
# deletable for now.
|
|
810
|
+
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
774
811
|
Device.objects.all().delete()
|
|
775
812
|
DeviceType.objects.all().delete()
|
|
776
813
|
Platform.objects.all().delete()
|
|
@@ -1166,6 +1203,7 @@ class DeviceTest(APIViewTestCases.APIViewTestCase):
|
|
|
1166
1203
|
|
|
1167
1204
|
@classmethod
|
|
1168
1205
|
def setUpTestData(cls):
|
|
1206
|
+
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
1169
1207
|
Device.objects.all().delete()
|
|
1170
1208
|
locations = Location.objects.filter(location_type=LocationType.objects.get(name="Campus"))[:2]
|
|
1171
1209
|
|
|
@@ -2168,7 +2206,10 @@ class ConnectedDeviceTest(APITestCase):
|
|
|
2168
2206
|
def test_get_connected_device(self):
|
|
2169
2207
|
url = reverse("dcim-api:connected-device-list")
|
|
2170
2208
|
response = self.client.get(url + "?peer_device=TestDevice2&peer_interface=eth0", **self.header)
|
|
2209
|
+
self.assertHttpStatus(response, status.HTTP_404_NOT_FOUND)
|
|
2171
2210
|
|
|
2211
|
+
self.add_permissions("dcim.view_interface")
|
|
2212
|
+
response = self.client.get(url + "?peer_device=TestDevice2&peer_interface=eth0", **self.header)
|
|
2172
2213
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
2173
2214
|
self.assertEqual(response.data["name"], self.device1.name)
|
|
2174
2215
|
|
|
@@ -2813,8 +2854,8 @@ class ControllerTestCase(APIViewTestCases.APIViewTestCase):
|
|
|
2813
2854
|
}
|
|
2814
2855
|
|
|
2815
2856
|
|
|
2816
|
-
class
|
|
2817
|
-
model =
|
|
2857
|
+
class ControllerManagedDeviceGroupTestCase(APIViewTestCases.APIViewTestCase):
|
|
2858
|
+
model = ControllerManagedDeviceGroup
|
|
2818
2859
|
|
|
2819
2860
|
@classmethod
|
|
2820
2861
|
def setUpTestData(cls):
|
|
@@ -2822,17 +2863,17 @@ class ControllerDeviceGroupTestCase(APIViewTestCases.APIViewTestCase):
|
|
|
2822
2863
|
|
|
2823
2864
|
cls.create_data = [
|
|
2824
2865
|
{
|
|
2825
|
-
"name": "
|
|
2866
|
+
"name": "ControllerManagedDeviceGroup 1",
|
|
2826
2867
|
"controller": controllers[0].pk,
|
|
2827
2868
|
"weight": 100,
|
|
2828
2869
|
},
|
|
2829
2870
|
{
|
|
2830
|
-
"name": "
|
|
2871
|
+
"name": "ControllerManagedDeviceGroup 2",
|
|
2831
2872
|
"controller": controllers[1].pk,
|
|
2832
2873
|
"weight": 150,
|
|
2833
2874
|
},
|
|
2834
2875
|
{
|
|
2835
|
-
"name": "
|
|
2876
|
+
"name": "ControllerManagedDeviceGroup 3",
|
|
2836
2877
|
"controller": controllers[2].pk,
|
|
2837
2878
|
"weight": 200,
|
|
2838
2879
|
},
|
|
@@ -26,8 +26,8 @@ from nautobot.dcim.filters import (
|
|
|
26
26
|
ConsolePortTemplateFilterSet,
|
|
27
27
|
ConsoleServerPortFilterSet,
|
|
28
28
|
ConsoleServerPortTemplateFilterSet,
|
|
29
|
-
ControllerDeviceGroupFilterSet,
|
|
30
29
|
ControllerFilterSet,
|
|
30
|
+
ControllerManagedDeviceGroupFilterSet,
|
|
31
31
|
DeviceBayFilterSet,
|
|
32
32
|
DeviceBayTemplateFilterSet,
|
|
33
33
|
DeviceFamilyFilterSet,
|
|
@@ -68,7 +68,7 @@ from nautobot.dcim.models import (
|
|
|
68
68
|
ConsoleServerPort,
|
|
69
69
|
ConsoleServerPortTemplate,
|
|
70
70
|
Controller,
|
|
71
|
-
|
|
71
|
+
ControllerManagedDeviceGroup,
|
|
72
72
|
Device,
|
|
73
73
|
DeviceBay,
|
|
74
74
|
DeviceBayTemplate,
|
|
@@ -112,6 +112,7 @@ User = get_user_model()
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
def common_test_data(cls):
|
|
115
|
+
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
115
116
|
Device.objects.all().delete()
|
|
116
117
|
tenants = Tenant.objects.filter(tenant_group__isnull=False)
|
|
117
118
|
cls.tenants = tenants
|
|
@@ -619,6 +620,82 @@ def common_test_data(cls):
|
|
|
619
620
|
cls.devices[0].tags.set(Tag.objects.get_for_model(Device))
|
|
620
621
|
cls.devices[1].tags.set(Tag.objects.get_for_model(Device)[:3])
|
|
621
622
|
|
|
623
|
+
controller_statuses = iter(Status.objects.get_for_model(Controller))
|
|
624
|
+
external_integrations = iter(ExternalIntegration.objects.all())
|
|
625
|
+
device_redundancy_groups = iter(DeviceRedundancyGroup.objects.all())
|
|
626
|
+
|
|
627
|
+
cls.controllers = (
|
|
628
|
+
Controller.objects.create(
|
|
629
|
+
name="Controller 1",
|
|
630
|
+
status=next(controller_statuses),
|
|
631
|
+
description="First",
|
|
632
|
+
location=loc0,
|
|
633
|
+
platform=platforms[0],
|
|
634
|
+
role=cls.device_roles[0],
|
|
635
|
+
tenant=tenants[0],
|
|
636
|
+
external_integration=next(external_integrations),
|
|
637
|
+
controller_device=cls.devices[0],
|
|
638
|
+
),
|
|
639
|
+
Controller.objects.create(
|
|
640
|
+
name="Controller 2",
|
|
641
|
+
status=next(controller_statuses),
|
|
642
|
+
description="Second",
|
|
643
|
+
location=loc1,
|
|
644
|
+
platform=platforms[1],
|
|
645
|
+
role=cls.device_roles[1],
|
|
646
|
+
tenant=tenants[1],
|
|
647
|
+
external_integration=next(external_integrations),
|
|
648
|
+
controller_device=cls.devices[1],
|
|
649
|
+
),
|
|
650
|
+
Controller.objects.create(
|
|
651
|
+
name="Controller 3",
|
|
652
|
+
status=next(controller_statuses),
|
|
653
|
+
description="Third",
|
|
654
|
+
location=loc2,
|
|
655
|
+
platform=platforms[2],
|
|
656
|
+
role=cls.device_roles[2],
|
|
657
|
+
tenant=tenants[2],
|
|
658
|
+
external_integration=next(external_integrations),
|
|
659
|
+
controller_device_redundancy_group=next(device_redundancy_groups),
|
|
660
|
+
),
|
|
661
|
+
Controller.objects.create(
|
|
662
|
+
name="Controller 4",
|
|
663
|
+
status=next(controller_statuses),
|
|
664
|
+
description="Forth",
|
|
665
|
+
location=loc2,
|
|
666
|
+
platform=platforms[2],
|
|
667
|
+
role=cls.device_roles[2],
|
|
668
|
+
tenant=tenants[2],
|
|
669
|
+
external_integration=next(external_integrations),
|
|
670
|
+
controller_device_redundancy_group=next(device_redundancy_groups),
|
|
671
|
+
),
|
|
672
|
+
)
|
|
673
|
+
cls.controllers[0].tags.set(Tag.objects.get_for_model(Controller))
|
|
674
|
+
cls.controllers[1].tags.set(Tag.objects.get_for_model(Controller)[:3])
|
|
675
|
+
|
|
676
|
+
parent_controller_managed_device_group = ControllerManagedDeviceGroup.objects.create(
|
|
677
|
+
name="Managed Device Group 11",
|
|
678
|
+
weight=1000,
|
|
679
|
+
controller=cls.controllers[0],
|
|
680
|
+
)
|
|
681
|
+
cls.controller_managed_device_groups = (
|
|
682
|
+
parent_controller_managed_device_group,
|
|
683
|
+
ControllerManagedDeviceGroup.objects.create(
|
|
684
|
+
name="Managed Device Group 12",
|
|
685
|
+
weight=2000,
|
|
686
|
+
controller=cls.controllers[1],
|
|
687
|
+
parent=parent_controller_managed_device_group,
|
|
688
|
+
),
|
|
689
|
+
ControllerManagedDeviceGroup.objects.create(
|
|
690
|
+
name="Managed Device Group 13",
|
|
691
|
+
weight=3000,
|
|
692
|
+
controller=cls.controllers[2],
|
|
693
|
+
parent=parent_controller_managed_device_group,
|
|
694
|
+
),
|
|
695
|
+
)
|
|
696
|
+
parent_controller_managed_device_group.tags.set(Tag.objects.get_for_model(ControllerManagedDeviceGroup))
|
|
697
|
+
cls.controller_managed_device_groups[1].tags.set(Tag.objects.get_for_model(ControllerManagedDeviceGroup)[:3])
|
|
698
|
+
|
|
622
699
|
|
|
623
700
|
class LocationTypeFilterSetTestCase(FilterTestCases.NameOnlyFilterTestCase):
|
|
624
701
|
queryset = LocationType.objects.all()
|
|
@@ -1341,8 +1418,8 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
|
|
|
1341
1418
|
("device_redundancy_group", "device_redundancy_group__id"),
|
|
1342
1419
|
("device_redundancy_group", "device_redundancy_group__name"),
|
|
1343
1420
|
("device_redundancy_group_priority",),
|
|
1344
|
-
("
|
|
1345
|
-
("
|
|
1421
|
+
("controller_managed_device_group", "controller_managed_device_group__id"),
|
|
1422
|
+
("controller_managed_device_group", "controller_managed_device_group__name"),
|
|
1346
1423
|
("device_type", "device_type__id"),
|
|
1347
1424
|
("device_type", "device_type__model"),
|
|
1348
1425
|
("front_ports", "front_ports__id"),
|
|
@@ -1415,19 +1492,19 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
|
|
|
1415
1492
|
Service.objects.create(device=devices[0], name="ssh", protocol="tcp", ports=[22])
|
|
1416
1493
|
Service.objects.create(device=devices[1], name="dns", protocol="udp", ports=[53])
|
|
1417
1494
|
|
|
1418
|
-
cls.
|
|
1495
|
+
cls.controller_managed_device_groups = list(ControllerManagedDeviceGroup.objects.all()[:2])
|
|
1419
1496
|
cls.device_redundancy_groups = list(DeviceRedundancyGroup.objects.all()[:2])
|
|
1420
1497
|
Device.objects.filter(pk=devices[0].pk).update(
|
|
1421
|
-
|
|
1498
|
+
controller_managed_device_group=cls.controller_managed_device_groups[0],
|
|
1422
1499
|
device_redundancy_group=cls.device_redundancy_groups[0],
|
|
1423
1500
|
)
|
|
1424
1501
|
Device.objects.filter(pk=devices[1].pk).update(
|
|
1425
|
-
|
|
1502
|
+
controller_managed_device_group=cls.controller_managed_device_groups[0],
|
|
1426
1503
|
device_redundancy_group=cls.device_redundancy_groups[0],
|
|
1427
1504
|
device_redundancy_group_priority=1,
|
|
1428
1505
|
)
|
|
1429
1506
|
Device.objects.filter(pk=devices[2].pk).update(
|
|
1430
|
-
|
|
1507
|
+
controller_managed_device_group=cls.controller_managed_device_groups[1],
|
|
1431
1508
|
device_redundancy_group=cls.device_redundancy_groups[1],
|
|
1432
1509
|
device_redundancy_group_priority=100,
|
|
1433
1510
|
)
|
|
@@ -3355,63 +3432,20 @@ class ControllerFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
|
3355
3432
|
("platform", "platform__name"),
|
|
3356
3433
|
("external_integration", "external_integration__id"),
|
|
3357
3434
|
("external_integration", "external_integration__name"),
|
|
3358
|
-
("
|
|
3359
|
-
("
|
|
3360
|
-
("
|
|
3361
|
-
("
|
|
3435
|
+
("controller_device", "controller_device__id"),
|
|
3436
|
+
("controller_device", "controller_device__name"),
|
|
3437
|
+
("controller_device_redundancy_group", "controller_device_redundancy_group__id"),
|
|
3438
|
+
("controller_device_redundancy_group", "controller_device_redundancy_group__name"),
|
|
3362
3439
|
)
|
|
3363
3440
|
|
|
3364
3441
|
@classmethod
|
|
3365
3442
|
def setUpTestData(cls):
|
|
3366
3443
|
common_test_data(cls)
|
|
3367
3444
|
|
|
3368
|
-
external_integrations = iter(ExternalIntegration.objects.all())
|
|
3369
|
-
locations = iter(Location.objects.filter(location_type__name="Campus"))
|
|
3370
|
-
platforms = iter(Platform.objects.all())
|
|
3371
|
-
roles = iter(Role.objects.get_for_model(Controller))
|
|
3372
|
-
statuses = iter(Status.objects.get_for_model(Controller))
|
|
3373
|
-
tenants = iter(Tenant.objects.all())
|
|
3374
|
-
|
|
3375
|
-
cls.controllers = (
|
|
3376
|
-
Controller.objects.create(
|
|
3377
|
-
name="Controller 1",
|
|
3378
|
-
status=next(statuses),
|
|
3379
|
-
description="First",
|
|
3380
|
-
location=next(locations),
|
|
3381
|
-
platform=next(platforms),
|
|
3382
|
-
role=next(roles),
|
|
3383
|
-
tenant=next(tenants),
|
|
3384
|
-
external_integration=next(external_integrations),
|
|
3385
|
-
deployed_controller_device=cls.devices[0],
|
|
3386
|
-
),
|
|
3387
|
-
Controller.objects.create(
|
|
3388
|
-
name="Controller 2",
|
|
3389
|
-
status=next(statuses),
|
|
3390
|
-
description="Second",
|
|
3391
|
-
location=next(locations),
|
|
3392
|
-
platform=next(platforms),
|
|
3393
|
-
role=next(roles),
|
|
3394
|
-
tenant=next(tenants),
|
|
3395
|
-
external_integration=next(external_integrations),
|
|
3396
|
-
deployed_controller_device=cls.devices[1],
|
|
3397
|
-
),
|
|
3398
|
-
Controller.objects.create(
|
|
3399
|
-
name="Controller 3",
|
|
3400
|
-
status=next(statuses),
|
|
3401
|
-
description="Third",
|
|
3402
|
-
location=next(locations),
|
|
3403
|
-
platform=next(platforms),
|
|
3404
|
-
role=next(roles),
|
|
3405
|
-
tenant=next(tenants),
|
|
3406
|
-
external_integration=next(external_integrations),
|
|
3407
|
-
deployed_controller_group=DeviceRedundancyGroup.objects.first(),
|
|
3408
|
-
),
|
|
3409
|
-
)
|
|
3410
|
-
|
|
3411
3445
|
|
|
3412
|
-
class
|
|
3413
|
-
queryset =
|
|
3414
|
-
filterset =
|
|
3446
|
+
class ControllerManagedDeviceGroupFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
3447
|
+
queryset = ControllerManagedDeviceGroup.objects.all()
|
|
3448
|
+
filterset = ControllerManagedDeviceGroupFilterSet
|
|
3415
3449
|
generic_filter_tests = (
|
|
3416
3450
|
("name",),
|
|
3417
3451
|
("weight",),
|
|
@@ -3424,26 +3458,3 @@ class ControllerDeviceGroupFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
|
3424
3458
|
@classmethod
|
|
3425
3459
|
def setUpTestData(cls):
|
|
3426
3460
|
common_test_data(cls)
|
|
3427
|
-
|
|
3428
|
-
cls.controllers = Controller.objects.all()[:3]
|
|
3429
|
-
|
|
3430
|
-
group1 = ControllerDeviceGroup.objects.create(
|
|
3431
|
-
name="Controller Device Group 11",
|
|
3432
|
-
weight=1000,
|
|
3433
|
-
controller=cls.controllers[0],
|
|
3434
|
-
)
|
|
3435
|
-
cls.controller_device_groups = (
|
|
3436
|
-
group1,
|
|
3437
|
-
ControllerDeviceGroup.objects.create(
|
|
3438
|
-
name="Controller Device Group 12",
|
|
3439
|
-
weight=2000,
|
|
3440
|
-
controller=cls.controllers[1],
|
|
3441
|
-
parent=group1,
|
|
3442
|
-
),
|
|
3443
|
-
ControllerDeviceGroup.objects.create(
|
|
3444
|
-
name="Controller Device Group 13",
|
|
3445
|
-
weight=3000,
|
|
3446
|
-
controller=cls.controllers[2],
|
|
3447
|
-
parent=group1,
|
|
3448
|
-
),
|
|
3449
|
-
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from django.test import TestCase
|
|
2
2
|
|
|
3
3
|
from nautobot.core.testing.forms import FormTestCases
|
|
4
|
-
from nautobot.dcim.choices import DeviceFaceChoices, InterfaceTypeChoices, RackWidthChoices
|
|
5
|
-
from nautobot.dcim.forms import DeviceFilterForm, DeviceForm, InterfaceCreateForm, RackForm
|
|
4
|
+
from nautobot.dcim.choices import DeviceFaceChoices, InterfaceModeChoices, InterfaceTypeChoices, RackWidthChoices
|
|
5
|
+
from nautobot.dcim.forms import DeviceFilterForm, DeviceForm, InterfaceCreateForm, InterfaceForm, RackForm
|
|
6
6
|
from nautobot.dcim.models import (
|
|
7
7
|
Device,
|
|
8
8
|
DeviceType,
|
|
@@ -14,6 +14,7 @@ from nautobot.dcim.models import (
|
|
|
14
14
|
Rack,
|
|
15
15
|
)
|
|
16
16
|
from nautobot.extras.models import Role, SecretsGroup, Status
|
|
17
|
+
from nautobot.ipam.models import VLAN
|
|
17
18
|
from nautobot.tenancy.models import Tenant
|
|
18
19
|
from nautobot.virtualization.models import Cluster, ClusterGroup, ClusterType
|
|
19
20
|
|
|
@@ -263,3 +264,49 @@ class RackTestCase(TestCase):
|
|
|
263
264
|
}
|
|
264
265
|
form = RackForm(data=data, instance=racks[0])
|
|
265
266
|
self.assertTrue(form.is_valid())
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class InterfaceTestCase(TestCase):
|
|
270
|
+
@classmethod
|
|
271
|
+
def setUpTestData(cls):
|
|
272
|
+
cls.device = Device.objects.first()
|
|
273
|
+
status = Status.objects.get_for_model(Interface).first()
|
|
274
|
+
cls.interface = Interface.objects.create(
|
|
275
|
+
device=cls.device,
|
|
276
|
+
name="test interface form 0.0",
|
|
277
|
+
type=InterfaceTypeChoices.TYPE_2GFC_SFP,
|
|
278
|
+
status=status,
|
|
279
|
+
)
|
|
280
|
+
cls.vlan = VLAN.objects.first()
|
|
281
|
+
cls.data = {
|
|
282
|
+
"device": cls.device.pk,
|
|
283
|
+
"name": "test interface form 0.0",
|
|
284
|
+
"type": InterfaceTypeChoices.TYPE_2GFC_SFP,
|
|
285
|
+
"status": status.pk,
|
|
286
|
+
"mode": InterfaceModeChoices.MODE_TAGGED,
|
|
287
|
+
"tagged_vlans": [cls.vlan.pk],
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
def test_interface_form_clean_vlan_location_fail(self):
|
|
291
|
+
"""Assert that form validation fails when no matching locations are associated to tagged VLAN"""
|
|
292
|
+
self.vlan.locations.set(list(Location.objects.exclude(pk=self.device.location.pk))[:2])
|
|
293
|
+
form = InterfaceForm(data=self.data, instance=self.interface)
|
|
294
|
+
self.assertFalse(form.is_valid())
|
|
295
|
+
|
|
296
|
+
def test_interface_vlan_location_clean_multiple_locations_pass(self):
|
|
297
|
+
"""Assert that form validation passes when multiple locations are associated to tagged VLAN with one matching"""
|
|
298
|
+
self.vlan.locations.add(self.device.location)
|
|
299
|
+
form = InterfaceForm(data=self.data, instance=self.interface)
|
|
300
|
+
self.assertTrue(form.is_valid())
|
|
301
|
+
|
|
302
|
+
def test_interface_vlan_location_clean_single_location_pass(self):
|
|
303
|
+
"""Assert that form validation passes when a single location is associated to tagged VLAN"""
|
|
304
|
+
self.vlan.locations.set([self.device.location])
|
|
305
|
+
form = InterfaceForm(data=self.data, instance=self.interface)
|
|
306
|
+
self.assertTrue(form.is_valid())
|
|
307
|
+
|
|
308
|
+
def test_interface_vlan_location_clean_no_locations_pass(self):
|
|
309
|
+
"""Assert that form validation passes when no locations are associated to tagged VLAN"""
|
|
310
|
+
self.vlan.locations.clear()
|
|
311
|
+
form = InterfaceForm(data=self.data, instance=self.interface)
|
|
312
|
+
self.assertTrue(form.is_valid())
|
|
@@ -4,12 +4,22 @@ from django.test import override_settings
|
|
|
4
4
|
from nautobot.core.graphql import execute_query
|
|
5
5
|
from nautobot.core.testing import create_test_user, TestCase
|
|
6
6
|
from nautobot.dcim.choices import InterfaceTypeChoices
|
|
7
|
-
from nautobot.dcim.models import
|
|
7
|
+
from nautobot.dcim.models import (
|
|
8
|
+
Controller,
|
|
9
|
+
Device,
|
|
10
|
+
DeviceType,
|
|
11
|
+
Interface,
|
|
12
|
+
Location,
|
|
13
|
+
LocationType,
|
|
14
|
+
Manufacturer,
|
|
15
|
+
Platform,
|
|
16
|
+
)
|
|
8
17
|
from nautobot.extras.models import DynamicGroup, Role, Status
|
|
9
18
|
|
|
10
19
|
|
|
11
20
|
class GraphQLTestCase(TestCase):
|
|
12
21
|
def setUp(self):
|
|
22
|
+
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
13
23
|
Device.objects.all().delete()
|
|
14
24
|
self.user = create_test_user("graphql_testuser")
|
|
15
25
|
self.location = Location.objects.filter(location_type=LocationType.objects.get(name="Campus")).first()
|
|
@@ -24,7 +24,7 @@ from nautobot.dcim.models import (
|
|
|
24
24
|
ConsoleServerPort,
|
|
25
25
|
ConsoleServerPortTemplate,
|
|
26
26
|
Controller,
|
|
27
|
-
|
|
27
|
+
ControllerManagedDeviceGroup,
|
|
28
28
|
Device,
|
|
29
29
|
DeviceBay,
|
|
30
30
|
DeviceBayTemplate,
|
|
@@ -1896,13 +1896,13 @@ class ControllerTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
1896
1896
|
status=Status.objects.get_for_model(Controller).first(),
|
|
1897
1897
|
role=Role.objects.get_for_model(Controller).first(),
|
|
1898
1898
|
location=Location.objects.first(),
|
|
1899
|
-
|
|
1900
|
-
|
|
1899
|
+
controller_device=Device.objects.first(),
|
|
1900
|
+
controller_device_redundancy_group=DeviceRedundancyGroup.objects.first(),
|
|
1901
1901
|
)
|
|
1902
1902
|
with self.assertRaises(ValidationError) as error:
|
|
1903
1903
|
controller.validated_save()
|
|
1904
1904
|
self.assertEqual(
|
|
1905
|
-
error.exception.message_dict["
|
|
1905
|
+
error.exception.message_dict["controller_device"][0],
|
|
1906
1906
|
"Cannot assign both a device and a device redundancy group to a controller.",
|
|
1907
1907
|
)
|
|
1908
1908
|
|
|
@@ -1924,19 +1924,19 @@ class ControllerTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
1924
1924
|
)
|
|
1925
1925
|
|
|
1926
1926
|
|
|
1927
|
-
class
|
|
1928
|
-
model =
|
|
1927
|
+
class ControllerManagedDeviceGroupTestCase(ModelTestCases.BaseModelTestCase):
|
|
1928
|
+
model = ControllerManagedDeviceGroup
|
|
1929
1929
|
|
|
1930
1930
|
def test_controller_matches_parent(self):
|
|
1931
1931
|
"""Ensure a controller device group cannot be linked to a controller that does not match its parent."""
|
|
1932
1932
|
controllers = iter(Controller.objects.all())
|
|
1933
|
-
parent_group =
|
|
1933
|
+
parent_group = ControllerManagedDeviceGroup(
|
|
1934
1934
|
name="Parent Group testing Controller match",
|
|
1935
1935
|
controller=next(controllers),
|
|
1936
1936
|
)
|
|
1937
1937
|
parent_group.validated_save()
|
|
1938
1938
|
|
|
1939
|
-
child_group =
|
|
1939
|
+
child_group = ControllerManagedDeviceGroup(
|
|
1940
1940
|
name="Child Group testing Controller match",
|
|
1941
1941
|
controller=next(controllers),
|
|
1942
1942
|
parent=parent_group,
|
|
@@ -1955,37 +1955,37 @@ class ControllerDeviceGroupTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
1955
1955
|
controller1, controller2 = Controller.objects.all()[:2]
|
|
1956
1956
|
self.assertNotEqual(controller1, controller2, "Controllers should be different")
|
|
1957
1957
|
|
|
1958
|
-
parent_group =
|
|
1958
|
+
parent_group = ControllerManagedDeviceGroup.objects.create(
|
|
1959
1959
|
name="Parent Group testing Controller match",
|
|
1960
1960
|
controller=controller1,
|
|
1961
1961
|
)
|
|
1962
|
-
child_group1 =
|
|
1962
|
+
child_group1 = ControllerManagedDeviceGroup.objects.create(
|
|
1963
1963
|
name="Child Group 1 testing Controller match",
|
|
1964
1964
|
controller=controller1,
|
|
1965
1965
|
parent=parent_group,
|
|
1966
1966
|
)
|
|
1967
|
-
child_group2 =
|
|
1967
|
+
child_group2 = ControllerManagedDeviceGroup.objects.create(
|
|
1968
1968
|
name="Child Group 2 testing Controller match",
|
|
1969
1969
|
controller=controller1,
|
|
1970
1970
|
parent=child_group1,
|
|
1971
1971
|
)
|
|
1972
1972
|
|
|
1973
|
-
parent_group =
|
|
1973
|
+
parent_group = ControllerManagedDeviceGroup.objects.get(pk=parent_group.pk)
|
|
1974
1974
|
parent_group.controller = controller2
|
|
1975
1975
|
parent_group.save()
|
|
1976
1976
|
|
|
1977
1977
|
self.assertEqual(
|
|
1978
|
-
|
|
1978
|
+
ControllerManagedDeviceGroup.objects.get(pk=parent_group.pk).controller,
|
|
1979
1979
|
controller2,
|
|
1980
1980
|
"Parent group controller should have been updated",
|
|
1981
1981
|
)
|
|
1982
1982
|
self.assertEqual(
|
|
1983
|
-
|
|
1983
|
+
ControllerManagedDeviceGroup.objects.get(pk=child_group1.pk).controller,
|
|
1984
1984
|
controller2,
|
|
1985
1985
|
"Child group 1 controller should have been updated",
|
|
1986
1986
|
)
|
|
1987
1987
|
self.assertEqual(
|
|
1988
|
-
|
|
1988
|
+
ControllerManagedDeviceGroup.objects.get(pk=child_group2.pk).controller,
|
|
1989
1989
|
controller2,
|
|
1990
1990
|
"Child group 2 controller should have been updated",
|
|
1991
1991
|
)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
"""Tests for DCIM Signals.py
|
|
1
|
+
"""Tests for DCIM Signals.py"""
|
|
2
2
|
|
|
3
3
|
from django.test import TestCase
|
|
4
4
|
|
|
5
5
|
from nautobot.dcim.models import (
|
|
6
|
+
Controller,
|
|
6
7
|
Device,
|
|
7
8
|
DeviceRedundancyGroup,
|
|
8
9
|
DeviceType,
|
|
@@ -103,6 +104,7 @@ class DeviceRedundancyGroupTest(TestCase):
|
|
|
103
104
|
self.device.device_redundancy_group_priority = 1
|
|
104
105
|
self.device.validated_save()
|
|
105
106
|
|
|
107
|
+
Controller.objects.all().delete()
|
|
106
108
|
deviceredundancygroup.delete()
|
|
107
109
|
|
|
108
110
|
self.device.refresh_from_db()
|