nautobot 2.4.11__py3-none-any.whl → 2.4.12__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/circuits/templates/circuits/circuittermination_retrieve.html +1 -114
- nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +1 -1
- nautobot/circuits/views.py +76 -6
- nautobot/cloud/navigation.py +1 -1
- nautobot/core/jobs/cleanup.py +4 -4
- nautobot/core/templates/components/panel/header_extra_content_table.html +12 -1
- nautobot/core/templates/components/panel/panel.html +4 -0
- nautobot/core/templates/generic/object_retrieve.html +1 -0
- nautobot/core/tests/test_utils.py +1 -177
- nautobot/core/tests/test_views.py +2 -2
- nautobot/core/ui/object_detail.py +1 -1
- nautobot/core/utils/module_loading.py +58 -63
- nautobot/dcim/filters/__init__.py +6 -0
- nautobot/dcim/filters/mixins.py +2 -1
- nautobot/dcim/models/devices.py +10 -0
- nautobot/dcim/tables/devices.py +2 -0
- nautobot/dcim/templates/dcim/controller/base.html +1 -9
- nautobot/dcim/templates/dcim/controller_retrieve.html +2 -83
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +2 -25
- nautobot/dcim/templates/dcim/virtualchassis.html +2 -51
- nautobot/dcim/templates/dcim/virtualchassis_add.html +2 -22
- nautobot/dcim/templates/dcim/virtualchassis_create.html +22 -0
- nautobot/dcim/templates/dcim/virtualchassis_edit.html +2 -93
- nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +51 -0
- nautobot/dcim/templates/dcim/virtualchassis_update.html +93 -0
- nautobot/dcim/urls.py +1 -58
- nautobot/dcim/views.py +145 -189
- nautobot/extras/datasources/git.py +2 -2
- nautobot/extras/jobs_ui.py +208 -0
- nautobot/extras/models/tags.py +4 -0
- nautobot/extras/tables.py +1 -1
- nautobot/extras/templates/extras/configcontextschema_retrieve.html +2 -2
- nautobot/extras/templates/extras/inc/configcontext_data.html +1 -1
- nautobot/extras/templates/extras/inc/configcontext_format.html +6 -0
- nautobot/extras/templates/extras/inc/json_data.html +1 -1
- nautobot/extras/templates/extras/inc/json_format.html +2 -2
- nautobot/extras/templates/extras/job_detail.html +1 -326
- nautobot/extras/templates/extras/tag_retrieve.html +1 -51
- nautobot/extras/views.py +80 -27
- nautobot/project-static/docs/404.html +2 -2
- nautobot/project-static/docs/apps/index.html +2 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.13a4f30d.min.js → bundle.56ea9cef.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.13a4f30d.min.js.map → bundle.56ea9cef.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2 -2
- nautobot/project-static/docs/development/apps/api/configuration-view.html +2 -2
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/global-search.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/graphql.html +2 -2
- nautobot/project-static/docs/development/apps/api/models/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +2 -2
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +2 -2
- nautobot/project-static/docs/development/apps/api/prometheus.html +2 -2
- nautobot/project-static/docs/development/apps/api/setup.html +2 -2
- nautobot/project-static/docs/development/apps/api/testing.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +2 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/index.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/notes.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +2 -2
- nautobot/project-static/docs/development/apps/api/views/urls.html +2 -2
- nautobot/project-static/docs/development/apps/index.html +2 -2
- nautobot/project-static/docs/development/apps/migration/code-updates.html +2 -2
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +2 -2
- nautobot/project-static/docs/development/apps/migration/from-v1.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +2 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +2 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +2 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +2 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +2 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +2 -2
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +2 -2
- nautobot/project-static/docs/development/core/application-registry.html +2 -2
- nautobot/project-static/docs/development/core/best-practices.html +2 -2
- nautobot/project-static/docs/development/core/bootstrap-ui.html +2 -2
- nautobot/project-static/docs/development/core/caching.html +2 -2
- nautobot/project-static/docs/development/core/controllers.html +2 -2
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +2 -2
- nautobot/project-static/docs/development/core/generic-views.html +2 -2
- nautobot/project-static/docs/development/core/getting-started.html +2 -2
- nautobot/project-static/docs/development/core/homepage.html +2 -2
- nautobot/project-static/docs/development/core/index.html +2 -2
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +2 -2
- nautobot/project-static/docs/development/core/model-checklist.html +2 -2
- nautobot/project-static/docs/development/core/model-features.html +2 -2
- nautobot/project-static/docs/development/core/natural-keys.html +2 -2
- nautobot/project-static/docs/development/core/navigation-menu.html +2 -2
- nautobot/project-static/docs/development/core/release-checklist.html +2 -2
- nautobot/project-static/docs/development/core/role-internals.html +2 -2
- nautobot/project-static/docs/development/core/settings.html +2 -2
- nautobot/project-static/docs/development/core/style-guide.html +2 -2
- nautobot/project-static/docs/development/core/templates.html +2 -2
- nautobot/project-static/docs/development/core/testing.html +2 -2
- nautobot/project-static/docs/development/core/ui-component-framework.html +2 -2
- nautobot/project-static/docs/development/core/user-preferences.html +2 -2
- nautobot/project-static/docs/development/index.html +2 -2
- nautobot/project-static/docs/development/jobs/getting-started.html +2 -6
- nautobot/project-static/docs/development/jobs/index.html +2 -2
- nautobot/project-static/docs/development/jobs/installation.html +2 -2
- nautobot/project-static/docs/development/jobs/job-extensions.html +2 -2
- nautobot/project-static/docs/development/jobs/job-logging.html +2 -2
- nautobot/project-static/docs/development/jobs/job-patterns.html +2 -2
- nautobot/project-static/docs/development/jobs/job-structure.html +2 -2
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +2 -2
- nautobot/project-static/docs/development/jobs/testing.html +2 -2
- nautobot/project-static/docs/index.html +2 -2
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +2 -2
- nautobot/project-static/docs/overview/design_philosophy.html +2 -2
- nautobot/project-static/docs/release-notes/index.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.0.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.1.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.2.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.3.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.4.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.5.html +2 -2
- nautobot/project-static/docs/release-notes/version-1.6.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.0.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.1.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.2.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.3.html +2 -2
- nautobot/project-static/docs/release-notes/version-2.4.html +111 -2
- nautobot/project-static/docs/requirements.txt +1 -1
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +299 -299
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +2 -2
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +2 -2
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +2 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +2 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +2 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +2 -2
- nautobot/project-static/docs/user-guide/administration/security/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/security/notices.html +2 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +2 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +2 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +2 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +3 -3
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +2 -2
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +2 -2
- nautobot/project-static/docs/user-guide/index.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +2 -2
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +2 -2
- nautobot/wireless/navigation.py +1 -1
- nautobot/wireless/tables.py +13 -5
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/METADATA +1 -1
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/RECORD +354 -349
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/NOTICE +0 -0
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/WHEEL +0 -0
- {nautobot-2.4.11.dist-info → nautobot-2.4.12.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% load helpers %}
|
|
3
|
+
{% load form_helpers %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<form action="" method="post" enctype="multipart/form-data" class="form form-horizontal">
|
|
7
|
+
{% csrf_token %}
|
|
8
|
+
{{ pk_form.pk }}
|
|
9
|
+
{{ formset.management_form }}
|
|
10
|
+
<div class="row">
|
|
11
|
+
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
|
|
12
|
+
<h3>{% block title %}{% if vc_form.instance %}Editing {{ vc_form.instance }}{% else %}New Virtual Chassis{% endif %}{% endblock %}</h3>
|
|
13
|
+
{% if vc_form.non_field_errors %}
|
|
14
|
+
<div class="panel panel-danger">
|
|
15
|
+
<div class="panel-heading"><strong>Errors</strong></div>
|
|
16
|
+
<div class="panel-body">
|
|
17
|
+
{{ vc_form.non_field_errors }}
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
{% endif %}
|
|
21
|
+
<div class="panel panel-default">
|
|
22
|
+
<div class="panel-heading"><strong>Virtual Chassis</strong></div>
|
|
23
|
+
<div class="table panel-body">
|
|
24
|
+
{% render_field vc_form.name %}
|
|
25
|
+
{% render_field vc_form.domain %}
|
|
26
|
+
{% render_field vc_form.master %}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{% include 'inc/extras_features_edit_form_fields.html' with form=vc_form %}
|
|
30
|
+
<div class="panel panel-default">
|
|
31
|
+
<div class="panel-heading"><strong>Members</strong></div>
|
|
32
|
+
<table class="table panel-body">
|
|
33
|
+
<thead>
|
|
34
|
+
<tr>
|
|
35
|
+
<th>Device</th>
|
|
36
|
+
<th>Rack/Unit</th>
|
|
37
|
+
<th>Serial</th>
|
|
38
|
+
<th>Position</th>
|
|
39
|
+
<th>Priority</th>
|
|
40
|
+
<th></th>
|
|
41
|
+
</tr>
|
|
42
|
+
</thead>
|
|
43
|
+
<tbody>
|
|
44
|
+
{% for form in formset %}
|
|
45
|
+
{% for field in form.hidden_fields %}
|
|
46
|
+
{{ field }}
|
|
47
|
+
{% endfor %}
|
|
48
|
+
{% with device=form.instance virtual_chassis=vc_form.instance %}
|
|
49
|
+
<tr>
|
|
50
|
+
<td>{{ device|hyperlinked_object }}</td>
|
|
51
|
+
<td>
|
|
52
|
+
{% if device.rack %}
|
|
53
|
+
{{ device.rack }} / {{ device.position }}
|
|
54
|
+
{% else %}
|
|
55
|
+
<span class="text-muted">—</span>
|
|
56
|
+
{% endif %}
|
|
57
|
+
</td>
|
|
58
|
+
<td>{{ device.serial|placeholder }}</td>
|
|
59
|
+
<td>
|
|
60
|
+
{{ form.vc_position }}
|
|
61
|
+
{% if form.vc_position.errors %}
|
|
62
|
+
<br /><small class="text-danger">{{ form.vc_position.errors.0 }}</small>
|
|
63
|
+
{% endif %}
|
|
64
|
+
</td>
|
|
65
|
+
<td>
|
|
66
|
+
{{ form.vc_priority }}
|
|
67
|
+
{% if form.vc_priority.errors %}
|
|
68
|
+
<br /><small class="text-danger">{{ form.vc_priority.errors.0 }}</small>
|
|
69
|
+
{% endif %}
|
|
70
|
+
</td>
|
|
71
|
+
<td>
|
|
72
|
+
{% if virtual_chassis.present_in_database %}
|
|
73
|
+
<a href="{% url 'dcim:virtualchassis_remove_member' pk=device.pk %}?return_url={% url 'dcim:virtualchassis_edit' pk=virtual_chassis.pk %}" class="btn btn-danger btn-xs{% if virtual_chassis.master == device %} disabled{% endif %}">
|
|
74
|
+
<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span>
|
|
75
|
+
</a>
|
|
76
|
+
{% endif %}
|
|
77
|
+
</td>
|
|
78
|
+
</tr>
|
|
79
|
+
{% endwith %}
|
|
80
|
+
{% endfor %}
|
|
81
|
+
</tbody>
|
|
82
|
+
</table>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="row">
|
|
87
|
+
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-right">
|
|
88
|
+
<button type="submit" name="_update" class="btn btn-primary">Update</button>
|
|
89
|
+
<a href="{{ return_url }}" class="btn btn-default">Cancel</a>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</form>
|
|
93
|
+
{% endblock %}
|
nautobot/dcim/urls.py
CHANGED
|
@@ -21,7 +21,6 @@ from .models import (
|
|
|
21
21
|
PowerPort,
|
|
22
22
|
Rack,
|
|
23
23
|
RearPort,
|
|
24
|
-
VirtualChassis,
|
|
25
24
|
)
|
|
26
25
|
|
|
27
26
|
app_name = "dcim"
|
|
@@ -49,6 +48,7 @@ router.register("rack-groups", views.RackGroupUIViewSet)
|
|
|
49
48
|
router.register("rack-reservations", views.RackReservationUIViewSet)
|
|
50
49
|
router.register("software-image-files", views.SoftwareImageFileUIViewSet)
|
|
51
50
|
router.register("software-versions", views.SoftwareVersionUIViewSet)
|
|
51
|
+
router.register("virtual-chassis", views.VirtualChassisUIViewSet)
|
|
52
52
|
router.register("virtual-device-contexts", views.VirtualDeviceContextUIViewSet)
|
|
53
53
|
|
|
54
54
|
urlpatterns = [
|
|
@@ -1194,63 +1194,6 @@ urlpatterns = [
|
|
|
1194
1194
|
name="interface_connections_list",
|
|
1195
1195
|
),
|
|
1196
1196
|
# Virtual chassis
|
|
1197
|
-
path(
|
|
1198
|
-
"virtual-chassis/",
|
|
1199
|
-
views.VirtualChassisListView.as_view(),
|
|
1200
|
-
name="virtualchassis_list",
|
|
1201
|
-
),
|
|
1202
|
-
path(
|
|
1203
|
-
"virtual-chassis/add/",
|
|
1204
|
-
views.VirtualChassisCreateView.as_view(),
|
|
1205
|
-
name="virtualchassis_add",
|
|
1206
|
-
),
|
|
1207
|
-
path(
|
|
1208
|
-
"virtual-chassis/import/",
|
|
1209
|
-
views.VirtualChassisBulkImportView.as_view(), # 3.0 TODO: remove, unused
|
|
1210
|
-
name="virtualchassis_import",
|
|
1211
|
-
),
|
|
1212
|
-
path(
|
|
1213
|
-
"virtual-chassis/edit/",
|
|
1214
|
-
views.VirtualChassisBulkEditView.as_view(),
|
|
1215
|
-
name="virtualchassis_bulk_edit",
|
|
1216
|
-
),
|
|
1217
|
-
path(
|
|
1218
|
-
"virtual-chassis/delete/",
|
|
1219
|
-
views.VirtualChassisBulkDeleteView.as_view(),
|
|
1220
|
-
name="virtualchassis_bulk_delete",
|
|
1221
|
-
),
|
|
1222
|
-
path(
|
|
1223
|
-
"virtual-chassis/<uuid:pk>/",
|
|
1224
|
-
views.VirtualChassisView.as_view(),
|
|
1225
|
-
name="virtualchassis",
|
|
1226
|
-
),
|
|
1227
|
-
path(
|
|
1228
|
-
"virtual-chassis/<uuid:pk>/edit/",
|
|
1229
|
-
views.VirtualChassisEditView.as_view(),
|
|
1230
|
-
name="virtualchassis_edit",
|
|
1231
|
-
),
|
|
1232
|
-
path(
|
|
1233
|
-
"virtual-chassis/<uuid:pk>/delete/",
|
|
1234
|
-
views.VirtualChassisDeleteView.as_view(),
|
|
1235
|
-
name="virtualchassis_delete",
|
|
1236
|
-
),
|
|
1237
|
-
path(
|
|
1238
|
-
"virtual-chassis/<uuid:pk>/changelog/",
|
|
1239
|
-
ObjectChangeLogView.as_view(),
|
|
1240
|
-
name="virtualchassis_changelog",
|
|
1241
|
-
kwargs={"model": VirtualChassis},
|
|
1242
|
-
),
|
|
1243
|
-
path(
|
|
1244
|
-
"virtual-chassis/<uuid:pk>/notes/",
|
|
1245
|
-
ObjectNotesView.as_view(),
|
|
1246
|
-
name="virtualchassis_notes",
|
|
1247
|
-
kwargs={"model": VirtualChassis},
|
|
1248
|
-
),
|
|
1249
|
-
path(
|
|
1250
|
-
"virtual-chassis/<uuid:pk>/add-member/",
|
|
1251
|
-
views.VirtualChassisAddMemberView.as_view(),
|
|
1252
|
-
name="virtualchassis_add_member",
|
|
1253
|
-
),
|
|
1254
1197
|
path(
|
|
1255
1198
|
"virtual-chassis-members/<uuid:pk>/delete/",
|
|
1256
1199
|
views.VirtualChassisRemoveMemberView.as_view(),
|
nautobot/dcim/views.py
CHANGED
|
@@ -70,8 +70,8 @@ from nautobot.wireless.models import (
|
|
|
70
70
|
ControllerManagedDeviceGroupWirelessNetworkAssignment,
|
|
71
71
|
)
|
|
72
72
|
from nautobot.wireless.tables import (
|
|
73
|
+
BaseControllerManagedDeviceGroupWirelessNetworkAssignmentTable,
|
|
73
74
|
ControllerManagedDeviceGroupRadioProfileAssignmentTable,
|
|
74
|
-
ControllerManagedDeviceGroupWirelessNetworkAssignmentTable,
|
|
75
75
|
DeviceGroupWirelessNetworkTable,
|
|
76
76
|
RadioProfileTable,
|
|
77
77
|
)
|
|
@@ -2238,7 +2238,7 @@ class DeviceWirelessView(generic.ObjectView):
|
|
|
2238
2238
|
wireless_networks = ControllerManagedDeviceGroupWirelessNetworkAssignment.objects.filter(
|
|
2239
2239
|
controller_managed_device_group=controller_managed_device_group
|
|
2240
2240
|
).select_related("wireless_network", "controller_managed_device_group", "vlan")
|
|
2241
|
-
wireless_networks_table =
|
|
2241
|
+
wireless_networks_table = BaseControllerManagedDeviceGroupWirelessNetworkAssignmentTable(
|
|
2242
2242
|
data=wireless_networks, user=request.user, orderable=False
|
|
2243
2243
|
)
|
|
2244
2244
|
wireless_networks_table.columns.hide("controller_managed_device_group")
|
|
@@ -3907,151 +3907,102 @@ class InterfaceConnectionsListView(ConnectionsListView):
|
|
|
3907
3907
|
#
|
|
3908
3908
|
|
|
3909
3909
|
|
|
3910
|
-
class
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
class VirtualChassisView(generic.ObjectView):
|
|
3910
|
+
class VirtualChassisUIViewSet(NautobotUIViewSet):
|
|
3911
|
+
bulk_update_form_class = forms.VirtualChassisBulkEditForm
|
|
3912
|
+
filterset_class = filters.VirtualChassisFilterSet
|
|
3913
|
+
filterset_form_class = forms.VirtualChassisFilterForm
|
|
3914
|
+
form_class = forms.VirtualChassisCreateForm
|
|
3915
|
+
serializer_class = serializers.VirtualChassisSerializer
|
|
3916
|
+
table_class = tables.VirtualChassisTable
|
|
3918
3917
|
queryset = VirtualChassis.objects.all()
|
|
3919
3918
|
|
|
3920
3919
|
def get_extra_context(self, request, instance):
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
return {"members": members, **super().get_extra_context(request, instance)}
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
class VirtualChassisCreateView(generic.ObjectEditView):
|
|
3927
|
-
queryset = VirtualChassis.objects.all()
|
|
3928
|
-
model_form = forms.VirtualChassisCreateForm
|
|
3929
|
-
template_name = "dcim/virtualchassis_add.html"
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
class VirtualChassisEditView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View):
|
|
3933
|
-
queryset = VirtualChassis.objects.all()
|
|
3934
|
-
|
|
3935
|
-
def get_required_permission(self):
|
|
3936
|
-
return "dcim.change_virtualchassis"
|
|
3937
|
-
|
|
3938
|
-
def get(self, request, pk):
|
|
3939
|
-
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
|
|
3940
|
-
VCMemberFormSet = modelformset_factory(
|
|
3941
|
-
model=Device,
|
|
3942
|
-
form=forms.DeviceVCMembershipForm,
|
|
3943
|
-
formset=forms.BaseVCMemberFormSet,
|
|
3944
|
-
extra=0,
|
|
3945
|
-
)
|
|
3946
|
-
members_queryset = virtual_chassis.members.select_related("rack").order_by("vc_position")
|
|
3947
|
-
|
|
3948
|
-
vc_form = forms.VirtualChassisForm(instance=virtual_chassis)
|
|
3949
|
-
vc_form.fields["master"].queryset = members_queryset
|
|
3950
|
-
formset = VCMemberFormSet(queryset=members_queryset)
|
|
3951
|
-
|
|
3952
|
-
return render(
|
|
3953
|
-
request,
|
|
3954
|
-
"dcim/virtualchassis_edit.html",
|
|
3955
|
-
{
|
|
3956
|
-
"vc_form": vc_form,
|
|
3957
|
-
"formset": formset,
|
|
3958
|
-
"return_url": self.get_return_url(request, virtual_chassis),
|
|
3959
|
-
},
|
|
3960
|
-
)
|
|
3961
|
-
|
|
3962
|
-
def post(self, request, pk):
|
|
3963
|
-
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
|
|
3964
|
-
VCMemberFormSet = modelformset_factory(
|
|
3965
|
-
model=Device,
|
|
3966
|
-
form=forms.DeviceVCMembershipForm,
|
|
3967
|
-
formset=forms.BaseVCMemberFormSet,
|
|
3968
|
-
extra=0,
|
|
3969
|
-
)
|
|
3970
|
-
members_queryset = virtual_chassis.members.select_related("rack").order_by("vc_position")
|
|
3971
|
-
|
|
3972
|
-
vc_form = forms.VirtualChassisForm(request.POST, instance=virtual_chassis)
|
|
3973
|
-
vc_form.fields["master"].queryset = members_queryset
|
|
3974
|
-
formset = VCMemberFormSet(request.POST, queryset=members_queryset)
|
|
3975
|
-
|
|
3976
|
-
if vc_form.is_valid() and formset.is_valid():
|
|
3977
|
-
with transaction.atomic():
|
|
3978
|
-
# Save the VirtualChassis
|
|
3979
|
-
vc_form.save()
|
|
3980
|
-
|
|
3981
|
-
# Nullify the vc_position of each member first to allow reordering without raising an IntegrityError on
|
|
3982
|
-
# duplicate positions. Then save each member instance.
|
|
3983
|
-
members = formset.save(commit=False)
|
|
3984
|
-
devices = Device.objects.filter(pk__in=[m.pk for m in members])
|
|
3985
|
-
for device in devices:
|
|
3986
|
-
device.vc_position = None
|
|
3987
|
-
device.save()
|
|
3988
|
-
for member in members:
|
|
3989
|
-
member.save()
|
|
3990
|
-
|
|
3991
|
-
return redirect(virtual_chassis.get_absolute_url())
|
|
3992
|
-
|
|
3993
|
-
return render(
|
|
3994
|
-
request,
|
|
3995
|
-
"dcim/virtualchassis_edit.html",
|
|
3996
|
-
{
|
|
3997
|
-
"vc_form": vc_form,
|
|
3998
|
-
"formset": formset,
|
|
3999
|
-
"return_url": self.get_return_url(request, virtual_chassis),
|
|
4000
|
-
},
|
|
4001
|
-
)
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
class VirtualChassisDeleteView(generic.ObjectDeleteView):
|
|
4005
|
-
queryset = VirtualChassis.objects.all()
|
|
3920
|
+
context = super().get_extra_context(request, instance)
|
|
4006
3921
|
|
|
3922
|
+
if self.action == "update":
|
|
3923
|
+
VCMemberFormSet = modelformset_factory(
|
|
3924
|
+
model=Device,
|
|
3925
|
+
form=forms.DeviceVCMembershipForm,
|
|
3926
|
+
formset=forms.BaseVCMemberFormSet,
|
|
3927
|
+
extra=0,
|
|
3928
|
+
)
|
|
3929
|
+
members_queryset = instance.members.select_related("rack").order_by("vc_position")
|
|
4007
3930
|
|
|
4008
|
-
|
|
4009
|
-
|
|
3931
|
+
if request.method == "POST":
|
|
3932
|
+
formset = VCMemberFormSet(request.POST, queryset=members_queryset)
|
|
3933
|
+
else:
|
|
3934
|
+
formset = VCMemberFormSet(queryset=members_queryset)
|
|
4010
3935
|
|
|
4011
|
-
|
|
4012
|
-
|
|
3936
|
+
vc_form = forms.VirtualChassisForm(instance=instance)
|
|
3937
|
+
vc_form.fields["master"].queryset = members_queryset
|
|
4013
3938
|
|
|
4014
|
-
|
|
4015
|
-
|
|
3939
|
+
context.update(
|
|
3940
|
+
{
|
|
3941
|
+
"formset": formset,
|
|
3942
|
+
"vc_form": vc_form,
|
|
3943
|
+
"return_url": self.get_return_url(request, instance),
|
|
3944
|
+
}
|
|
3945
|
+
)
|
|
4016
3946
|
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
3947
|
+
elif self.action == "retrieve":
|
|
3948
|
+
members = Device.objects.restrict(request.user).filter(virtual_chassis=instance)
|
|
3949
|
+
context.update({"members": members})
|
|
4020
3950
|
|
|
4021
|
-
return
|
|
4022
|
-
request,
|
|
4023
|
-
"dcim/virtualchassis_add_member.html",
|
|
4024
|
-
{
|
|
4025
|
-
"virtual_chassis": virtual_chassis,
|
|
4026
|
-
"member_select_form": member_select_form,
|
|
4027
|
-
"membership_form": membership_form,
|
|
4028
|
-
"return_url": self.get_return_url(request, virtual_chassis),
|
|
4029
|
-
},
|
|
4030
|
-
)
|
|
3951
|
+
return context
|
|
4031
3952
|
|
|
4032
|
-
def
|
|
4033
|
-
|
|
3953
|
+
def form_save(self, form, **kwargs):
|
|
3954
|
+
obj = super().form_save(form, **kwargs)
|
|
4034
3955
|
|
|
4035
|
-
|
|
3956
|
+
if self.action == "update":
|
|
3957
|
+
context = self.get_extra_context(self.request, obj)
|
|
3958
|
+
formset = context.get("formset")
|
|
4036
3959
|
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
3960
|
+
if formset.is_valid():
|
|
3961
|
+
with transaction.atomic():
|
|
3962
|
+
members = formset.save(commit=False)
|
|
3963
|
+
# Nullify the vc_position of each member first to allow reordering without raising an IntegrityError on
|
|
3964
|
+
# duplicate positions. Then save each member instance.
|
|
3965
|
+
Device.objects.filter(pk__in=[m.pk for m in members]).update(vc_position=None)
|
|
3966
|
+
for member in members:
|
|
3967
|
+
member.save()
|
|
3968
|
+
else:
|
|
3969
|
+
raise ValidationError(formset.errors)
|
|
4042
3970
|
|
|
4043
|
-
|
|
4044
|
-
membership_form.save()
|
|
4045
|
-
msg = format_html('Added member <a href="{}">{}</a>', device.get_absolute_url(), device)
|
|
4046
|
-
messages.success(request, msg)
|
|
3971
|
+
return obj
|
|
4047
3972
|
|
|
4048
|
-
|
|
4049
|
-
|
|
3973
|
+
@action(
|
|
3974
|
+
detail=True,
|
|
3975
|
+
methods=["get", "post"],
|
|
3976
|
+
url_path="add-member",
|
|
3977
|
+
url_name="add_member",
|
|
3978
|
+
custom_view_base_action="change",
|
|
3979
|
+
custom_view_additional_permissions=["dcim.change_virtualchassis"],
|
|
3980
|
+
)
|
|
3981
|
+
def add_member(self, request, pk=None):
|
|
3982
|
+
virtual_chassis = self.get_object()
|
|
4050
3983
|
|
|
4051
|
-
|
|
3984
|
+
if request.method == "POST":
|
|
3985
|
+
member_select_form = forms.VCMemberSelectForm(request.POST)
|
|
3986
|
+
if member_select_form.is_valid():
|
|
3987
|
+
device = member_select_form.cleaned_data["device"]
|
|
3988
|
+
device.virtual_chassis = virtual_chassis
|
|
3989
|
+
data = {k: request.POST[k] for k in ["vc_position", "vc_priority"]}
|
|
3990
|
+
membership_form = forms.DeviceVCMembershipForm(data=data, validate_vc_position=True, instance=device)
|
|
3991
|
+
|
|
3992
|
+
if membership_form.is_valid():
|
|
3993
|
+
membership_form.save()
|
|
3994
|
+
msg = format_html('Added member <a href="{}">{}</a>', device.get_absolute_url(), device)
|
|
3995
|
+
messages.success(request, msg)
|
|
4052
3996
|
|
|
3997
|
+
if "_addanother" in request.POST:
|
|
3998
|
+
return redirect(request.get_full_path())
|
|
3999
|
+
return redirect(self.get_return_url(request, device))
|
|
4000
|
+
else:
|
|
4001
|
+
membership_form = forms.DeviceVCMembershipForm(data=request.POST)
|
|
4053
4002
|
else:
|
|
4054
|
-
|
|
4003
|
+
initial_data = {k: request.GET[k] for k in request.GET}
|
|
4004
|
+
member_select_form = forms.VCMemberSelectForm(initial=initial_data)
|
|
4005
|
+
membership_form = forms.DeviceVCMembershipForm(initial=initial_data)
|
|
4055
4006
|
|
|
4056
4007
|
return render(
|
|
4057
4008
|
request,
|
|
@@ -4120,24 +4071,6 @@ class VirtualChassisRemoveMemberView(ObjectPermissionRequiredMixin, GetReturnURL
|
|
|
4120
4071
|
)
|
|
4121
4072
|
|
|
4122
4073
|
|
|
4123
|
-
class VirtualChassisBulkImportView(generic.BulkImportView): # 3.0 TODO: remove, unused
|
|
4124
|
-
queryset = VirtualChassis.objects.all()
|
|
4125
|
-
table = tables.VirtualChassisTable
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
class VirtualChassisBulkEditView(generic.BulkEditView):
|
|
4129
|
-
queryset = VirtualChassis.objects.all()
|
|
4130
|
-
filterset = filters.VirtualChassisFilterSet
|
|
4131
|
-
table = tables.VirtualChassisTable
|
|
4132
|
-
form = forms.VirtualChassisBulkEditForm
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
class VirtualChassisBulkDeleteView(generic.BulkDeleteView):
|
|
4136
|
-
queryset = VirtualChassis.objects.all()
|
|
4137
|
-
filterset = filters.VirtualChassisFilterSet
|
|
4138
|
-
table = tables.VirtualChassisTable
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
4074
|
#
|
|
4142
4075
|
# Power panels
|
|
4143
4076
|
#
|
|
@@ -4687,25 +4620,69 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
4687
4620
|
table_class = tables.ControllerTable
|
|
4688
4621
|
template_name = "dcim/controller_create.html"
|
|
4689
4622
|
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4623
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
4624
|
+
panels=(
|
|
4625
|
+
object_detail.ObjectFieldsPanel(
|
|
4626
|
+
section=SectionChoices.LEFT_HALF,
|
|
4627
|
+
weight=100,
|
|
4628
|
+
fields="__all__",
|
|
4629
|
+
value_transforms={
|
|
4630
|
+
"capabilities": [helpers.label_list],
|
|
4631
|
+
},
|
|
4632
|
+
exclude_fields=[
|
|
4633
|
+
"external_integration",
|
|
4634
|
+
"controller_device",
|
|
4635
|
+
"controller_device_redundancy_group",
|
|
4636
|
+
],
|
|
4637
|
+
),
|
|
4638
|
+
object_detail.ObjectFieldsPanel(
|
|
4639
|
+
section=SectionChoices.RIGHT_HALF,
|
|
4640
|
+
weight=200,
|
|
4641
|
+
label="Integration",
|
|
4642
|
+
fields=[
|
|
4643
|
+
"external_integration",
|
|
4644
|
+
"controller_device",
|
|
4645
|
+
"controller_device_redundancy_group",
|
|
4646
|
+
],
|
|
4647
|
+
),
|
|
4648
|
+
object_detail.ObjectsTablePanel(
|
|
4649
|
+
section=SectionChoices.FULL_WIDTH,
|
|
4650
|
+
weight=100,
|
|
4651
|
+
table_class=tables.DeviceTable,
|
|
4652
|
+
table_title="Managed Devices",
|
|
4653
|
+
table_filter="controller_managed_device_group__controller",
|
|
4654
|
+
include_columns=[
|
|
4655
|
+
"capabilities",
|
|
4656
|
+
"controller_managed_device_group",
|
|
4657
|
+
"manufacturer",
|
|
4658
|
+
],
|
|
4659
|
+
related_field_name="controller",
|
|
4660
|
+
add_button_route=None,
|
|
4661
|
+
),
|
|
4662
|
+
),
|
|
4663
|
+
extra_tabs=(
|
|
4664
|
+
object_detail.DistinctViewTab(
|
|
4665
|
+
weight=700,
|
|
4666
|
+
tab_id="wireless_networks",
|
|
4667
|
+
url_name="dcim:controller_wirelessnetworks",
|
|
4668
|
+
label="Wireless Networks",
|
|
4669
|
+
related_object_attribute="wireless_network_assignments",
|
|
4670
|
+
panels=(
|
|
4671
|
+
object_detail.ObjectsTablePanel(
|
|
4672
|
+
section=SectionChoices.FULL_WIDTH,
|
|
4673
|
+
weight=100,
|
|
4674
|
+
table_title="Wireless Networks",
|
|
4675
|
+
table_class=BaseControllerManagedDeviceGroupWirelessNetworkAssignmentTable,
|
|
4676
|
+
table_filter="controller_managed_device_group__controller",
|
|
4677
|
+
tab_id="wireless_networks",
|
|
4678
|
+
add_button_route=None,
|
|
4679
|
+
select_related_fields=["wireless_network"],
|
|
4680
|
+
exclude_columns=["controller"],
|
|
4681
|
+
),
|
|
4682
|
+
),
|
|
4683
|
+
),
|
|
4684
|
+
),
|
|
4685
|
+
)
|
|
4709
4686
|
|
|
4710
4687
|
@action(
|
|
4711
4688
|
detail=True,
|
|
@@ -4716,28 +4693,7 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
4716
4693
|
custom_view_additional_permissions=["wireless.view_controllermanageddevicegroupwirelessnetworkassignment"],
|
|
4717
4694
|
)
|
|
4718
4695
|
def wirelessnetworks(self, request, *args, **kwargs):
|
|
4719
|
-
|
|
4720
|
-
controller_managed_device_groups = instance.controller_managed_device_groups.restrict(
|
|
4721
|
-
request.user, "view"
|
|
4722
|
-
).values_list("pk", flat=True)
|
|
4723
|
-
wireless_networks = ControllerManagedDeviceGroupWirelessNetworkAssignment.objects.filter(
|
|
4724
|
-
controller_managed_device_group__in=list(controller_managed_device_groups)
|
|
4725
|
-
).select_related("wireless_network")
|
|
4726
|
-
wireless_networks_table = ControllerManagedDeviceGroupWirelessNetworkAssignmentTable(
|
|
4727
|
-
data=wireless_networks, user=request.user, orderable=False
|
|
4728
|
-
)
|
|
4729
|
-
wireless_networks_table.columns.hide("controller")
|
|
4730
|
-
|
|
4731
|
-
RequestConfig(
|
|
4732
|
-
request, paginate={"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
4733
|
-
).configure(wireless_networks_table)
|
|
4734
|
-
|
|
4735
|
-
return Response(
|
|
4736
|
-
{
|
|
4737
|
-
"wireless_networks_table": wireless_networks_table,
|
|
4738
|
-
"active_tab": "wireless-networks",
|
|
4739
|
-
}
|
|
4740
|
-
)
|
|
4696
|
+
return Response({})
|
|
4741
4697
|
|
|
4742
4698
|
|
|
4743
4699
|
class ControllerManagedDeviceGroupUIViewSet(NautobotUIViewSet):
|
|
@@ -720,8 +720,8 @@ def refresh_job_code_from_repository(repository_slug, skip_reimport=False, ignor
|
|
|
720
720
|
After cloning/updating/deleting a GitRepository on disk, call this function to reload and reregister its Python.
|
|
721
721
|
|
|
722
722
|
Args:
|
|
723
|
-
repository_slug (str): Repository
|
|
724
|
-
skip_reimport (bool): If True, unload existing
|
|
723
|
+
repository_slug (str): Repository directory in GIT_ROOT that was updated or deleted.
|
|
724
|
+
skip_reimport (bool): If True, unload existing code from this repository but do not re-import it.
|
|
725
725
|
ignore_import_errors (bool): If True, any exceptions raised in the import will be caught and logged.
|
|
726
726
|
If False, exceptions will be re-raised after logging.
|
|
727
727
|
"""
|