nautobot 2.3.0__py3-none-any.whl → 2.3.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/cloud/factory.py +0 -2
- nautobot/cloud/filters.py +0 -3
- nautobot/cloud/forms.py +1 -7
- nautobot/cloud/migrations/0001_initial.py +1 -1
- nautobot/cloud/models.py +2 -1
- nautobot/cloud/tables.py +17 -1
- nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +7 -1
- nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +0 -11
- nautobot/cloud/templates/cloud/cloudservice_retrieve.html +0 -4
- nautobot/cloud/tests/test_filters.py +0 -12
- nautobot/core/filters.py +1 -15
- nautobot/core/forms/forms.py +2 -10
- nautobot/core/graphql/generators.py +2 -2
- nautobot/core/graphql/schema.py +14 -6
- nautobot/core/jobs/__init__.py +1 -4
- nautobot/core/management/commands/generate_test_data.py +2 -2
- nautobot/core/models/__init__.py +2 -2
- nautobot/core/settings.py +2 -13
- nautobot/core/settings.yaml +2 -16
- nautobot/core/tables.py +0 -3
- nautobot/core/templates/generic/object_retrieve.html +5 -5
- nautobot/core/templates/nautobot_config.py.j2 +0 -15
- nautobot/core/testing/filters.py +1 -12
- nautobot/core/tests/integration/test_general_functionality.py +1 -1
- nautobot/core/tests/test_jobs.py +1 -74
- nautobot/core/views/generic.py +1 -1
- nautobot/core/views/mixins.py +1 -1
- nautobot/core/views/utils.py +6 -8
- nautobot/dcim/factory.py +1 -4
- nautobot/dcim/filters/__init__.py +0 -4
- nautobot/dcim/forms.py +0 -5
- nautobot/dcim/migrations/0061_module_models.py +0 -1
- nautobot/dcim/models/device_components.py +0 -7
- nautobot/dcim/models/devices.py +4 -6
- nautobot/dcim/models/racks.py +1 -0
- nautobot/dcim/tables/devices.py +3 -17
- nautobot/dcim/tables/devicetypes.py +1 -1
- nautobot/dcim/templates/dcim/device/base.html +1 -1
- nautobot/dcim/templates/dcim/device.html +2 -2
- nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +0 -6
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +0 -17
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +2 -2
- nautobot/dcim/tests/test_api.py +0 -2
- nautobot/dcim/tests/test_filters.py +7 -14
- nautobot/dcim/tests/test_models.py +0 -31
- nautobot/dcim/tests/test_views.py +0 -39
- nautobot/dcim/views.py +1 -4
- nautobot/extras/api/views.py +59 -7
- nautobot/extras/factory.py +12 -50
- nautobot/extras/forms/base.py +4 -10
- nautobot/extras/homepage.py +2 -12
- nautobot/extras/jobs.py +2 -2
- nautobot/extras/migrations/0111_metadata.py +4 -4
- nautobot/extras/models/jobs.py +0 -83
- nautobot/extras/models/metadata.py +18 -18
- nautobot/extras/models/models.py +0 -2
- nautobot/extras/signals.py +1 -14
- nautobot/extras/tables.py +14 -43
- nautobot/extras/templates/extras/job_detail.html +0 -11
- nautobot/extras/tests/test_api.py +9 -16
- nautobot/extras/tests/test_jobs.py +2 -2
- nautobot/extras/tests/test_models.py +18 -20
- nautobot/extras/tests/test_views.py +3 -23
- nautobot/extras/utils.py +6 -35
- nautobot/extras/views.py +50 -27
- nautobot/ipam/filters.py +1 -1
- nautobot/ipam/forms.py +1 -1
- nautobot/ipam/models.py +20 -9
- nautobot/ipam/tables.py +0 -4
- nautobot/ipam/tests/test_models.py +2 -3
- nautobot/ipam/views.py +11 -6
- nautobot/project-static/css/base.css +0 -1
- nautobot/project-static/docs/404.html +18 -18
- nautobot/project-static/docs/apps/index.html +18 -18
- nautobot/project-static/docs/apps/nautobot-apps.html +18 -18
- nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.76a95c52.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +18 -66
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +18 -66
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +18 -34
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +18 -82
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +21 -75
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +18 -34
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +18 -34
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +18 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +19 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +18 -34
- nautobot/project-static/docs/development/apps/api/configuration-view.html +18 -18
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +18 -18
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +18 -18
- nautobot/project-static/docs/development/apps/api/models/global-search.html +18 -18
- nautobot/project-static/docs/development/apps/api/models/graphql.html +18 -18
- nautobot/project-static/docs/development/apps/api/models/index.html +22 -33
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +18 -18
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +18 -18
- nautobot/project-static/docs/development/apps/api/prometheus.html +18 -18
- nautobot/project-static/docs/development/apps/api/setup.html +18 -18
- nautobot/project-static/docs/development/apps/api/testing.html +18 -18
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +18 -18
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +18 -18
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +18 -18
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +18 -18
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/base-template.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/index.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/notes.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +18 -18
- nautobot/project-static/docs/development/apps/api/views/urls.html +18 -18
- nautobot/project-static/docs/development/apps/index.html +18 -18
- nautobot/project-static/docs/development/apps/migration/code-updates.html +18 -18
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +18 -18
- nautobot/project-static/docs/development/apps/migration/from-v1.html +18 -18
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +18 -18
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +18 -18
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +18 -18
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +18 -18
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +18 -18
- nautobot/project-static/docs/development/core/application-registry.html +18 -18
- nautobot/project-static/docs/development/core/best-practices.html +18 -18
- nautobot/project-static/docs/development/core/bootstrap-ui.html +18 -18
- nautobot/project-static/docs/development/core/caching.html +18 -18
- nautobot/project-static/docs/development/core/controllers.html +18 -18
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +18 -18
- nautobot/project-static/docs/development/core/generic-views.html +18 -18
- nautobot/project-static/docs/development/core/getting-started.html +18 -18
- nautobot/project-static/docs/development/core/homepage.html +18 -18
- nautobot/project-static/docs/development/core/index.html +18 -29
- nautobot/project-static/docs/development/core/model-checklist.html +20 -26
- nautobot/project-static/docs/development/core/model-features.html +18 -18
- nautobot/project-static/docs/development/core/natural-keys.html +18 -18
- nautobot/project-static/docs/development/core/navigation-menu.html +18 -18
- nautobot/project-static/docs/development/core/release-checklist.html +18 -18
- nautobot/project-static/docs/development/core/role-internals.html +18 -18
- nautobot/project-static/docs/development/core/settings.html +18 -18
- nautobot/project-static/docs/development/core/style-guide.html +19 -19
- nautobot/project-static/docs/development/core/templates.html +18 -18
- nautobot/project-static/docs/development/core/testing.html +18 -18
- nautobot/project-static/docs/development/core/user-preferences.html +18 -18
- nautobot/project-static/docs/development/index.html +18 -18
- nautobot/project-static/docs/development/jobs/index.html +379 -393
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +18 -18
- nautobot/project-static/docs/index.html +13 -9032
- nautobot/project-static/docs/models/extras/metadatachoice.html +3 -3
- nautobot/project-static/docs/models/extras/metadatatype.html +3 -3
- nautobot/project-static/docs/models/extras/objectmetadata.html +3 -3
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +18 -18
- nautobot/project-static/docs/overview/design_philosophy.html +20 -20
- nautobot/project-static/docs/overview/index.html +9032 -13
- nautobot/project-static/docs/release-notes/index.html +19 -252
- nautobot/project-static/docs/release-notes/version-1.0.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.1.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.2.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.3.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.4.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.5.html +18 -18
- nautobot/project-static/docs/release-notes/version-1.6.html +18 -18
- nautobot/project-static/docs/release-notes/version-2.0.html +18 -18
- nautobot/project-static/docs/release-notes/version-2.1.html +18 -18
- nautobot/project-static/docs/release-notes/version-2.2.html +111 -248
- nautobot/project-static/docs/release-notes/version-2.3.html +90 -520
- nautobot/project-static/docs/requirements.txt +3 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +278 -278
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +18 -18
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +18 -18
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +18 -18
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +18 -18
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +20 -52
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +18 -18
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +18 -22
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +18 -18
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +18 -18
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +18 -18
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +18 -18
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +82 -69
- nautobot/project-static/docs/user-guide/administration/installation/index.html +24 -24
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +52 -60
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +87 -80
- nautobot/project-static/docs/user-guide/administration/installation/services.html +44 -37
- nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +18 -18
- nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +18 -18
- nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +18 -18
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +18 -18
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +18 -18
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +24 -76
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +18 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +19 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +19 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +18 -62
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +18 -18
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +18 -18
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +18 -18
- nautobot/project-static/docs/user-guide/index.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +21 -21
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/{objectmetadata.html → metadata.html} +84 -197
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +36 -36
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +33 -33
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +21 -21
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +18 -18
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +18 -18
- nautobot/tenancy/templates/tenancy/tenant.html +4 -4
- nautobot/virtualization/models.py +2 -0
- nautobot/virtualization/tables.py +5 -2
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/METADATA +3 -3
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/RECORD +364 -364
- nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.3cba04c6.min.css.map +0 -1
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/NOTICE +0 -0
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/WHEEL +0 -0
- {nautobot-2.3.0.dist-info → nautobot-2.3.0b1.dist-info}/entry_points.txt +0 -0
nautobot/core/views/generic.py
CHANGED
|
@@ -586,7 +586,6 @@ class ObjectDeleteView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
|
|
586
586
|
|
|
587
587
|
if form.is_valid():
|
|
588
588
|
logger.debug("Form validation was successful")
|
|
589
|
-
msg = f"Deleted {self.queryset.model._meta.verbose_name} {obj}"
|
|
590
589
|
|
|
591
590
|
try:
|
|
592
591
|
obj.delete()
|
|
@@ -595,6 +594,7 @@ class ObjectDeleteView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
|
|
595
594
|
handle_protectederror([obj], request, e)
|
|
596
595
|
return redirect(obj.get_absolute_url())
|
|
597
596
|
|
|
597
|
+
msg = f"Deleted {self.queryset.model._meta.verbose_name} {obj}"
|
|
598
598
|
logger.info(msg)
|
|
599
599
|
messages.success(request, msg)
|
|
600
600
|
|
nautobot/core/views/mixins.py
CHANGED
|
@@ -745,8 +745,8 @@ class ObjectDestroyViewMixin(NautobotViewSetMixin, mixins.DestroyModelMixin):
|
|
|
745
745
|
queryset = self.get_queryset()
|
|
746
746
|
try:
|
|
747
747
|
with transaction.atomic():
|
|
748
|
-
msg = f"Deleted {queryset.model._meta.verbose_name} {obj}"
|
|
749
748
|
obj.delete()
|
|
749
|
+
msg = f"Deleted {queryset.model._meta.verbose_name} {obj}"
|
|
750
750
|
self.logger.info(msg)
|
|
751
751
|
messages.success(request, msg)
|
|
752
752
|
self.success_url = self.get_return_url(request, obj)
|
nautobot/core/views/utils.py
CHANGED
|
@@ -360,14 +360,12 @@ def common_detail_view_context(request, instance):
|
|
|
360
360
|
|
|
361
361
|
if instance.is_metadata_associable_model:
|
|
362
362
|
paginate = {"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
)
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
RequestConfig(request, paginate).configure(object_metadata_table)
|
|
369
|
-
context["associated_object_metadata_table"] = object_metadata_table
|
|
363
|
+
object_metadatas = instance.associated_object_metadatas.restrict(request.user, "view").order_by("scoped_fields")
|
|
364
|
+
object_metadatas_table = ObjectMetadataTable(object_metadatas, orderable=False)
|
|
365
|
+
object_metadatas_table.columns.hide("assigned_object")
|
|
366
|
+
RequestConfig(request, paginate).configure(object_metadatas_table)
|
|
367
|
+
context["associated_object_metadatas_table"] = object_metadatas_table
|
|
370
368
|
else:
|
|
371
|
-
context["
|
|
369
|
+
context["associated_object_metadatas_table"] = None
|
|
372
370
|
|
|
373
371
|
return context
|
nautobot/dcim/factory.py
CHANGED
|
@@ -760,16 +760,13 @@ module_types = (
|
|
|
760
760
|
class ModuleTypeFactory(PrimaryModelFactory):
|
|
761
761
|
class Meta:
|
|
762
762
|
model = ModuleType
|
|
763
|
-
exclude = ("has_part_number",
|
|
763
|
+
exclude = ("has_part_number",)
|
|
764
764
|
|
|
765
765
|
manufacturer = random_instance(Manufacturer, allow_null=False)
|
|
766
766
|
|
|
767
767
|
has_part_number = NautobotBoolIterator()
|
|
768
768
|
part_number = factory.Maybe("has_part_number", factory.Faker("ean", length=8), "")
|
|
769
769
|
|
|
770
|
-
has_comments = NautobotBoolIterator()
|
|
771
|
-
comments = factory.Maybe("has_comments", factory.Faker("bs"))
|
|
772
|
-
|
|
773
770
|
@factory.lazy_attribute
|
|
774
771
|
def model(self):
|
|
775
772
|
"""
|
|
@@ -1999,10 +1999,6 @@ class ModuleTypeFilterSet(DeviceTypeModuleTypeCommonFiltersMixin, NautobotFilter
|
|
|
1999
1999
|
"lookup_expr": "icontains",
|
|
2000
2000
|
"preprocessor": str.strip,
|
|
2001
2001
|
},
|
|
2002
|
-
"comments": {
|
|
2003
|
-
"lookup_expr": "icontains",
|
|
2004
|
-
"preprocessor": str.strip,
|
|
2005
|
-
},
|
|
2006
2002
|
},
|
|
2007
2003
|
)
|
|
2008
2004
|
has_modules = RelatedMembershipBooleanFilter(
|
nautobot/dcim/forms.py
CHANGED
|
@@ -886,7 +886,6 @@ class DeviceTypeBulkEditForm(TagsBulkEditFormMixin, NautobotBulkEditForm):
|
|
|
886
886
|
software_image_files = DynamicModelMultipleChoiceField(queryset=SoftwareImageFile.objects.all(), required=False)
|
|
887
887
|
u_height = forms.IntegerField(required=False)
|
|
888
888
|
is_full_depth = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label="Is full depth")
|
|
889
|
-
comments = CommentField(label="Comments", required=False)
|
|
890
889
|
|
|
891
890
|
class Meta:
|
|
892
891
|
nullable_fields = ["device_family", "software_image_files"]
|
|
@@ -947,7 +946,6 @@ class DeviceTypeFilterForm(NautobotFilterForm):
|
|
|
947
946
|
|
|
948
947
|
class ModuleTypeForm(NautobotModelForm):
|
|
949
948
|
manufacturer = DynamicModelChoiceField(queryset=Manufacturer.objects.all())
|
|
950
|
-
comments = CommentField(label="Comments")
|
|
951
949
|
|
|
952
950
|
class Meta:
|
|
953
951
|
model = ModuleType
|
|
@@ -955,7 +953,6 @@ class ModuleTypeForm(NautobotModelForm):
|
|
|
955
953
|
"manufacturer",
|
|
956
954
|
"model",
|
|
957
955
|
"part_number",
|
|
958
|
-
"comments",
|
|
959
956
|
"tags",
|
|
960
957
|
]
|
|
961
958
|
|
|
@@ -977,7 +974,6 @@ class ModuleTypeImportForm(BootstrapMixin, forms.ModelForm):
|
|
|
977
974
|
"manufacturer",
|
|
978
975
|
"model",
|
|
979
976
|
"part_number",
|
|
980
|
-
"comments",
|
|
981
977
|
]
|
|
982
978
|
|
|
983
979
|
|
|
@@ -985,7 +981,6 @@ class ModuleTypeBulkEditForm(TagsBulkEditFormMixin, NautobotBulkEditForm):
|
|
|
985
981
|
pk = forms.ModelMultipleChoiceField(queryset=ModuleType.objects.all(), widget=forms.MultipleHiddenInput())
|
|
986
982
|
manufacturer = DynamicModelChoiceField(queryset=Manufacturer.objects.all(), required=False)
|
|
987
983
|
part_number = forms.CharField(required=False)
|
|
988
|
-
comments = CommentField(label="Comments", required=False)
|
|
989
984
|
|
|
990
985
|
class Meta:
|
|
991
986
|
nullable_fields = []
|
|
@@ -138,7 +138,6 @@ class Migration(migrations.Migration):
|
|
|
138
138
|
),
|
|
139
139
|
("model", models.CharField(max_length=255)),
|
|
140
140
|
("part_number", models.CharField(blank=True, max_length=255)),
|
|
141
|
-
("comments", models.TextField(blank=True)),
|
|
142
141
|
],
|
|
143
142
|
options={
|
|
144
143
|
"ordering": ("manufacturer", "model"),
|
|
@@ -26,7 +26,6 @@ from nautobot.dcim.choices import (
|
|
|
26
26
|
PowerOutletFeedLegChoices,
|
|
27
27
|
PowerOutletTypeChoices,
|
|
28
28
|
PowerPortTypeChoices,
|
|
29
|
-
SubdeviceRoleChoices,
|
|
30
29
|
)
|
|
31
30
|
from nautobot.dcim.constants import (
|
|
32
31
|
NONCONNECTABLE_IFACE_TYPES,
|
|
@@ -1097,12 +1096,6 @@ class DeviceBay(ComponentModel):
|
|
|
1097
1096
|
"installed_device": f"Cannot install the specified device; device is already installed in {current_bay}"
|
|
1098
1097
|
}
|
|
1099
1098
|
)
|
|
1100
|
-
if self.installed_device.device_type.subdevice_role != SubdeviceRoleChoices.ROLE_CHILD:
|
|
1101
|
-
raise ValidationError(
|
|
1102
|
-
{
|
|
1103
|
-
"installed_device": f'Cannot install device "{self.installed_device}"; device-type "{self.installed_device.device_type}" subdevice_role is not "child".'
|
|
1104
|
-
}
|
|
1105
|
-
)
|
|
1106
1099
|
|
|
1107
1100
|
|
|
1108
1101
|
#
|
nautobot/dcim/models/devices.py
CHANGED
|
@@ -452,6 +452,7 @@ class Platform(OrganizationalModel):
|
|
|
452
452
|
@extras_features(
|
|
453
453
|
"custom_links",
|
|
454
454
|
"custom_validators",
|
|
455
|
+
"dynamic_groups",
|
|
455
456
|
"export_templates",
|
|
456
457
|
"graphql",
|
|
457
458
|
"locations",
|
|
@@ -1108,6 +1109,7 @@ class VirtualChassis(PrimaryModel):
|
|
|
1108
1109
|
@extras_features(
|
|
1109
1110
|
"custom_links",
|
|
1110
1111
|
"custom_validators",
|
|
1112
|
+
"dynamic_groups",
|
|
1111
1113
|
"export_templates",
|
|
1112
1114
|
"graphql",
|
|
1113
1115
|
"statuses",
|
|
@@ -1153,10 +1155,6 @@ class DeviceRedundancyGroup(PrimaryModel):
|
|
|
1153
1155
|
def devices_sorted(self):
|
|
1154
1156
|
return self.devices.order_by("device_redundancy_group_priority")
|
|
1155
1157
|
|
|
1156
|
-
@property
|
|
1157
|
-
def controllers_sorted(self):
|
|
1158
|
-
return self.controllers.order_by("name")
|
|
1159
|
-
|
|
1160
1158
|
def __str__(self):
|
|
1161
1159
|
return self.name
|
|
1162
1160
|
|
|
@@ -1339,6 +1337,7 @@ class SoftwareVersion(PrimaryModel):
|
|
|
1339
1337
|
@extras_features(
|
|
1340
1338
|
"custom_links",
|
|
1341
1339
|
"custom_validators",
|
|
1340
|
+
"dynamic_groups",
|
|
1342
1341
|
"export_templates",
|
|
1343
1342
|
"graphql",
|
|
1344
1343
|
"locations",
|
|
@@ -1422,6 +1421,7 @@ class Controller(PrimaryModel):
|
|
|
1422
1421
|
@extras_features(
|
|
1423
1422
|
"custom_links",
|
|
1424
1423
|
"custom_validators",
|
|
1424
|
+
"dynamic_groups",
|
|
1425
1425
|
"export_templates",
|
|
1426
1426
|
"graphql",
|
|
1427
1427
|
"webhooks",
|
|
@@ -1510,7 +1510,6 @@ class ModuleType(PrimaryModel):
|
|
|
1510
1510
|
part_number = models.CharField(
|
|
1511
1511
|
max_length=CHARFIELD_MAX_LENGTH, blank=True, help_text="Discrete part number (optional)"
|
|
1512
1512
|
)
|
|
1513
|
-
comments = models.TextField(blank=True)
|
|
1514
1513
|
|
|
1515
1514
|
clone_fields = [
|
|
1516
1515
|
"manufacturer",
|
|
@@ -1531,7 +1530,6 @@ class ModuleType(PrimaryModel):
|
|
|
1531
1530
|
("manufacturer", self.manufacturer.name),
|
|
1532
1531
|
("model", self.model),
|
|
1533
1532
|
("part_number", self.part_number),
|
|
1534
|
-
("comments", self.comments),
|
|
1535
1533
|
)
|
|
1536
1534
|
)
|
|
1537
1535
|
|
nautobot/dcim/models/racks.py
CHANGED
nautobot/dcim/tables/devices.py
CHANGED
|
@@ -261,7 +261,7 @@ class ModuleTable(StatusTableMixin, RoleTableMixin, BaseTable):
|
|
|
261
261
|
)
|
|
262
262
|
location = tables.Column(linkify=True)
|
|
263
263
|
tenant = TenantColumn()
|
|
264
|
-
tags = TagColumn(url_name="dcim:
|
|
264
|
+
tags = TagColumn(url_name="dcim:device_list")
|
|
265
265
|
actions = ButtonsColumn(Module, prepend_template=MODULE_BUTTONS)
|
|
266
266
|
|
|
267
267
|
class Meta(BaseTable.Meta):
|
|
@@ -1125,27 +1125,13 @@ class DeviceRedundancyGroupTable(BaseTable):
|
|
|
1125
1125
|
url_params={"device_redundancy_group": "pk"},
|
|
1126
1126
|
verbose_name="Devices",
|
|
1127
1127
|
)
|
|
1128
|
-
controller_count = LinkedCountColumn(
|
|
1129
|
-
viewname="dcim:controller_list",
|
|
1130
|
-
url_params={"controller_device_redundancy_group": "pk"},
|
|
1131
|
-
verbose_name="Controllers",
|
|
1132
|
-
)
|
|
1133
1128
|
secrets_group = tables.Column(linkify=True)
|
|
1134
1129
|
tags = TagColumn(url_name="dcim:deviceredundancygroup_list")
|
|
1135
1130
|
|
|
1136
1131
|
class Meta(BaseTable.Meta):
|
|
1137
1132
|
model = DeviceRedundancyGroup
|
|
1138
|
-
fields = (
|
|
1139
|
-
|
|
1140
|
-
"name",
|
|
1141
|
-
"status",
|
|
1142
|
-
"failover_strategy",
|
|
1143
|
-
"controller_count",
|
|
1144
|
-
"device_count",
|
|
1145
|
-
"secrets_group",
|
|
1146
|
-
"tags",
|
|
1147
|
-
)
|
|
1148
|
-
default_columns = ("pk", "name", "status", "failover_strategy", "controller_count", "device_count")
|
|
1133
|
+
fields = ("pk", "name", "status", "failover_strategy", "device_count", "secrets_group", "tags")
|
|
1134
|
+
default_columns = ("pk", "name", "status", "failover_strategy", "device_count")
|
|
1149
1135
|
|
|
1150
1136
|
|
|
1151
1137
|
#
|
|
@@ -160,7 +160,7 @@ class ModuleTypeTable(BaseTable):
|
|
|
160
160
|
url_params={"module_type": "pk"},
|
|
161
161
|
verbose_name="Modules",
|
|
162
162
|
)
|
|
163
|
-
tags = TagColumn(url_name="dcim:
|
|
163
|
+
tags = TagColumn(url_name="dcim:devicetype_list")
|
|
164
164
|
|
|
165
165
|
class Meta(BaseTable.Meta):
|
|
166
166
|
model = ModuleType
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<a href="{% url 'dcim:device_modulebays' pk=object.pk %}">Modules {% badge module_count %}</a>
|
|
72
72
|
</li>
|
|
73
73
|
{% endif %}
|
|
74
|
-
{% with interface_count=object.
|
|
74
|
+
{% with interface_count=object.all_interfaces.count %}
|
|
75
75
|
{% if interface_count %}
|
|
76
76
|
<li role="presentation" {% if active_tab == 'interfaces' %} class="active"{% endif %}>
|
|
77
77
|
<a href="{% url 'dcim:device_interfaces' pk=object.pk %}">Interfaces {% badge interface_count %}</a>
|
|
@@ -427,7 +427,7 @@
|
|
|
427
427
|
</div>
|
|
428
428
|
{% endif %}
|
|
429
429
|
{% if object.is_metadata_associable_model and perms.extras.view_objectmetadata %}
|
|
430
|
-
<div id="
|
|
430
|
+
<div id="object_metadatas" role="tabpanel" class="tab-pane {% if request.GET.tab == 'object_metadatas' %}active{% else %}fade{% endif %}">
|
|
431
431
|
<div class="row">
|
|
432
432
|
<div class="col-md-12">
|
|
433
433
|
<form method="post">
|
|
@@ -440,7 +440,7 @@
|
|
|
440
440
|
</div>
|
|
441
441
|
</div>
|
|
442
442
|
<div class="table-responsive">
|
|
443
|
-
{% render_table
|
|
443
|
+
{% render_table associated_object_metadatas_table 'inc/table.html' %}
|
|
444
444
|
</div>
|
|
445
445
|
</div>
|
|
446
446
|
</form>
|
|
@@ -45,12 +45,6 @@
|
|
|
45
45
|
{% endblock content_right_page %}
|
|
46
46
|
|
|
47
47
|
{% block content_full_width_page %}
|
|
48
|
-
<div class="panel panel-default">
|
|
49
|
-
<div class="panel-heading">
|
|
50
|
-
<strong>Controllers</strong>
|
|
51
|
-
</div>
|
|
52
|
-
{% include 'responsive_table.html' with table=controllers_table %}
|
|
53
|
-
</div>
|
|
54
48
|
<div class="panel panel-default">
|
|
55
49
|
<div class="panel-heading">
|
|
56
50
|
<strong>Devices</strong>
|
|
@@ -113,23 +113,6 @@
|
|
|
113
113
|
</div>
|
|
114
114
|
{% endblock content_left_page %}
|
|
115
115
|
|
|
116
|
-
{% block content_right_page %}
|
|
117
|
-
<div class="panel panel-default">
|
|
118
|
-
<div class="panel-heading">
|
|
119
|
-
<strong>Comments</strong>
|
|
120
|
-
</div>
|
|
121
|
-
<div class="panel-body rendered-markdown">
|
|
122
|
-
{% if object.comments %}
|
|
123
|
-
{{ object.comments|render_markdown }}
|
|
124
|
-
{% else %}
|
|
125
|
-
<span class="text-muted">None</span>
|
|
126
|
-
{% endif %}
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
{% endblock content_right_page %}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
116
|
{% block extra_tab_content %}
|
|
134
117
|
<div role="tabpanel" class="tab-pane {% if request.GET.tab == 'interfaces' %}active{% else %}fade{% endif %}" id="interfaces">
|
|
135
118
|
{% include 'dcim/inc/moduletype_component_table.html' with table=interface_table title='Interfaces' tab='interfaces' %}
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
</div>
|
|
237
237
|
{% endif %}
|
|
238
238
|
{% if object.is_metadata_associable_model and perms.extras.view_objectmetadata %}
|
|
239
|
-
<div id="
|
|
239
|
+
<div id="object_metadatas" role="tabpanel" class="tab-pane {% if request.GET.tab == 'object_metadatas' %}active{% else %}fade{% endif %}">
|
|
240
240
|
<div class="row">
|
|
241
241
|
<div class="col-md-12">
|
|
242
242
|
<form method="post">
|
|
@@ -249,7 +249,7 @@
|
|
|
249
249
|
</div>
|
|
250
250
|
</div>
|
|
251
251
|
<div class="table-responsive">
|
|
252
|
-
{% render_table
|
|
252
|
+
{% render_table associated_object_metadatas_table 'inc/table.html' %}
|
|
253
253
|
</div>
|
|
254
254
|
</div>
|
|
255
255
|
</form>
|
nautobot/dcim/tests/test_api.py
CHANGED
|
@@ -1022,7 +1022,6 @@ class ModuleTypeTest(APIViewTestCases.APIViewTestCase):
|
|
|
1022
1022
|
model = ModuleType
|
|
1023
1023
|
bulk_update_data = {
|
|
1024
1024
|
"part_number": "ABC123",
|
|
1025
|
-
"comments": "changed comment",
|
|
1026
1025
|
}
|
|
1027
1026
|
|
|
1028
1027
|
@classmethod
|
|
@@ -1034,7 +1033,6 @@ class ModuleTypeTest(APIViewTestCases.APIViewTestCase):
|
|
|
1034
1033
|
"manufacturer": manufacturer_id,
|
|
1035
1034
|
"model": "Module Type 1",
|
|
1036
1035
|
"part_number": "123456",
|
|
1037
|
-
"comments": "test comment",
|
|
1038
1036
|
},
|
|
1039
1037
|
{
|
|
1040
1038
|
"manufacturer": manufacturer_id,
|
|
@@ -656,15 +656,9 @@ def common_test_data(cls):
|
|
|
656
656
|
device_redundancy_groups = iter(DeviceRedundancyGroup.objects.all())
|
|
657
657
|
|
|
658
658
|
module_types = (
|
|
659
|
-
ModuleType.objects.create(
|
|
660
|
-
|
|
661
|
-
),
|
|
662
|
-
ModuleType.objects.create(
|
|
663
|
-
manufacturer=cls.manufacturers[1], model="Filter Test Module Type 2", comments="Module Type 2"
|
|
664
|
-
),
|
|
665
|
-
ModuleType.objects.create(
|
|
666
|
-
manufacturer=cls.manufacturers[2], model="Filter Test Module Type 3", comments="Module Type 3"
|
|
667
|
-
),
|
|
659
|
+
ModuleType.objects.create(manufacturer=cls.manufacturers[0], model="Filter Test Module Type 1"),
|
|
660
|
+
ModuleType.objects.create(manufacturer=cls.manufacturers[1], model="Filter Test Module Type 2"),
|
|
661
|
+
ModuleType.objects.create(manufacturer=cls.manufacturers[2], model="Filter Test Module Type 3"),
|
|
668
662
|
)
|
|
669
663
|
|
|
670
664
|
# Create 3 of each component template on the first two module types
|
|
@@ -904,7 +898,7 @@ class ModularDeviceComponentTestMixin(DeviceComponentTestMixin):
|
|
|
904
898
|
)
|
|
905
899
|
parent_module_bay = ModuleBay.objects.create(name="Parent module bay", position="1", parent_device=device)
|
|
906
900
|
module_type = ModuleType.objects.create(
|
|
907
|
-
manufacturer=manufacturer, model=f"Test Device Filter for {model} Module Type"
|
|
901
|
+
manufacturer=manufacturer, model=f"Test Device Filter for {model} Module Type"
|
|
908
902
|
)
|
|
909
903
|
module = Module.objects.create(
|
|
910
904
|
module_type=module_type, parent_module_bay=parent_module_bay, status=self.module_statuses[0]
|
|
@@ -2532,7 +2526,7 @@ class InterfaceTestCase(PathEndpointModelTestMixin, ModularDeviceComponentTestMi
|
|
|
2532
2526
|
name="Parent module bay", position="1", parent_device=device_vc_master
|
|
2533
2527
|
)
|
|
2534
2528
|
module_type = ModuleType.objects.create(
|
|
2535
|
-
manufacturer=manufacturer, model="Test Device Filter for Interface Module Type"
|
|
2529
|
+
manufacturer=manufacturer, model="Test Device Filter for Interface Module Type"
|
|
2536
2530
|
)
|
|
2537
2531
|
module = Module.objects.create(
|
|
2538
2532
|
module_type=module_type, parent_module_bay=parent_module_bay, status=self.module_statuses[0]
|
|
@@ -2778,7 +2772,7 @@ class FrontPortTestCase(ModularDeviceComponentTestMixin, FilterTestCases.FilterT
|
|
|
2778
2772
|
)
|
|
2779
2773
|
parent_module_bay = ModuleBay.objects.create(name="Parent module bay", position="1", parent_device=device)
|
|
2780
2774
|
module_type = ModuleType.objects.create(
|
|
2781
|
-
manufacturer=manufacturer, model="Test Device Filter for FrontPort Module Type"
|
|
2775
|
+
manufacturer=manufacturer, model="Test Device Filter for FrontPort Module Type"
|
|
2782
2776
|
)
|
|
2783
2777
|
module = Module.objects.create(
|
|
2784
2778
|
module_type=module_type, parent_module_bay=parent_module_bay, status=self.module_statuses[0]
|
|
@@ -3363,7 +3357,7 @@ class CableTestCase(FilterTestCases.FilterTestCase):
|
|
|
3363
3357
|
)
|
|
3364
3358
|
parent_module_bay = ModuleBay.objects.create(name="Parent module bay", position="1", parent_device=device)
|
|
3365
3359
|
module_type = ModuleType.objects.create(
|
|
3366
|
-
manufacturer=manufacturer, model="Test Device Filter for Cable Module Type"
|
|
3360
|
+
manufacturer=manufacturer, model="Test Device Filter for Cable Module Type"
|
|
3367
3361
|
)
|
|
3368
3362
|
module = Module.objects.create(
|
|
3369
3363
|
module_type=module_type, parent_module_bay=parent_module_bay, status=self.module_statuses[0]
|
|
@@ -4018,7 +4012,6 @@ class ModuleTypeTestCase(FilterTestCases.FilterTestCase):
|
|
|
4018
4012
|
queryset = ModuleType.objects.all()
|
|
4019
4013
|
filterset = ModuleTypeFilterSet
|
|
4020
4014
|
generic_filter_tests = [
|
|
4021
|
-
("comments",),
|
|
4022
4015
|
("manufacturer", "manufacturer__id"),
|
|
4023
4016
|
("manufacturer", "manufacturer__name"),
|
|
4024
4017
|
("model",),
|
|
@@ -1903,37 +1903,6 @@ class DeviceTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
1903
1903
|
self.assertNotEqual(child_mtime_after_parent_rack_update_save, child_mtime_after_parent_site_update_save)
|
|
1904
1904
|
|
|
1905
1905
|
|
|
1906
|
-
class DeviceBayTestCase(ModelTestCases.BaseModelTestCase):
|
|
1907
|
-
model = DeviceBay
|
|
1908
|
-
|
|
1909
|
-
def setUp(self):
|
|
1910
|
-
self.devices = Device.objects.filter(device_type__subdevice_role=SubdeviceRoleChoices.ROLE_PARENT)
|
|
1911
|
-
devicetype = DeviceType.objects.create(
|
|
1912
|
-
manufacturer=self.devices[0].device_type.manufacturer,
|
|
1913
|
-
model="TestDeviceType1",
|
|
1914
|
-
u_height=0,
|
|
1915
|
-
subdevice_role=SubdeviceRoleChoices.ROLE_CHILD,
|
|
1916
|
-
)
|
|
1917
|
-
child_device = Device.objects.create(
|
|
1918
|
-
device_type=devicetype,
|
|
1919
|
-
role=self.devices[0].role,
|
|
1920
|
-
name="TestDevice1",
|
|
1921
|
-
status=self.devices[0].status,
|
|
1922
|
-
location=self.devices[0].location,
|
|
1923
|
-
)
|
|
1924
|
-
DeviceBay.objects.create(device=self.devices[0], name="Device Bay 1", installed_device=child_device)
|
|
1925
|
-
|
|
1926
|
-
def test_assigning_installed_device(self):
|
|
1927
|
-
server = Device.objects.exclude(device_type__subdevice_role=SubdeviceRoleChoices.ROLE_CHILD).last()
|
|
1928
|
-
bay = DeviceBay(device=self.devices[1], name="Device Bay Err", installed_device=server)
|
|
1929
|
-
with self.assertRaises(ValidationError) as err:
|
|
1930
|
-
bay.validated_save()
|
|
1931
|
-
self.assertIn(
|
|
1932
|
-
f'Cannot install device "{server}"; device-type "{server.device_type}" subdevice_role is not "child".',
|
|
1933
|
-
str(err.exception),
|
|
1934
|
-
)
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
1906
|
class DeviceTypeToSoftwareImageFileTestCase(ModelTestCases.BaseModelTestCase):
|
|
1938
1907
|
model = DeviceTypeToSoftwareImageFile
|
|
1939
1908
|
|
|
@@ -817,7 +817,6 @@ class DeviceTypeTestCase(
|
|
|
817
817
|
cls.bulk_edit_data = {
|
|
818
818
|
"u_height": 0,
|
|
819
819
|
"is_full_depth": False,
|
|
820
|
-
"comments": "changed comment",
|
|
821
820
|
}
|
|
822
821
|
|
|
823
822
|
def test_list_has_correct_links(self):
|
|
@@ -1197,7 +1196,6 @@ class ModuleTypeTestCase(
|
|
|
1197
1196
|
ModuleType.objects.create(
|
|
1198
1197
|
model="Test Module Type 1",
|
|
1199
1198
|
manufacturer=manufacturers[0],
|
|
1200
|
-
comments="test comment",
|
|
1201
1199
|
)
|
|
1202
1200
|
ModuleType.objects.create(
|
|
1203
1201
|
model="Test Module Type 2",
|
|
@@ -1217,12 +1215,10 @@ class ModuleTypeTestCase(
|
|
|
1217
1215
|
"model": "Test Module Type X",
|
|
1218
1216
|
"part_number": "123ABC",
|
|
1219
1217
|
"tags": [t.pk for t in Tag.objects.get_for_model(ModuleType)],
|
|
1220
|
-
"comments": "test comment",
|
|
1221
1218
|
}
|
|
1222
1219
|
|
|
1223
1220
|
cls.bulk_edit_data = {
|
|
1224
1221
|
"manufacturer": manufacturers[1].pk,
|
|
1225
|
-
"comments": "changed comment",
|
|
1226
1222
|
}
|
|
1227
1223
|
|
|
1228
1224
|
def test_list_has_correct_links(self):
|
|
@@ -2363,19 +2359,6 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2363
2359
|
sorted(interface_ips),
|
|
2364
2360
|
)
|
|
2365
2361
|
|
|
2366
|
-
with self.subTest("Assert Assigning IPAddress Without Selecting Any IPAddress Raises Exception"):
|
|
2367
|
-
assign_ip_form_data["pk"] = []
|
|
2368
|
-
assign_ip_request = {
|
|
2369
|
-
"path": reverse("ipam:ipaddress_assign")
|
|
2370
|
-
+ f"?interface={self.interfaces[1].id}&return_url={device_list_url}",
|
|
2371
|
-
"data": post_data(assign_ip_form_data),
|
|
2372
|
-
}
|
|
2373
|
-
response = self.client.post(**assign_ip_request, follow=True)
|
|
2374
|
-
self.assertHttpStatus(response, 200)
|
|
2375
|
-
self.assertIn(
|
|
2376
|
-
"Please select at least one IP Address from the table.", response.content.decode(response.charset)
|
|
2377
|
-
)
|
|
2378
|
-
|
|
2379
2362
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2380
2363
|
def test_device_rearports(self):
|
|
2381
2364
|
device = Device.objects.first()
|
|
@@ -4189,28 +4172,6 @@ class VirtualChassisTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
4189
4172
|
"domain": "domain-x",
|
|
4190
4173
|
}
|
|
4191
4174
|
|
|
4192
|
-
def test_device_interfaces_count_correct(self):
|
|
4193
|
-
"""
|
|
4194
|
-
This checks whether the other memebers' interfaces are included in the
|
|
4195
|
-
interfaces tab of the master device and whether the interface count on the tab header is
|
|
4196
|
-
rendered correctly.
|
|
4197
|
-
"""
|
|
4198
|
-
self.user.is_superuser = True
|
|
4199
|
-
self.user.save()
|
|
4200
|
-
interface_status = Status.objects.get_for_model(Interface).first()
|
|
4201
|
-
Interface.objects.create(device=self.devices[0], name="eth0", status=interface_status)
|
|
4202
|
-
Interface.objects.create(device=self.devices[0], name="eth1", status=interface_status)
|
|
4203
|
-
Interface.objects.create(device=self.devices[1], name="device 1 interface 1", status=interface_status)
|
|
4204
|
-
Interface.objects.create(device=self.devices[1], name="device 1 interface 2", status=interface_status)
|
|
4205
|
-
Interface.objects.create(device=self.devices[2], name="device 2 interface 1", status=interface_status)
|
|
4206
|
-
Interface.objects.create(device=self.devices[2], name="device 2 interface 2", status=interface_status)
|
|
4207
|
-
response = self.client.get(reverse("dcim:device_interfaces", kwargs={"pk": self.devices[0].pk}))
|
|
4208
|
-
self.assertIn('Interfaces <span class="badge">6</span>', str(response.content))
|
|
4209
|
-
self.assertIn("device 1 interface 1", str(response.content))
|
|
4210
|
-
self.assertIn("device 1 interface 2", str(response.content))
|
|
4211
|
-
self.assertIn("device 2 interface 1", str(response.content))
|
|
4212
|
-
self.assertIn("device 2 interface 2", str(response.content))
|
|
4213
|
-
|
|
4214
4175
|
def test_device_column_visible(self):
|
|
4215
4176
|
"""
|
|
4216
4177
|
This checks whether the device column on a device's interfaces
|
nautobot/dcim/views.py
CHANGED
|
@@ -1923,7 +1923,7 @@ class DeviceInterfacesView(DeviceComponentTabView):
|
|
|
1923
1923
|
|
|
1924
1924
|
def get_extra_context(self, request, instance):
|
|
1925
1925
|
interfaces = (
|
|
1926
|
-
instance.
|
|
1926
|
+
instance.all_interfaces.restrict(request.user, "view")
|
|
1927
1927
|
.prefetch_related(
|
|
1928
1928
|
Prefetch("ip_addresses", queryset=IPAddress.objects.restrict(request.user)),
|
|
1929
1929
|
Prefetch("member_interfaces", queryset=Interface.objects.restrict(request.user)),
|
|
@@ -4049,9 +4049,6 @@ class DeviceRedundancyGroupUIViewSet(NautobotUIViewSet):
|
|
|
4049
4049
|
devices_table = tables.DeviceTable(devices)
|
|
4050
4050
|
devices_table.columns.show("device_redundancy_group_priority")
|
|
4051
4051
|
context["devices_table"] = devices_table
|
|
4052
|
-
controllers = instance.controllers_sorted.restrict(request.user)
|
|
4053
|
-
controllers_table = tables.ControllerTable(controllers)
|
|
4054
|
-
context["controllers_table"] = controllers_table
|
|
4055
4052
|
return context
|
|
4056
4053
|
|
|
4057
4054
|
|
nautobot/extras/api/views.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from datetime import timedelta
|
|
2
|
+
|
|
1
3
|
from django.conf import settings
|
|
2
4
|
from django.contrib.contenttypes.models import ContentType
|
|
3
5
|
from django.forms import ValidationError as FormsValidationError
|
|
@@ -490,6 +492,59 @@ class ImageAttachmentViewSet(ModelViewSet):
|
|
|
490
492
|
#
|
|
491
493
|
|
|
492
494
|
|
|
495
|
+
def _create_schedule(serializer, data, job_model, user, approval_required, task_queue=None):
|
|
496
|
+
"""
|
|
497
|
+
This is an internal function to create a scheduled job from API data.
|
|
498
|
+
It has to handle both once-offs (i.e. of type TYPE_FUTURE) and interval
|
|
499
|
+
jobs.
|
|
500
|
+
"""
|
|
501
|
+
type_ = serializer["interval"]
|
|
502
|
+
if type_ == JobExecutionType.TYPE_IMMEDIATELY:
|
|
503
|
+
time = timezone.now()
|
|
504
|
+
name = serializer.get("name") or f"{job_model.name} - {time}"
|
|
505
|
+
elif type_ == JobExecutionType.TYPE_CUSTOM:
|
|
506
|
+
time = serializer.get("start_time") # doing .get("key", "default") returns None instead of "default"
|
|
507
|
+
if time is None:
|
|
508
|
+
# "start_time" is checked against models.ScheduledJob.earliest_possible_time()
|
|
509
|
+
# which returns timezone.now() + timedelta(seconds=15)
|
|
510
|
+
time = timezone.now() + timedelta(seconds=20)
|
|
511
|
+
name = serializer["name"]
|
|
512
|
+
else:
|
|
513
|
+
time = serializer["start_time"]
|
|
514
|
+
name = serializer["name"]
|
|
515
|
+
crontab = serializer.get("crontab", "")
|
|
516
|
+
|
|
517
|
+
celery_kwargs = {
|
|
518
|
+
"nautobot_job_profile": False,
|
|
519
|
+
"queue": task_queue,
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
# 2.0 TODO: To revisit this as part of a larger Jobs cleanup in 2.0.
|
|
523
|
+
#
|
|
524
|
+
# We pass in task and job_model here partly for forward/backward compatibility logic, and
|
|
525
|
+
# part fallback safety. It's mildly useful to store both the task module/class name and the JobModel
|
|
526
|
+
# FK on the ScheduledJob, as in the case where the JobModel gets deleted (and the FK becomes
|
|
527
|
+
# null) you still have a bit of context on the ScheduledJob as to what it was originally
|
|
528
|
+
# scheduled for.
|
|
529
|
+
scheduled_job = ScheduledJob(
|
|
530
|
+
name=name,
|
|
531
|
+
task=job_model.class_path,
|
|
532
|
+
job_model=job_model,
|
|
533
|
+
start_time=time,
|
|
534
|
+
description=f"Nautobot job {name} scheduled by {user} for {time}",
|
|
535
|
+
kwargs=data,
|
|
536
|
+
celery_kwargs=celery_kwargs,
|
|
537
|
+
interval=type_,
|
|
538
|
+
one_off=(type_ == JobExecutionType.TYPE_FUTURE),
|
|
539
|
+
user=user,
|
|
540
|
+
approval_required=approval_required,
|
|
541
|
+
crontab=crontab,
|
|
542
|
+
queue=task_queue,
|
|
543
|
+
)
|
|
544
|
+
scheduled_job.validated_save()
|
|
545
|
+
return scheduled_job
|
|
546
|
+
|
|
547
|
+
|
|
493
548
|
class JobViewSetBase(
|
|
494
549
|
NautobotAPIVersionMixin,
|
|
495
550
|
# note no CreateModelMixin
|
|
@@ -689,16 +744,13 @@ class JobViewSetBase(
|
|
|
689
744
|
|
|
690
745
|
# Try to create a ScheduledJob, or...
|
|
691
746
|
if schedule_data:
|
|
692
|
-
schedule =
|
|
747
|
+
schedule = _create_schedule(
|
|
748
|
+
schedule_data,
|
|
749
|
+
job_class.serialize_data(cleaned_data),
|
|
693
750
|
job_model,
|
|
694
751
|
request.user,
|
|
695
|
-
|
|
696
|
-
start_time=schedule_data.get("start_time"),
|
|
697
|
-
interval=schedule_data.get("interval"),
|
|
698
|
-
crontab=schedule_data.get("crontab", ""),
|
|
699
|
-
approval_required=approval_required,
|
|
752
|
+
approval_required,
|
|
700
753
|
task_queue=input_serializer.validated_data.get("task_queue", None),
|
|
701
|
-
**job_class.serialize_data(cleaned_data),
|
|
702
754
|
)
|
|
703
755
|
else:
|
|
704
756
|
schedule = None
|