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/core/wsgi.py
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import os
|
|
3
2
|
|
|
4
3
|
from django.core import cache
|
|
5
4
|
from django.core.wsgi import get_wsgi_application
|
|
6
5
|
from django.db import connections
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
import nautobot
|
|
8
|
+
|
|
9
|
+
# This is the Django default left here for visibility on how the Nautobot pattern
|
|
10
|
+
# differs.
|
|
11
|
+
# os.environ.setdefault("DJANGO_SETTINGS_MODULE", "nautobot.core.settings")
|
|
12
|
+
|
|
13
|
+
# Instead of just pointing to `DJANGO_SETTINGS_MODULE` and letting Django run with it,
|
|
14
|
+
# we're using the custom Nautobot loader code to read environment or config path for us.
|
|
15
|
+
nautobot.setup()
|
|
9
16
|
|
|
10
17
|
# Use try/except because we might not be running uWSGI. If `settings.WEBSERVER_WARMUP` is `True`,
|
|
11
18
|
# will first call `get_internal_wsgi_application` which does not have `uwsgi` module loaded
|
nautobot/dcim/api/serializers.py
CHANGED
|
@@ -55,7 +55,7 @@ from nautobot.dcim.models import (
|
|
|
55
55
|
ConsoleServerPort,
|
|
56
56
|
ConsoleServerPortTemplate,
|
|
57
57
|
Controller,
|
|
58
|
-
|
|
58
|
+
ControllerManagedDeviceGroup,
|
|
59
59
|
Device,
|
|
60
60
|
DeviceBay,
|
|
61
61
|
DeviceBayTemplate,
|
|
@@ -598,7 +598,7 @@ class DeviceSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
|
|
|
598
598
|
"secrets_group",
|
|
599
599
|
"device_redundancy_group",
|
|
600
600
|
"device_redundancy_group_priority",
|
|
601
|
-
"
|
|
601
|
+
"controller_managed_device_group",
|
|
602
602
|
]
|
|
603
603
|
},
|
|
604
604
|
},
|
|
@@ -1049,7 +1049,7 @@ class ControllerSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
|
|
|
1049
1049
|
fields = "__all__"
|
|
1050
1050
|
|
|
1051
1051
|
|
|
1052
|
-
class
|
|
1052
|
+
class ControllerManagedDeviceGroupSerializer(NautobotModelSerializer, TaggedModelSerializerMixin):
|
|
1053
1053
|
class Meta:
|
|
1054
|
-
model =
|
|
1054
|
+
model = ControllerManagedDeviceGroup
|
|
1055
1055
|
fields = "__all__"
|
nautobot/dcim/api/urls.py
CHANGED
|
@@ -2,8 +2,7 @@ from nautobot.core.api.routers import OrderedDefaultRouter
|
|
|
2
2
|
|
|
3
3
|
from . import views
|
|
4
4
|
|
|
5
|
-
router = OrderedDefaultRouter()
|
|
6
|
-
router.APIRootView = views.DCIMRootView
|
|
5
|
+
router = OrderedDefaultRouter(view_name="DCIM")
|
|
7
6
|
|
|
8
7
|
# Locations
|
|
9
8
|
router.register("location-types", views.LocationTypeViewSet)
|
|
@@ -80,7 +79,7 @@ router.register("connected-device", views.ConnectedDeviceViewSet, basename="conn
|
|
|
80
79
|
|
|
81
80
|
# Controllers
|
|
82
81
|
router.register("controllers", views.ControllerViewSet)
|
|
83
|
-
router.register("controller-device-groups", views.
|
|
82
|
+
router.register("controller-managed-device-groups", views.ControllerManagedDeviceGroupViewSet)
|
|
84
83
|
|
|
85
84
|
app_name = "dcim-api"
|
|
86
85
|
urlpatterns = router.urls
|
nautobot/dcim/api/views.py
CHANGED
|
@@ -13,7 +13,6 @@ from rest_framework.decorators import action
|
|
|
13
13
|
from rest_framework.mixins import ListModelMixin
|
|
14
14
|
from rest_framework.permissions import IsAuthenticated
|
|
15
15
|
from rest_framework.response import Response
|
|
16
|
-
from rest_framework.routers import APIRootView
|
|
17
16
|
from rest_framework.viewsets import GenericViewSet, ViewSet
|
|
18
17
|
|
|
19
18
|
from nautobot.circuits.models import Circuit
|
|
@@ -30,7 +29,7 @@ from nautobot.dcim.models import (
|
|
|
30
29
|
ConsoleServerPort,
|
|
31
30
|
ConsoleServerPortTemplate,
|
|
32
31
|
Controller,
|
|
33
|
-
|
|
32
|
+
ControllerManagedDeviceGroup,
|
|
34
33
|
Device,
|
|
35
34
|
DeviceBay,
|
|
36
35
|
DeviceBayTemplate,
|
|
@@ -76,16 +75,6 @@ from nautobot.virtualization.models import VirtualMachine
|
|
|
76
75
|
from . import serializers
|
|
77
76
|
from .exceptions import MissingFilterException
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
class DCIMRootView(APIRootView):
|
|
81
|
-
"""
|
|
82
|
-
DCIM API root view
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
def get_view_name(self):
|
|
86
|
-
return "DCIM"
|
|
87
|
-
|
|
88
|
-
|
|
89
78
|
# Mixins
|
|
90
79
|
|
|
91
80
|
|
|
@@ -391,7 +380,7 @@ class DeviceViewSet(ConfigContextQuerySetMixin, NautobotModelViewSet):
|
|
|
391
380
|
"software_version",
|
|
392
381
|
"virtual_chassis__master",
|
|
393
382
|
"device_redundancy_group",
|
|
394
|
-
"
|
|
383
|
+
"controller_managed_device_group",
|
|
395
384
|
"secrets_group",
|
|
396
385
|
"status",
|
|
397
386
|
).prefetch_related("tags", "primary_ip4__nat_outside_list", "primary_ip6__nat_outside_list", "software_image_files")
|
|
@@ -786,7 +775,7 @@ class ConnectedDeviceViewSet(ViewSet):
|
|
|
786
775
|
|
|
787
776
|
# Determine local interface from peer interface's connection
|
|
788
777
|
peer_interface = get_object_or_404(
|
|
789
|
-
Interface.objects.
|
|
778
|
+
Interface.objects.restrict(request.user, "view"),
|
|
790
779
|
device__name=peer_device_name,
|
|
791
780
|
name=peer_interface_name,
|
|
792
781
|
)
|
|
@@ -840,11 +829,11 @@ class ControllerViewSet(NautobotModelViewSet):
|
|
|
840
829
|
filterset_class = filters.ControllerFilterSet
|
|
841
830
|
|
|
842
831
|
|
|
843
|
-
class
|
|
844
|
-
queryset =
|
|
832
|
+
class ControllerManagedDeviceGroupViewSet(NautobotModelViewSet):
|
|
833
|
+
queryset = ControllerManagedDeviceGroup.objects.select_related(
|
|
845
834
|
"controller",
|
|
846
835
|
"parent",
|
|
847
836
|
).prefetch_related("tags")
|
|
848
837
|
|
|
849
|
-
serializer_class = serializers.
|
|
850
|
-
filterset_class = filters.
|
|
838
|
+
serializer_class = serializers.ControllerManagedDeviceGroupSerializer
|
|
839
|
+
filterset_class = filters.ControllerManagedDeviceGroupFilterSet
|
nautobot/dcim/apps.py
CHANGED
|
@@ -5,14 +5,18 @@ class DCIMConfig(NautobotConfig):
|
|
|
5
5
|
name = "nautobot.dcim"
|
|
6
6
|
verbose_name = "DCIM"
|
|
7
7
|
searchable_models = [
|
|
8
|
+
"cable",
|
|
9
|
+
"controller",
|
|
10
|
+
"device",
|
|
11
|
+
"devicefamily",
|
|
12
|
+
"deviceredundancygroup",
|
|
13
|
+
"devicetype",
|
|
8
14
|
"location",
|
|
15
|
+
"powerfeed",
|
|
9
16
|
"rack",
|
|
10
17
|
"rackgroup",
|
|
11
|
-
"
|
|
12
|
-
"device",
|
|
18
|
+
"softwareversion",
|
|
13
19
|
"virtualchassis",
|
|
14
|
-
"cable",
|
|
15
|
-
"powerfeed",
|
|
16
20
|
]
|
|
17
21
|
|
|
18
22
|
def ready(self):
|
nautobot/dcim/elevations.py
CHANGED
|
@@ -3,6 +3,8 @@ from django.urls import reverse
|
|
|
3
3
|
from django.utils.http import urlencode
|
|
4
4
|
import svgwrite
|
|
5
5
|
|
|
6
|
+
from nautobot.core.utils.config import get_settings_or_config
|
|
7
|
+
|
|
6
8
|
from .choices import DeviceFaceChoices
|
|
7
9
|
from .constants import RACK_ELEVATION_BORDER_WIDTH
|
|
8
10
|
|
|
@@ -233,7 +235,9 @@ class RackElevationSVG:
|
|
|
233
235
|
start_y + unit_height / 2 + RACK_ELEVATION_BORDER_WIDTH,
|
|
234
236
|
)
|
|
235
237
|
unit = ru + 1 if self.rack.desc_units else self.rack.u_height - ru
|
|
236
|
-
|
|
238
|
+
unit_two_digit_format = get_settings_or_config("RACK_ELEVATION_UNIT_TWO_DIGIT_FORMAT")
|
|
239
|
+
unit_display = f"{unit:02d}" if unit_two_digit_format else str(unit)
|
|
240
|
+
drawing.add(drawing.text(unit_display, position_coordinates, class_="unit"))
|
|
237
241
|
|
|
238
242
|
for unit in self.merge_elevations(face):
|
|
239
243
|
# Loop through all units in the elevation
|
nautobot/dcim/factory.py
CHANGED
|
@@ -26,7 +26,7 @@ from nautobot.dcim.choices import (
|
|
|
26
26
|
)
|
|
27
27
|
from nautobot.dcim.models import (
|
|
28
28
|
Controller,
|
|
29
|
-
|
|
29
|
+
ControllerManagedDeviceGroup,
|
|
30
30
|
Device,
|
|
31
31
|
DeviceFamily,
|
|
32
32
|
DeviceRedundancyGroup,
|
|
@@ -167,7 +167,7 @@ class DeviceFactory(PrimaryModelFactory):
|
|
|
167
167
|
factory.Faker("pyint", min_value=1, max_value=500),
|
|
168
168
|
)
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
controller_managed_device_group = random_instance(ControllerManagedDeviceGroup)
|
|
171
171
|
|
|
172
172
|
has_comments = NautobotBoolIterator()
|
|
173
173
|
comments = factory.Maybe("has_comments", factory.Faker("bs"))
|
|
@@ -694,19 +694,19 @@ class ControllerFactory(PrimaryModelFactory):
|
|
|
694
694
|
location = random_instance(lambda: Location.objects.get_for_model(Controller), allow_null=False)
|
|
695
695
|
tenant = random_instance(Tenant)
|
|
696
696
|
external_integration = random_instance(ExternalIntegration)
|
|
697
|
-
|
|
698
|
-
|
|
697
|
+
controller_device = factory.Maybe("has_device", random_instance(Device), None)
|
|
698
|
+
controller_device_redundancy_group = factory.Maybe("has_device", None, random_instance(DeviceRedundancyGroup))
|
|
699
699
|
|
|
700
700
|
|
|
701
|
-
class
|
|
701
|
+
class ControllerManagedDeviceGroupFactory(PrimaryModelFactory):
|
|
702
702
|
class Meta:
|
|
703
|
-
model =
|
|
703
|
+
model = ControllerManagedDeviceGroup
|
|
704
704
|
|
|
705
705
|
class Params:
|
|
706
706
|
has_parent = NautobotBoolIterator()
|
|
707
707
|
|
|
708
708
|
name = UniqueFaker("word")
|
|
709
|
-
parent = factory.Maybe("has_parent", random_instance(
|
|
709
|
+
parent = factory.Maybe("has_parent", random_instance(ControllerManagedDeviceGroup), None)
|
|
710
710
|
controller = factory.LazyAttribute(
|
|
711
711
|
lambda o: o.parent.controller if o.parent else Controller.objects.order_by("?").first()
|
|
712
712
|
)
|
|
@@ -42,7 +42,7 @@ from nautobot.dcim.models import (
|
|
|
42
42
|
ConsoleServerPort,
|
|
43
43
|
ConsoleServerPortTemplate,
|
|
44
44
|
Controller,
|
|
45
|
-
|
|
45
|
+
ControllerManagedDeviceGroup,
|
|
46
46
|
Device,
|
|
47
47
|
DeviceBay,
|
|
48
48
|
DeviceBayTemplate,
|
|
@@ -99,7 +99,7 @@ __all__ = (
|
|
|
99
99
|
"ConsoleServerPortFilterSet",
|
|
100
100
|
"ConsoleServerPortTemplateFilterSet",
|
|
101
101
|
"ControllerFilterSet",
|
|
102
|
-
"
|
|
102
|
+
"ControllerManagedDeviceGroupFilterSet",
|
|
103
103
|
"DeviceBayFilterSet",
|
|
104
104
|
"DeviceBayTemplateFilterSet",
|
|
105
105
|
"DeviceFilterSet",
|
|
@@ -918,11 +918,11 @@ class DeviceFilterSet(
|
|
|
918
918
|
to_field_name="name",
|
|
919
919
|
label="Device Redundancy Groups (name or ID)",
|
|
920
920
|
)
|
|
921
|
-
|
|
922
|
-
field_name="
|
|
923
|
-
queryset=
|
|
921
|
+
controller_managed_device_group = NaturalKeyOrPKMultipleChoiceFilter(
|
|
922
|
+
field_name="controller_managed_device_group",
|
|
923
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
924
924
|
to_field_name="name",
|
|
925
|
-
label="Controller Device Groups (name or ID)",
|
|
925
|
+
label="Controller Managed Device Groups (name or ID)",
|
|
926
926
|
)
|
|
927
927
|
virtual_chassis_member = is_virtual_chassis_member
|
|
928
928
|
has_console_ports = RelatedMembershipBooleanFilter(
|
|
@@ -1842,7 +1842,6 @@ class ControllerFilterSet(
|
|
|
1842
1842
|
NautobotFilterSet,
|
|
1843
1843
|
LocatableModelFilterSetMixin,
|
|
1844
1844
|
TenancyModelFilterSetMixin,
|
|
1845
|
-
LocalContextModelFilterSetMixin,
|
|
1846
1845
|
StatusModelFilterSetMixin,
|
|
1847
1846
|
RoleModelFilterSetMixin,
|
|
1848
1847
|
):
|
|
@@ -1864,15 +1863,15 @@ class ControllerFilterSet(
|
|
|
1864
1863
|
to_field_name="name",
|
|
1865
1864
|
label="External integration (name or ID)",
|
|
1866
1865
|
)
|
|
1867
|
-
|
|
1866
|
+
controller_device = NaturalKeyOrPKMultipleChoiceFilter(
|
|
1868
1867
|
queryset=Device.objects.all(),
|
|
1869
1868
|
to_field_name="name",
|
|
1870
|
-
label="
|
|
1869
|
+
label="Controller device (name or ID)",
|
|
1871
1870
|
)
|
|
1872
|
-
|
|
1871
|
+
controller_device_redundancy_group = NaturalKeyOrPKMultipleChoiceFilter(
|
|
1873
1872
|
queryset=DeviceRedundancyGroup.objects.all(),
|
|
1874
1873
|
to_field_name="name",
|
|
1875
|
-
label="
|
|
1874
|
+
label="Controller device redundancy group (name or ID)",
|
|
1876
1875
|
)
|
|
1877
1876
|
|
|
1878
1877
|
class Meta:
|
|
@@ -1880,8 +1879,8 @@ class ControllerFilterSet(
|
|
|
1880
1879
|
fields = "__all__"
|
|
1881
1880
|
|
|
1882
1881
|
|
|
1883
|
-
class
|
|
1884
|
-
"""Filters for
|
|
1882
|
+
class ControllerManagedDeviceGroupFilterSet(NautobotFilterSet):
|
|
1883
|
+
"""Filters for ControllerManagedDeviceGroup model."""
|
|
1885
1884
|
|
|
1886
1885
|
q = SearchFilter(
|
|
1887
1886
|
filter_predicates={
|
|
@@ -1894,7 +1893,7 @@ class ControllerDeviceGroupFilterSet(NautobotFilterSet):
|
|
|
1894
1893
|
label="Controller (name or ID)",
|
|
1895
1894
|
)
|
|
1896
1895
|
parent = NaturalKeyOrPKMultipleChoiceFilter(
|
|
1897
|
-
queryset=
|
|
1896
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
1898
1897
|
to_field_name="name",
|
|
1899
1898
|
label="Parent group (name or ID)",
|
|
1900
1899
|
)
|
|
@@ -1906,7 +1905,7 @@ class ControllerDeviceGroupFilterSet(NautobotFilterSet):
|
|
|
1906
1905
|
)
|
|
1907
1906
|
|
|
1908
1907
|
class Meta:
|
|
1909
|
-
model =
|
|
1908
|
+
model = ControllerManagedDeviceGroup
|
|
1910
1909
|
fields = "__all__"
|
|
1911
1910
|
|
|
1912
1911
|
def generate_query__subtree(self, value):
|
|
@@ -1914,7 +1913,7 @@ class ControllerDeviceGroupFilterSet(NautobotFilterSet):
|
|
|
1914
1913
|
if value:
|
|
1915
1914
|
params = Q(pk__in=[v.pk for v in value])
|
|
1916
1915
|
filter_name = "in"
|
|
1917
|
-
for _ in range(
|
|
1916
|
+
for _ in range(ControllerManagedDeviceGroup.objects.max_depth + 1):
|
|
1918
1917
|
filter_name = f"parent__{filter_name}"
|
|
1919
1918
|
params |= Q(**{filter_name: value})
|
|
1920
1919
|
return params
|
|
@@ -1922,6 +1921,6 @@ class ControllerDeviceGroupFilterSet(NautobotFilterSet):
|
|
|
1922
1921
|
|
|
1923
1922
|
@extend_schema_field({"type": "string"})
|
|
1924
1923
|
def _subtree(self, queryset, name, value):
|
|
1925
|
-
"""FilterSet method for getting Groups that are or are descended from a given
|
|
1924
|
+
"""FilterSet method for getting Groups that are or are descended from a given ControllerManagedDeviceGroup(s)."""
|
|
1926
1925
|
params = self.generate_query__subtree(value)
|
|
1927
1926
|
return queryset.filter(params)
|
nautobot/dcim/forms.py
CHANGED
|
@@ -55,7 +55,7 @@ from nautobot.extras.forms import (
|
|
|
55
55
|
)
|
|
56
56
|
from nautobot.extras.models import ExternalIntegration, SecretsGroup, Status
|
|
57
57
|
from nautobot.ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
|
|
58
|
-
from nautobot.ipam.models import IPAddress, IPAddressToInterface, VLAN, VRF
|
|
58
|
+
from nautobot.ipam.models import IPAddress, IPAddressToInterface, VLAN, VLANLocationAssignment, VRF
|
|
59
59
|
from nautobot.tenancy.forms import TenancyFilterForm, TenancyForm
|
|
60
60
|
from nautobot.tenancy.models import Tenant, TenantGroup
|
|
61
61
|
from nautobot.virtualization.models import Cluster, ClusterGroup, VirtualMachine
|
|
@@ -95,7 +95,7 @@ from .models import (
|
|
|
95
95
|
ConsoleServerPort,
|
|
96
96
|
ConsoleServerPortTemplate,
|
|
97
97
|
Controller,
|
|
98
|
-
|
|
98
|
+
ControllerManagedDeviceGroup,
|
|
99
99
|
Device,
|
|
100
100
|
DeviceBay,
|
|
101
101
|
DeviceBayTemplate,
|
|
@@ -194,8 +194,13 @@ class InterfaceCommonForm(forms.Form):
|
|
|
194
194
|
# TODO: after Location model replaced Site, which was not a hierarchical model, should we allow users to add a VLAN
|
|
195
195
|
# belongs to the parent Location or the child location of the parent device to the `tagged_vlan` field of the interface?
|
|
196
196
|
elif mode == InterfaceModeChoices.MODE_TAGGED:
|
|
197
|
-
|
|
198
|
-
invalid_vlans = [
|
|
197
|
+
valid_location = self.cleaned_data[parent_field].location
|
|
198
|
+
invalid_vlans = [
|
|
199
|
+
str(v)
|
|
200
|
+
for v in tagged_vlans
|
|
201
|
+
if v.locations.without_tree_fields().exists()
|
|
202
|
+
and not VLANLocationAssignment.objects.filter(location=valid_location, vlan=v).exists()
|
|
203
|
+
]
|
|
199
204
|
|
|
200
205
|
if invalid_vlans:
|
|
201
206
|
raise forms.ValidationError(
|
|
@@ -1548,7 +1553,9 @@ class DeviceForm(LocatableModelFormMixin, NautobotModelForm, TenancyForm, LocalC
|
|
|
1548
1553
|
},
|
|
1549
1554
|
)
|
|
1550
1555
|
device_redundancy_group = DynamicModelChoiceField(queryset=DeviceRedundancyGroup.objects.all(), required=False)
|
|
1551
|
-
|
|
1556
|
+
controller_managed_device_group = DynamicModelChoiceField(
|
|
1557
|
+
queryset=ControllerManagedDeviceGroup.objects.all(), required=False
|
|
1558
|
+
)
|
|
1552
1559
|
position = forms.IntegerField(
|
|
1553
1560
|
required=False,
|
|
1554
1561
|
help_text="The lowest-numbered unit occupied by the device",
|
|
@@ -1618,7 +1625,7 @@ class DeviceForm(LocatableModelFormMixin, NautobotModelForm, TenancyForm, LocalC
|
|
|
1618
1625
|
"rack",
|
|
1619
1626
|
"device_redundancy_group",
|
|
1620
1627
|
"device_redundancy_group_priority",
|
|
1621
|
-
"
|
|
1628
|
+
"controller_managed_device_group",
|
|
1622
1629
|
"position",
|
|
1623
1630
|
"face",
|
|
1624
1631
|
"status",
|
|
@@ -1760,7 +1767,9 @@ class DeviceBulkEditForm(
|
|
|
1760
1767
|
secrets_group = DynamicModelChoiceField(queryset=SecretsGroup.objects.all(), required=False)
|
|
1761
1768
|
device_redundancy_group = DynamicModelChoiceField(queryset=DeviceRedundancyGroup.objects.all(), required=False)
|
|
1762
1769
|
device_redundancy_group_priority = forms.IntegerField(required=False, min_value=1)
|
|
1763
|
-
|
|
1770
|
+
controller_managed_device_group = DynamicModelChoiceField(
|
|
1771
|
+
queryset=ControllerManagedDeviceGroup.objects.all(), required=False
|
|
1772
|
+
)
|
|
1764
1773
|
software_version = DynamicModelChoiceField(queryset=SoftwareVersion.objects.all(), required=False)
|
|
1765
1774
|
software_image_files = DynamicModelMultipleChoiceField(queryset=SoftwareImageFile.objects.all(), required=False)
|
|
1766
1775
|
|
|
@@ -1778,7 +1787,7 @@ class DeviceBulkEditForm(
|
|
|
1778
1787
|
"secrets_group",
|
|
1779
1788
|
"device_redundancy_group",
|
|
1780
1789
|
"device_redundancy_group_priority",
|
|
1781
|
-
"
|
|
1790
|
+
"controller_managed_device_group",
|
|
1782
1791
|
"software_image_files",
|
|
1783
1792
|
"software_version",
|
|
1784
1793
|
]
|
|
@@ -1858,8 +1867,8 @@ class DeviceFilterForm(
|
|
|
1858
1867
|
null_option="None",
|
|
1859
1868
|
)
|
|
1860
1869
|
device_redundancy_group_priority = NumericArrayField(base_field=forms.IntegerField(min_value=1), required=False)
|
|
1861
|
-
|
|
1862
|
-
queryset=
|
|
1870
|
+
controller_managed_device_group = DynamicModelMultipleChoiceField(
|
|
1871
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
1863
1872
|
to_field_name="name",
|
|
1864
1873
|
required=False,
|
|
1865
1874
|
null_option="None",
|
|
@@ -4123,9 +4132,30 @@ class SoftwareVersionForm(NautobotModelForm):
|
|
|
4123
4132
|
fields = "__all__"
|
|
4124
4133
|
|
|
4125
4134
|
|
|
4126
|
-
class ControllerForm(LocatableModelFormMixin, NautobotModelForm, TenancyForm
|
|
4135
|
+
class ControllerForm(LocatableModelFormMixin, NautobotModelForm, TenancyForm):
|
|
4127
4136
|
"""Controller create/edit form."""
|
|
4128
4137
|
|
|
4138
|
+
platform = DynamicModelChoiceField(
|
|
4139
|
+
queryset=Platform.objects.all(),
|
|
4140
|
+
required=False,
|
|
4141
|
+
)
|
|
4142
|
+
tenant = DynamicModelChoiceField(
|
|
4143
|
+
queryset=Tenant.objects.all(),
|
|
4144
|
+
required=False,
|
|
4145
|
+
)
|
|
4146
|
+
external_integration = DynamicModelChoiceField(
|
|
4147
|
+
queryset=ExternalIntegration.objects.all(),
|
|
4148
|
+
required=False,
|
|
4149
|
+
)
|
|
4150
|
+
controller_device = DynamicModelChoiceField(
|
|
4151
|
+
queryset=Device.objects.all(),
|
|
4152
|
+
required=False,
|
|
4153
|
+
)
|
|
4154
|
+
controller_device_redundancy_group = DynamicModelChoiceField(
|
|
4155
|
+
queryset=DeviceRedundancyGroup.objects.all(),
|
|
4156
|
+
required=False,
|
|
4157
|
+
)
|
|
4158
|
+
|
|
4129
4159
|
class Meta:
|
|
4130
4160
|
model = Controller
|
|
4131
4161
|
fields = (
|
|
@@ -4137,15 +4167,14 @@ class ControllerForm(LocatableModelFormMixin, NautobotModelForm, TenancyForm, Lo
|
|
|
4137
4167
|
"tenant",
|
|
4138
4168
|
"location",
|
|
4139
4169
|
"external_integration",
|
|
4140
|
-
"
|
|
4141
|
-
"
|
|
4170
|
+
"controller_device",
|
|
4171
|
+
"controller_device_redundancy_group",
|
|
4142
4172
|
"tags",
|
|
4143
4173
|
)
|
|
4144
4174
|
|
|
4145
4175
|
|
|
4146
4176
|
class ControllerFilterForm(
|
|
4147
4177
|
NautobotFilterForm,
|
|
4148
|
-
LocalContextFilterForm,
|
|
4149
4178
|
LocatableModelFilterFormMixin,
|
|
4150
4179
|
TenancyFilterForm,
|
|
4151
4180
|
StatusModelFilterFormMixin,
|
|
@@ -4167,15 +4196,15 @@ class ControllerFilterForm(
|
|
|
4167
4196
|
required=False,
|
|
4168
4197
|
label="External integration",
|
|
4169
4198
|
)
|
|
4170
|
-
|
|
4199
|
+
controller_device = DynamicModelMultipleChoiceField(
|
|
4171
4200
|
queryset=Device.objects.all(),
|
|
4172
4201
|
required=False,
|
|
4173
|
-
label="
|
|
4202
|
+
label="Controller device",
|
|
4174
4203
|
)
|
|
4175
|
-
|
|
4204
|
+
controller_device_redundancy_group = DynamicModelMultipleChoiceField(
|
|
4176
4205
|
queryset=DeviceRedundancyGroup.objects.all(),
|
|
4177
4206
|
required=False,
|
|
4178
|
-
label="
|
|
4207
|
+
label="Controller device redundancy group",
|
|
4179
4208
|
)
|
|
4180
4209
|
tags = TagFilterField(model)
|
|
4181
4210
|
field_order = (
|
|
@@ -4188,8 +4217,8 @@ class ControllerFilterForm(
|
|
|
4188
4217
|
"platform",
|
|
4189
4218
|
"tenant",
|
|
4190
4219
|
"external_integration",
|
|
4191
|
-
"
|
|
4192
|
-
"
|
|
4220
|
+
"controller_device",
|
|
4221
|
+
"controller_device_redundancy_group",
|
|
4193
4222
|
"tags",
|
|
4194
4223
|
)
|
|
4195
4224
|
|
|
@@ -4200,7 +4229,6 @@ class ControllerBulkEditForm(
|
|
|
4200
4229
|
StatusModelBulkEditFormMixin,
|
|
4201
4230
|
RoleModelBulkEditFormMixin,
|
|
4202
4231
|
NautobotBulkEditForm,
|
|
4203
|
-
LocalContextModelBulkEditForm,
|
|
4204
4232
|
):
|
|
4205
4233
|
"""Controller bulk edit form."""
|
|
4206
4234
|
|
|
@@ -4220,11 +4248,11 @@ class ControllerBulkEditForm(
|
|
|
4220
4248
|
queryset=ExternalIntegration.objects.all(),
|
|
4221
4249
|
required=False,
|
|
4222
4250
|
)
|
|
4223
|
-
|
|
4251
|
+
controller_device = DynamicModelChoiceField(
|
|
4224
4252
|
queryset=Device.objects.all(),
|
|
4225
4253
|
required=False,
|
|
4226
4254
|
)
|
|
4227
|
-
|
|
4255
|
+
controller_device_redundancy_group = DynamicModelChoiceField(
|
|
4228
4256
|
queryset=DeviceRedundancyGroup.objects.all(),
|
|
4229
4257
|
required=False,
|
|
4230
4258
|
)
|
|
@@ -4239,24 +4267,24 @@ class ControllerBulkEditForm(
|
|
|
4239
4267
|
"platform",
|
|
4240
4268
|
"tenant",
|
|
4241
4269
|
"external_integration",
|
|
4242
|
-
"
|
|
4243
|
-
"
|
|
4270
|
+
"controller_device",
|
|
4271
|
+
"controller_device_redundancy_group",
|
|
4244
4272
|
"tags",
|
|
4245
4273
|
)
|
|
4246
4274
|
|
|
4247
4275
|
|
|
4248
|
-
class
|
|
4249
|
-
"""
|
|
4276
|
+
class ControllerManagedDeviceGroupForm(NautobotModelForm):
|
|
4277
|
+
"""ControllerManagedDeviceGroup create/edit form."""
|
|
4250
4278
|
|
|
4251
|
-
controller = DynamicModelChoiceField(queryset=Controller.objects.all(), required=
|
|
4279
|
+
controller = DynamicModelChoiceField(queryset=Controller.objects.all(), required=True)
|
|
4252
4280
|
devices = DynamicModelMultipleChoiceField(queryset=Device.objects.all(), required=False)
|
|
4253
|
-
parent = DynamicModelChoiceField(queryset=
|
|
4281
|
+
parent = DynamicModelChoiceField(queryset=ControllerManagedDeviceGroup.objects.all(), required=False)
|
|
4254
4282
|
|
|
4255
4283
|
class Meta:
|
|
4256
|
-
model =
|
|
4284
|
+
model = ControllerManagedDeviceGroup
|
|
4257
4285
|
fields = (
|
|
4258
|
-
"name",
|
|
4259
4286
|
"controller",
|
|
4287
|
+
"name",
|
|
4260
4288
|
"devices",
|
|
4261
4289
|
"parent",
|
|
4262
4290
|
"weight",
|
|
@@ -4275,13 +4303,10 @@ class ControllerDeviceGroupForm(NautobotModelForm):
|
|
|
4275
4303
|
return instance
|
|
4276
4304
|
|
|
4277
4305
|
|
|
4278
|
-
class
|
|
4279
|
-
|
|
4280
|
-
NautobotFilterForm,
|
|
4281
|
-
):
|
|
4282
|
-
"""ControllerDeviceGroup basic filter form."""
|
|
4306
|
+
class ControllerManagedDeviceGroupFilterForm(NautobotFilterForm):
|
|
4307
|
+
"""ControllerManagedDeviceGroup basic filter form."""
|
|
4283
4308
|
|
|
4284
|
-
model =
|
|
4309
|
+
model = ControllerManagedDeviceGroup
|
|
4285
4310
|
q = forms.CharField(required=False, label="Search")
|
|
4286
4311
|
name = forms.CharField(required=False, label="Name")
|
|
4287
4312
|
controller = DynamicModelChoiceField(
|
|
@@ -4290,13 +4315,13 @@ class ControllerDeviceGroupFilterForm(
|
|
|
4290
4315
|
label="Controller",
|
|
4291
4316
|
)
|
|
4292
4317
|
parent = DynamicModelChoiceField(
|
|
4293
|
-
queryset=
|
|
4318
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
4294
4319
|
required=False,
|
|
4295
4320
|
label="Parent",
|
|
4296
4321
|
)
|
|
4297
4322
|
weight = forms.IntegerField(required=False, label="Weight")
|
|
4298
4323
|
subtree = DynamicModelMultipleChoiceField(
|
|
4299
|
-
queryset=
|
|
4324
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
4300
4325
|
to_field_name="name",
|
|
4301
4326
|
required=False,
|
|
4302
4327
|
)
|
|
@@ -4312,23 +4337,19 @@ class ControllerDeviceGroupFilterForm(
|
|
|
4312
4337
|
)
|
|
4313
4338
|
|
|
4314
4339
|
|
|
4315
|
-
class
|
|
4316
|
-
|
|
4317
|
-
NautobotBulkEditForm,
|
|
4318
|
-
LocalContextModelBulkEditForm,
|
|
4319
|
-
):
|
|
4320
|
-
"""ControllerDeviceGroup bulk edit form."""
|
|
4340
|
+
class ControllerManagedDeviceGroupBulkEditForm(TagsBulkEditFormMixin, NautobotBulkEditForm):
|
|
4341
|
+
"""ControllerManagedDeviceGroup bulk edit form."""
|
|
4321
4342
|
|
|
4322
4343
|
pk = forms.ModelMultipleChoiceField(
|
|
4323
|
-
queryset=
|
|
4344
|
+
queryset=ControllerManagedDeviceGroup.objects.all(),
|
|
4324
4345
|
widget=forms.MultipleHiddenInput,
|
|
4325
4346
|
)
|
|
4326
4347
|
controller = DynamicModelChoiceField(queryset=Controller.objects.all(), required=False)
|
|
4327
|
-
parent = DynamicModelChoiceField(queryset=
|
|
4348
|
+
parent = DynamicModelChoiceField(queryset=ControllerManagedDeviceGroup.objects.all(), required=False)
|
|
4328
4349
|
weight = forms.IntegerField(required=False)
|
|
4329
4350
|
|
|
4330
4351
|
class Meta:
|
|
4331
|
-
model =
|
|
4352
|
+
model = ControllerManagedDeviceGroup
|
|
4332
4353
|
fields = (
|
|
4333
4354
|
"controller",
|
|
4334
4355
|
"parent",
|
nautobot/dcim/homepage.py
CHANGED
|
@@ -79,13 +79,21 @@ layout = (
|
|
|
79
79
|
description="Represents a set of devices which share a common control plane",
|
|
80
80
|
weight=400,
|
|
81
81
|
),
|
|
82
|
+
HomePageItem(
|
|
83
|
+
name="Controllers",
|
|
84
|
+
link="dcim:controller_list",
|
|
85
|
+
model=models.Controller,
|
|
86
|
+
permissions=["dcim.view_controller"],
|
|
87
|
+
description="Represents a network or SDN (Software-Defined Networking) controllers",
|
|
88
|
+
weight=500,
|
|
89
|
+
),
|
|
82
90
|
HomePageItem(
|
|
83
91
|
name="Device Redundancy Groups",
|
|
84
92
|
link="dcim:deviceredundancygroup_list",
|
|
85
93
|
model=models.DeviceRedundancyGroup,
|
|
86
94
|
permissions=["dcim.view_deviceredundancygroup"],
|
|
87
95
|
description="Represents a set of devices which operate in a failover/HA group",
|
|
88
|
-
weight=
|
|
96
|
+
weight=600,
|
|
89
97
|
),
|
|
90
98
|
HomePageItem(
|
|
91
99
|
name="Interface Redundancy Groups",
|
|
@@ -93,11 +101,11 @@ layout = (
|
|
|
93
101
|
model=models.InterfaceRedundancyGroup,
|
|
94
102
|
permissions=["dcim.view_interfaceredundancygroup"],
|
|
95
103
|
description="Represents a set of interfaces which operate in a failover/HA group",
|
|
96
|
-
weight=
|
|
104
|
+
weight=700,
|
|
97
105
|
),
|
|
98
106
|
HomePageGroup(
|
|
99
107
|
name="Connections",
|
|
100
|
-
weight=
|
|
108
|
+
weight=800,
|
|
101
109
|
items=(
|
|
102
110
|
HomePageItem(
|
|
103
111
|
name="Cables",
|