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
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{% extends 'generic/object_create.html' %}
|
|
2
|
+
{% load form_helpers %}
|
|
3
|
+
{% load helpers %}
|
|
4
|
+
{% load static %}
|
|
5
|
+
|
|
6
|
+
{% block javascript %}
|
|
7
|
+
<script type="text/javascript">
|
|
8
|
+
const parentInput = $('select#id_parent');
|
|
9
|
+
const controllerInput = $('select#id_controller');
|
|
10
|
+
|
|
11
|
+
const controllerUrl = '{% url 'dcim-api:controllerdevicegroup-list' %}';
|
|
12
|
+
|
|
13
|
+
const updateControllerFromParent = (parentUuid) => {
|
|
14
|
+
$.ajax({
|
|
15
|
+
url: `${controllerUrl}${parentUuid}/`,
|
|
16
|
+
method: "GET",
|
|
17
|
+
success: (data) => {
|
|
18
|
+
if (data.controller) {
|
|
19
|
+
controllerInput.val(data.controller.id);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
error: (error) => console.log("ERROR", error),
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const onParentInput = (event) => {
|
|
27
|
+
const parentUuid = parentInput.val();
|
|
28
|
+
if (parentUuid) {
|
|
29
|
+
controllerInput.prop("disabled", true);
|
|
30
|
+
if (event) {
|
|
31
|
+
updateControllerFromParent(parentUuid);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
controllerInput.prop("disabled", false);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
parentInput.on('select2:select', onParentInput);
|
|
39
|
+
parentInput.on('select2:unselect', onParentInput);
|
|
40
|
+
|
|
41
|
+
onParentInput();
|
|
42
|
+
</script>
|
|
43
|
+
{% endblock %}
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
<th>Interface</th>
|
|
16
16
|
<th>Configured Device</th>
|
|
17
17
|
<th>Configured Interface</th>
|
|
18
|
-
<th>Configured MAC Address</th>
|
|
19
18
|
<th>LLDP Device</th>
|
|
20
19
|
<th>LLDP Interface</th>
|
|
21
20
|
</tr>
|
|
@@ -28,21 +27,18 @@
|
|
|
28
27
|
<td class="configured_device" data="{{ iface.connected_endpoint.device }}" data-chassis="{{ iface.connected_endpoint.device.virtual_chassis.name }}">
|
|
29
28
|
{{ iface.connected_endpoint.device|hyperlinked_object }}
|
|
30
29
|
</td>
|
|
31
|
-
<td class="configured_interface" data
|
|
30
|
+
<td class="configured_interface" data="{{ iface.connected_endpoint }}">
|
|
32
31
|
<span title="{{ iface.connected_endpoint.get_type_display }}">{{ iface.connected_endpoint }}</span>
|
|
33
32
|
</td>
|
|
34
|
-
<td class="configured_mac" data-mac-address="{{ iface.connected_endpoint.mac_address }}">
|
|
35
|
-
<span>{{ iface.connected_endpoint.mac_address }}</span>
|
|
36
|
-
</td>
|
|
37
33
|
{% elif iface.connected_endpoint.circuit %}
|
|
38
34
|
{% with circuit=iface.connected_endpoint.circuit %}
|
|
39
|
-
<td colspan="
|
|
35
|
+
<td colspan="2">
|
|
40
36
|
<i class="mdi mdi-lightning-bolt" title="Circuit"></i>
|
|
41
37
|
<a href="{{ circuit.get_absolute_url }}">{{ circuit.provider }} {{ circuit }}</a>
|
|
42
38
|
</td>
|
|
43
39
|
{% endwith %}
|
|
44
40
|
{% else %}
|
|
45
|
-
<td colspan="
|
|
41
|
+
<td colspan="2">None</td>
|
|
46
42
|
{% endif %}
|
|
47
43
|
<td class="device"></td>
|
|
48
44
|
<td class="interface"></td>
|
|
@@ -56,71 +52,51 @@
|
|
|
56
52
|
{% block javascript %}
|
|
57
53
|
{{ block.super }}
|
|
58
54
|
<script type="text/javascript">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
ready(() => {
|
|
68
|
-
fetch("{% url 'dcim-api:device-napalm' pk=object.pk %}?method=get_lldp_neighbors_detail")
|
|
69
|
-
.then((response) => {
|
|
70
|
-
if (!response.ok) {
|
|
71
|
-
throw Error(response.statusText);
|
|
72
|
-
}
|
|
73
|
-
return response.json();
|
|
74
|
-
})
|
|
75
|
-
.then((data) => {
|
|
76
|
-
const interfaces = data["get_lldp_neighbors_detail"];
|
|
77
|
-
for (var iface of Object.keys(interfaces)) {
|
|
78
|
-
const neighbor = interfaces[iface][0];
|
|
79
|
-
const row = document.querySelector('*[data-interface-name="'+ iface.split(".")[0].replace(/([\/:])/g, "\\$1") + '"]');
|
|
80
|
-
// var row = $('*[data-interface-name="' + iface.split(".")[0].replace(/([\/:])/g, "\\$1") + '"]');
|
|
55
|
+
$(document).ready(function() {
|
|
56
|
+
$.ajax({
|
|
57
|
+
url: "{% url 'dcim-api:device-napalm' pk=object.pk %}?method=get_lldp_neighbors_detail",
|
|
58
|
+
dataType: 'json',
|
|
59
|
+
success: function(json) {
|
|
60
|
+
$.each(json['get_lldp_neighbors_detail'], function(iface, neighbors) {
|
|
61
|
+
var neighbor = neighbors[0];
|
|
62
|
+
var row = $('*[data-interface-name="' + iface.split(".")[0].replace(/([\/:])/g, "\\$1") + '"]');
|
|
81
63
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
64
|
+
// Glean configured hostnames/interfaces from the DOM
|
|
65
|
+
var configured_device = row.children('td.configured_device').attr('data');
|
|
66
|
+
var configured_chassis = row.children('td.configured_device').attr('data-chassis');
|
|
67
|
+
var configured_interface = row.children('td.configured_interface').attr('data');
|
|
68
|
+
var configured_interface_short = null;
|
|
69
|
+
if (configured_interface) {
|
|
70
|
+
// Match long-form IOS names against short ones (e.g. Gi0/1 == GigabitEthernet0/1).
|
|
71
|
+
configured_interface_short = configured_interface.replace(/^([A-Z][a-z])[^0-9]*([0-9\/]+)$/, "$1$2");
|
|
72
|
+
}
|
|
92
73
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
74
|
+
// Clean up hostnames/interfaces learned via LLDP
|
|
75
|
+
var neighbor_host = neighbor['remote_system_name'] || ""; // sanitize hostname if it's null to avoid breaking the split func
|
|
76
|
+
var neighbor_port = neighbor['remote_port'] || ""; // sanitize port if it's null to avoid breaking the split func
|
|
77
|
+
var lldp_device = neighbor_host.split(".")[0]; // Strip off any trailing domain name
|
|
78
|
+
var lldp_interface = neighbor_port.split(".")[0]; // Strip off any trailing subinterface ID
|
|
98
79
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
80
|
+
// Add LLDP neighbors to table
|
|
81
|
+
row.children('td.device').html(lldp_device);
|
|
82
|
+
row.children('td.interface').html(lldp_interface);
|
|
102
83
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.catch((error) => {
|
|
118
|
-
if (error.responseText) {
|
|
119
|
-
alert(error.responseText);
|
|
120
|
-
} else {
|
|
121
|
-
throw error;
|
|
84
|
+
// Apply colors to rows
|
|
85
|
+
if (!configured_device && lldp_device) {
|
|
86
|
+
row.addClass('info');
|
|
87
|
+
} else if ((configured_device == lldp_device || configured_chassis == lldp_device) && configured_interface == lldp_interface) {
|
|
88
|
+
row.addClass('success');
|
|
89
|
+
} else if ((configured_device == lldp_device || configured_chassis == lldp_device) && configured_interface_short == lldp_interface) {
|
|
90
|
+
row.addClass('success');
|
|
91
|
+
} else {
|
|
92
|
+
row.addClass('danger');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
error: function(xhr) {
|
|
97
|
+
alert(xhr.responseText);
|
|
122
98
|
}
|
|
123
99
|
});
|
|
124
100
|
});
|
|
125
101
|
</script>
|
|
126
|
-
{% endblock %}
|
|
102
|
+
{% endblock %}
|
|
@@ -206,19 +206,11 @@
|
|
|
206
206
|
</td>
|
|
207
207
|
</tr>
|
|
208
208
|
<tr>
|
|
209
|
-
<td>Controller
|
|
209
|
+
<td>Controller Device Group</td>
|
|
210
210
|
<td>
|
|
211
|
-
{{ object.
|
|
211
|
+
{{ object.controller_device_group|hyperlinked_object }}
|
|
212
212
|
</td>
|
|
213
213
|
</tr>
|
|
214
|
-
{% if object.controller_managed_device_group %}
|
|
215
|
-
<tr>
|
|
216
|
-
<td>Managed by Controller</td>
|
|
217
|
-
<td>
|
|
218
|
-
{{ object.controller_managed_device_group.controller|hyperlinked_object }}
|
|
219
|
-
</td>
|
|
220
|
-
</tr>
|
|
221
|
-
{% endif %}
|
|
222
214
|
{% if object.cluster %}
|
|
223
215
|
<tr>
|
|
224
216
|
<td>Cluster</td>
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
{% render_field form.secrets_group %}
|
|
91
91
|
{% render_field form.device_redundancy_group %}
|
|
92
92
|
{% render_field form.device_redundancy_group_priority %}
|
|
93
|
-
{% render_field form.
|
|
93
|
+
{% render_field form.controller_device_group %}
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
96
96
|
<div class="panel panel-default">
|
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
|
+
ControllerDeviceGroup,
|
|
30
30
|
Device,
|
|
31
31
|
DeviceBay,
|
|
32
32
|
DeviceBayTemplate,
|
|
@@ -771,7 +771,6 @@ class ManufacturerTest(APIViewTestCases.APIViewTestCase):
|
|
|
771
771
|
# FIXME: This has to be replaced with# `get_deletable_object` and
|
|
772
772
|
# `get_deletable_object_pks` but this is a workaround just so all of these objects are
|
|
773
773
|
# deletable for now.
|
|
774
|
-
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
775
774
|
Device.objects.all().delete()
|
|
776
775
|
DeviceType.objects.all().delete()
|
|
777
776
|
Platform.objects.all().delete()
|
|
@@ -1167,7 +1166,6 @@ class DeviceTest(APIViewTestCases.APIViewTestCase):
|
|
|
1167
1166
|
|
|
1168
1167
|
@classmethod
|
|
1169
1168
|
def setUpTestData(cls):
|
|
1170
|
-
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
1171
1169
|
Device.objects.all().delete()
|
|
1172
1170
|
locations = Location.objects.filter(location_type=LocationType.objects.get(name="Campus"))[:2]
|
|
1173
1171
|
|
|
@@ -2170,10 +2168,7 @@ class ConnectedDeviceTest(APITestCase):
|
|
|
2170
2168
|
def test_get_connected_device(self):
|
|
2171
2169
|
url = reverse("dcim-api:connected-device-list")
|
|
2172
2170
|
response = self.client.get(url + "?peer_device=TestDevice2&peer_interface=eth0", **self.header)
|
|
2173
|
-
self.assertHttpStatus(response, status.HTTP_404_NOT_FOUND)
|
|
2174
2171
|
|
|
2175
|
-
self.add_permissions("dcim.view_interface")
|
|
2176
|
-
response = self.client.get(url + "?peer_device=TestDevice2&peer_interface=eth0", **self.header)
|
|
2177
2172
|
self.assertHttpStatus(response, status.HTTP_200_OK)
|
|
2178
2173
|
self.assertEqual(response.data["name"], self.device1.name)
|
|
2179
2174
|
|
|
@@ -2818,8 +2813,8 @@ class ControllerTestCase(APIViewTestCases.APIViewTestCase):
|
|
|
2818
2813
|
}
|
|
2819
2814
|
|
|
2820
2815
|
|
|
2821
|
-
class
|
|
2822
|
-
model =
|
|
2816
|
+
class ControllerDeviceGroupTestCase(APIViewTestCases.APIViewTestCase):
|
|
2817
|
+
model = ControllerDeviceGroup
|
|
2823
2818
|
|
|
2824
2819
|
@classmethod
|
|
2825
2820
|
def setUpTestData(cls):
|
|
@@ -2827,17 +2822,17 @@ class ControllerManagedDeviceGroupTestCase(APIViewTestCases.APIViewTestCase):
|
|
|
2827
2822
|
|
|
2828
2823
|
cls.create_data = [
|
|
2829
2824
|
{
|
|
2830
|
-
"name": "
|
|
2825
|
+
"name": "ControllerDeviceGroup 1",
|
|
2831
2826
|
"controller": controllers[0].pk,
|
|
2832
2827
|
"weight": 100,
|
|
2833
2828
|
},
|
|
2834
2829
|
{
|
|
2835
|
-
"name": "
|
|
2830
|
+
"name": "ControllerDeviceGroup 2",
|
|
2836
2831
|
"controller": controllers[1].pk,
|
|
2837
2832
|
"weight": 150,
|
|
2838
2833
|
},
|
|
2839
2834
|
{
|
|
2840
|
-
"name": "
|
|
2835
|
+
"name": "ControllerDeviceGroup 3",
|
|
2841
2836
|
"controller": controllers[2].pk,
|
|
2842
2837
|
"weight": 200,
|
|
2843
2838
|
},
|
|
@@ -26,8 +26,8 @@ from nautobot.dcim.filters import (
|
|
|
26
26
|
ConsolePortTemplateFilterSet,
|
|
27
27
|
ConsoleServerPortFilterSet,
|
|
28
28
|
ConsoleServerPortTemplateFilterSet,
|
|
29
|
+
ControllerDeviceGroupFilterSet,
|
|
29
30
|
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
|
+
ControllerDeviceGroup,
|
|
72
72
|
Device,
|
|
73
73
|
DeviceBay,
|
|
74
74
|
DeviceBayTemplate,
|
|
@@ -112,7 +112,6 @@ User = get_user_model()
|
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
def common_test_data(cls):
|
|
115
|
-
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
116
115
|
Device.objects.all().delete()
|
|
117
116
|
tenants = Tenant.objects.filter(tenant_group__isnull=False)
|
|
118
117
|
cls.tenants = tenants
|
|
@@ -620,82 +619,6 @@ def common_test_data(cls):
|
|
|
620
619
|
cls.devices[0].tags.set(Tag.objects.get_for_model(Device))
|
|
621
620
|
cls.devices[1].tags.set(Tag.objects.get_for_model(Device)[:3])
|
|
622
621
|
|
|
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
|
-
|
|
699
622
|
|
|
700
623
|
class LocationTypeFilterSetTestCase(FilterTestCases.NameOnlyFilterTestCase):
|
|
701
624
|
queryset = LocationType.objects.all()
|
|
@@ -1418,8 +1341,8 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
|
|
|
1418
1341
|
("device_redundancy_group", "device_redundancy_group__id"),
|
|
1419
1342
|
("device_redundancy_group", "device_redundancy_group__name"),
|
|
1420
1343
|
("device_redundancy_group_priority",),
|
|
1421
|
-
("
|
|
1422
|
-
("
|
|
1344
|
+
("controller_device_group", "controller_device_group__id"),
|
|
1345
|
+
("controller_device_group", "controller_device_group__name"),
|
|
1423
1346
|
("device_type", "device_type__id"),
|
|
1424
1347
|
("device_type", "device_type__model"),
|
|
1425
1348
|
("front_ports", "front_ports__id"),
|
|
@@ -1492,19 +1415,19 @@ class DeviceTestCase(FilterTestCases.FilterTestCase, FilterTestCases.TenancyFilt
|
|
|
1492
1415
|
Service.objects.create(device=devices[0], name="ssh", protocol="tcp", ports=[22])
|
|
1493
1416
|
Service.objects.create(device=devices[1], name="dns", protocol="udp", ports=[53])
|
|
1494
1417
|
|
|
1495
|
-
cls.
|
|
1418
|
+
cls.controller_device_groups = list(ControllerDeviceGroup.objects.all()[:2])
|
|
1496
1419
|
cls.device_redundancy_groups = list(DeviceRedundancyGroup.objects.all()[:2])
|
|
1497
1420
|
Device.objects.filter(pk=devices[0].pk).update(
|
|
1498
|
-
|
|
1421
|
+
controller_device_group=cls.controller_device_groups[0],
|
|
1499
1422
|
device_redundancy_group=cls.device_redundancy_groups[0],
|
|
1500
1423
|
)
|
|
1501
1424
|
Device.objects.filter(pk=devices[1].pk).update(
|
|
1502
|
-
|
|
1425
|
+
controller_device_group=cls.controller_device_groups[0],
|
|
1503
1426
|
device_redundancy_group=cls.device_redundancy_groups[0],
|
|
1504
1427
|
device_redundancy_group_priority=1,
|
|
1505
1428
|
)
|
|
1506
1429
|
Device.objects.filter(pk=devices[2].pk).update(
|
|
1507
|
-
|
|
1430
|
+
controller_device_group=cls.controller_device_groups[1],
|
|
1508
1431
|
device_redundancy_group=cls.device_redundancy_groups[1],
|
|
1509
1432
|
device_redundancy_group_priority=100,
|
|
1510
1433
|
)
|
|
@@ -3432,20 +3355,63 @@ class ControllerFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
|
3432
3355
|
("platform", "platform__name"),
|
|
3433
3356
|
("external_integration", "external_integration__id"),
|
|
3434
3357
|
("external_integration", "external_integration__name"),
|
|
3435
|
-
("
|
|
3436
|
-
("
|
|
3437
|
-
("
|
|
3438
|
-
("
|
|
3358
|
+
("deployed_controller_device", "deployed_controller_device__id"),
|
|
3359
|
+
("deployed_controller_device", "deployed_controller_device__name"),
|
|
3360
|
+
("deployed_controller_group", "deployed_controller_group__id"),
|
|
3361
|
+
("deployed_controller_group", "deployed_controller_group__name"),
|
|
3439
3362
|
)
|
|
3440
3363
|
|
|
3441
3364
|
@classmethod
|
|
3442
3365
|
def setUpTestData(cls):
|
|
3443
3366
|
common_test_data(cls)
|
|
3444
3367
|
|
|
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
|
+
|
|
3445
3411
|
|
|
3446
|
-
class
|
|
3447
|
-
queryset =
|
|
3448
|
-
filterset =
|
|
3412
|
+
class ControllerDeviceGroupFilterSetTestCase(FilterTestCases.FilterTestCase):
|
|
3413
|
+
queryset = ControllerDeviceGroup.objects.all()
|
|
3414
|
+
filterset = ControllerDeviceGroupFilterSet
|
|
3449
3415
|
generic_filter_tests = (
|
|
3450
3416
|
("name",),
|
|
3451
3417
|
("weight",),
|
|
@@ -3458,3 +3424,26 @@ class ControllerManagedDeviceGroupFilterSetTestCase(FilterTestCases.FilterTestCa
|
|
|
3458
3424
|
@classmethod
|
|
3459
3425
|
def setUpTestData(cls):
|
|
3460
3426
|
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
|
+
)
|
|
@@ -4,22 +4,12 @@ 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
|
|
8
|
-
Controller,
|
|
9
|
-
Device,
|
|
10
|
-
DeviceType,
|
|
11
|
-
Interface,
|
|
12
|
-
Location,
|
|
13
|
-
LocationType,
|
|
14
|
-
Manufacturer,
|
|
15
|
-
Platform,
|
|
16
|
-
)
|
|
7
|
+
from nautobot.dcim.models import Device, DeviceType, Interface, Location, LocationType, Manufacturer, Platform
|
|
17
8
|
from nautobot.extras.models import DynamicGroup, Role, Status
|
|
18
9
|
|
|
19
10
|
|
|
20
11
|
class GraphQLTestCase(TestCase):
|
|
21
12
|
def setUp(self):
|
|
22
|
-
Controller.objects.filter(controller_device__isnull=False).delete()
|
|
23
13
|
Device.objects.all().delete()
|
|
24
14
|
self.user = create_test_user("graphql_testuser")
|
|
25
15
|
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
|
+
ControllerDeviceGroup,
|
|
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
|
+
deployed_controller_device=Device.objects.first(),
|
|
1900
|
+
deployed_controller_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["deployed_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 ControllerDeviceGroupTestCase(ModelTestCases.BaseModelTestCase):
|
|
1928
|
+
model = ControllerDeviceGroup
|
|
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 = ControllerDeviceGroup(
|
|
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 = ControllerDeviceGroup(
|
|
1940
1940
|
name="Child Group testing Controller match",
|
|
1941
1941
|
controller=next(controllers),
|
|
1942
1942
|
parent=parent_group,
|
|
@@ -1955,37 +1955,37 @@ class ControllerManagedDeviceGroupTestCase(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 = ControllerDeviceGroup.objects.create(
|
|
1959
1959
|
name="Parent Group testing Controller match",
|
|
1960
1960
|
controller=controller1,
|
|
1961
1961
|
)
|
|
1962
|
-
child_group1 =
|
|
1962
|
+
child_group1 = ControllerDeviceGroup.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 = ControllerDeviceGroup.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 = ControllerDeviceGroup.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
|
+
ControllerDeviceGroup.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
|
+
ControllerDeviceGroup.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
|
+
ControllerDeviceGroup.objects.get(pk=child_group2.pk).controller,
|
|
1989
1989
|
controller2,
|
|
1990
1990
|
"Child group 2 controller should have been updated",
|
|
1991
1991
|
)
|