nautobot 2.4.9__py3-none-any.whl → 2.4.11__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/tests/test_views.py +13 -1
- nautobot/cloud/views.py +39 -9
- nautobot/core/api/parsers.py +56 -2
- nautobot/core/celery/__init__.py +21 -0
- nautobot/core/celery/encoders.py +3 -0
- nautobot/core/forms/forms.py +4 -1
- nautobot/core/jobs/bulk_actions.py +8 -8
- nautobot/core/jobs/cleanup.py +11 -0
- nautobot/core/management/commands/generate_test_data.py +2 -1
- nautobot/core/models/__init__.py +2 -0
- nautobot/core/templates/generic/object_retrieve.html +1 -1
- nautobot/core/testing/mixins.py +19 -1
- nautobot/core/testing/views.py +104 -8
- nautobot/core/tests/test_csv.py +92 -1
- nautobot/core/tests/test_jinja_filters.py +59 -0
- nautobot/core/tests/test_jobs.py +20 -4
- nautobot/core/tests/test_utils.py +193 -0
- nautobot/core/tests/test_views.py +73 -0
- nautobot/core/tests/test_views_utils.py +53 -2
- nautobot/core/ui/object_detail.py +4 -0
- nautobot/core/urls.py +2 -2
- nautobot/core/utils/lookup.py +4 -2
- nautobot/core/utils/module_loading.py +86 -58
- nautobot/core/views/__init__.py +21 -0
- nautobot/core/views/generic.py +2 -12
- nautobot/core/views/mixins.py +19 -1
- nautobot/core/views/renderers.py +4 -13
- nautobot/core/views/utils.py +16 -0
- nautobot/dcim/api/serializers.py +13 -0
- nautobot/dcim/api/urls.py +1 -0
- nautobot/dcim/api/views.py +20 -0
- nautobot/dcim/apps.py +1 -0
- nautobot/dcim/factory.py +11 -0
- nautobot/dcim/filters/__init__.py +110 -0
- nautobot/dcim/forms.py +205 -19
- nautobot/dcim/migrations/0070_modulefamily_models.py +92 -0
- nautobot/dcim/models/__init__.py +2 -0
- nautobot/dcim/models/device_component_templates.py +18 -0
- nautobot/dcim/models/device_components.py +25 -1
- nautobot/dcim/models/devices.py +68 -0
- nautobot/dcim/navigation.py +16 -0
- nautobot/dcim/tables/__init__.py +2 -0
- nautobot/dcim/tables/devices.py +48 -0
- nautobot/dcim/tables/devicetypes.py +35 -1
- nautobot/dcim/tables/template_code.py +2 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +1 -90
- nautobot/dcim/templates/dcim/inc/cable_toggle_buttons.html +1 -1
- nautobot/dcim/templates/dcim/interfaceredundancygroup_retrieve.html +1 -63
- nautobot/dcim/templates/dcim/location.html +2 -249
- nautobot/dcim/templates/dcim/location_edit.html +2 -38
- nautobot/dcim/templates/dcim/location_retrieve.html +249 -0
- nautobot/dcim/templates/dcim/location_update.html +38 -0
- nautobot/dcim/templates/dcim/module_update.html +1 -0
- nautobot/dcim/templates/dcim/modulebay_retrieve.html +93 -1
- nautobot/dcim/templates/dcim/modulefamily_retrieve.html +31 -0
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +6 -0
- nautobot/dcim/templates/dcim/powerfeed_retrieve.html +1 -160
- nautobot/dcim/tests/test_api.py +35 -0
- nautobot/dcim/tests/test_filters.py +102 -3
- nautobot/dcim/tests/test_models.py +146 -0
- nautobot/dcim/tests/test_views.py +70 -97
- nautobot/dcim/urls.py +4 -22
- nautobot/dcim/views.py +439 -153
- nautobot/extras/api/views.py +9 -2
- nautobot/extras/context_managers.py +2 -2
- nautobot/extras/datasources/git.py +11 -3
- nautobot/extras/forms/forms.py +9 -5
- nautobot/extras/jobs.py +4 -2
- nautobot/extras/models/customfields.py +2 -0
- nautobot/extras/models/datasources.py +13 -8
- nautobot/extras/models/groups.py +18 -0
- nautobot/extras/models/jobs.py +19 -0
- nautobot/extras/models/metadata.py +2 -0
- nautobot/extras/models/models.py +4 -0
- nautobot/extras/models/secrets.py +7 -0
- nautobot/extras/plugins/__init__.py +3 -0
- nautobot/extras/secrets/__init__.py +14 -0
- nautobot/extras/tables.py +40 -3
- nautobot/extras/templates/extras/configcontext.html +2 -220
- nautobot/extras/templates/extras/configcontext_edit.html +2 -50
- nautobot/extras/templates/extras/configcontext_retrieve.html +2 -0
- nautobot/extras/templates/extras/configcontext_update.html +50 -0
- nautobot/extras/templates/extras/configcontextschema.html +2 -48
- nautobot/extras/templates/extras/configcontextschema_edit.html +2 -19
- nautobot/extras/templates/extras/configcontextschema_retrieve.html +48 -0
- nautobot/extras/templates/extras/configcontextschema_update.html +19 -0
- nautobot/extras/templates/extras/inc/configcontext_data.html +1 -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_edit.html +12 -6
- nautobot/extras/templates/extras/tag.html +2 -52
- nautobot/extras/templates/extras/tag_edit.html +2 -15
- nautobot/extras/templates/extras/tag_retrieve.html +52 -0
- nautobot/extras/templates/extras/tag_update.html +15 -0
- nautobot/extras/templates/extras/team_retrieve.html +2 -2
- nautobot/extras/tests/test_api.py +15 -15
- nautobot/extras/tests/test_context_managers.py +20 -0
- nautobot/extras/tests/test_filters.py +4 -4
- nautobot/extras/tests/test_jobs.py +23 -10
- nautobot/extras/tests/test_models.py +45 -8
- nautobot/extras/tests/test_plugins.py +6 -3
- nautobot/extras/tests/test_views.py +66 -11
- nautobot/extras/urls.py +4 -134
- nautobot/extras/views.py +113 -158
- nautobot/ipam/models.py +51 -4
- nautobot/ipam/tables.py +19 -0
- nautobot/ipam/templates/ipam/vlan.html +2 -84
- nautobot/ipam/templates/ipam/vlan_edit.html +2 -24
- nautobot/ipam/templates/ipam/vlan_retrieve.html +84 -0
- nautobot/ipam/templates/ipam/vlan_update.html +24 -0
- nautobot/ipam/tests/test_views.py +5 -0
- nautobot/ipam/urls.py +1 -21
- nautobot/ipam/views.py +45 -70
- nautobot/project-static/docs/404.html +31 -8
- nautobot/project-static/docs/apps/index.html +31 -8
- nautobot/project-static/docs/apps/nautobot-apps.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +120 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +31 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +31 -8
- nautobot/project-static/docs/development/apps/api/configuration-view.html +31 -8
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +31 -8
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +31 -8
- nautobot/project-static/docs/development/apps/api/models/global-search.html +31 -8
- nautobot/project-static/docs/development/apps/api/models/graphql.html +31 -8
- nautobot/project-static/docs/development/apps/api/models/index.html +31 -8
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +40 -8
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +70 -46
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +31 -8
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +31 -8
- nautobot/project-static/docs/development/apps/api/prometheus.html +31 -8
- nautobot/project-static/docs/development/apps/api/setup.html +31 -8
- nautobot/project-static/docs/development/apps/api/testing.html +31 -8
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +31 -8
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +31 -8
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +31 -8
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +31 -8
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/base-template.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/index.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/notes.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +31 -8
- nautobot/project-static/docs/development/apps/api/views/urls.html +31 -8
- nautobot/project-static/docs/development/apps/index.html +31 -8
- nautobot/project-static/docs/development/apps/migration/code-updates.html +31 -8
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +31 -8
- nautobot/project-static/docs/development/apps/migration/from-v1.html +31 -8
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +31 -8
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +31 -8
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +31 -8
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +31 -8
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +31 -8
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +31 -8
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +31 -8
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +31 -8
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +31 -8
- nautobot/project-static/docs/development/core/application-registry.html +31 -8
- nautobot/project-static/docs/development/core/best-practices.html +31 -8
- nautobot/project-static/docs/development/core/bootstrap-ui.html +31 -8
- nautobot/project-static/docs/development/core/caching.html +31 -8
- nautobot/project-static/docs/development/core/controllers.html +31 -8
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +31 -8
- nautobot/project-static/docs/development/core/generic-views.html +31 -8
- nautobot/project-static/docs/development/core/getting-started.html +31 -8
- nautobot/project-static/docs/development/core/homepage.html +31 -8
- nautobot/project-static/docs/development/core/index.html +31 -8
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +31 -8
- nautobot/project-static/docs/development/core/model-checklist.html +31 -8
- nautobot/project-static/docs/development/core/model-features.html +31 -8
- nautobot/project-static/docs/development/core/natural-keys.html +31 -8
- nautobot/project-static/docs/development/core/navigation-menu.html +31 -8
- nautobot/project-static/docs/development/core/release-checklist.html +31 -8
- nautobot/project-static/docs/development/core/role-internals.html +31 -8
- nautobot/project-static/docs/development/core/settings.html +31 -8
- nautobot/project-static/docs/development/core/style-guide.html +31 -8
- nautobot/project-static/docs/development/core/templates.html +31 -8
- nautobot/project-static/docs/development/core/testing.html +31 -8
- nautobot/project-static/docs/development/core/ui-component-framework.html +31 -8
- nautobot/project-static/docs/development/core/user-preferences.html +31 -8
- nautobot/project-static/docs/development/index.html +31 -8
- nautobot/project-static/docs/development/jobs/getting-started.html +35 -8
- nautobot/project-static/docs/development/jobs/index.html +31 -8
- nautobot/project-static/docs/development/jobs/installation.html +31 -8
- nautobot/project-static/docs/development/jobs/job-extensions.html +31 -8
- nautobot/project-static/docs/development/jobs/job-logging.html +31 -8
- nautobot/project-static/docs/development/jobs/job-patterns.html +31 -8
- nautobot/project-static/docs/development/jobs/job-structure.html +31 -8
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +31 -8
- nautobot/project-static/docs/development/jobs/testing.html +31 -8
- nautobot/project-static/docs/index.html +31 -8
- nautobot/project-static/docs/insert-analytics.sh +36 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +31 -8
- nautobot/project-static/docs/overview/design_philosophy.html +31 -8
- nautobot/project-static/docs/release-notes/index.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.0.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.1.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.2.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.3.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.4.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.5.html +31 -8
- nautobot/project-static/docs/release-notes/version-1.6.html +328 -8
- nautobot/project-static/docs/release-notes/version-2.0.html +31 -8
- nautobot/project-static/docs/release-notes/version-2.1.html +31 -8
- nautobot/project-static/docs/release-notes/version-2.2.html +31 -8
- nautobot/project-static/docs/release-notes/version-2.3.html +31 -8
- nautobot/project-static/docs/release-notes/version-2.4.html +353 -8
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +302 -298
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +31 -8
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +31 -8
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/index.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +31 -8
- nautobot/project-static/docs/user-guide/administration/installation/services.html +31 -8
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +31 -8
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +31 -8
- nautobot/project-static/docs/user-guide/administration/security/index.html +31 -9
- nautobot/project-static/docs/user-guide/administration/security/notices.html +144 -9
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +31 -8
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +31 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +43 -20
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +35 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +35 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +35 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulefamily.html +10261 -0
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +34 -11
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +31 -8
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +41 -15
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +31 -8
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +31 -8
- nautobot/project-static/docs/user-guide/index.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +37 -9
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/managing-jobs.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +31 -8
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +31 -8
- nautobot/tenancy/tables.py +2 -0
- nautobot/users/models.py +4 -0
- nautobot/virtualization/models.py +4 -0
- nautobot/virtualization/tests/test_views.py +1 -1
- nautobot/wireless/forms.py +0 -1
- nautobot/wireless/models.py +1 -1
- nautobot/wireless/tables.py +7 -0
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/METADATA +4 -4
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/RECORD +433 -418
- /nautobot/dcim/templates/dcim/{platform_edit.html → platform_create.html} +0 -0
- /nautobot/extras/test_jobs/{pass.py → pass_job.py} +0 -0
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/NOTICE +0 -0
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/WHEEL +0 -0
- {nautobot-2.4.9.dist-info → nautobot-2.4.11.dist-info}/entry_points.txt +0 -0
|
@@ -50,6 +50,7 @@ from nautobot.dcim.models import (
|
|
|
50
50
|
Module,
|
|
51
51
|
ModuleBay,
|
|
52
52
|
ModuleBayTemplate,
|
|
53
|
+
ModuleFamily,
|
|
53
54
|
ModuleType,
|
|
54
55
|
Platform,
|
|
55
56
|
PowerOutlet,
|
|
@@ -3404,6 +3405,130 @@ class ModuleTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
3404
3405
|
)
|
|
3405
3406
|
self.assertEqual(child_module.interfaces.first().name, "Interface " + module_bay_position + "/3/2")
|
|
3406
3407
|
|
|
3408
|
+
def test_module_manufacturer_constraint_requires_first_party_false(self):
|
|
3409
|
+
"""Test that modules are allowed when requires_first_party_modules is False, regardless of manufacturer."""
|
|
3410
|
+
manufacturer = Manufacturer.objects.create(name="Different Manufacturer")
|
|
3411
|
+
module_type = ModuleType.objects.create(manufacturer=manufacturer, model="Different Module")
|
|
3412
|
+
module_bay = ModuleBay.objects.create(
|
|
3413
|
+
parent_device=self.device, position="test1", requires_first_party_modules=False
|
|
3414
|
+
)
|
|
3415
|
+
module = Module(
|
|
3416
|
+
module_type=module_type,
|
|
3417
|
+
parent_module_bay=module_bay,
|
|
3418
|
+
status=self.status,
|
|
3419
|
+
)
|
|
3420
|
+
|
|
3421
|
+
module.full_clean()
|
|
3422
|
+
module.save()
|
|
3423
|
+
|
|
3424
|
+
def test_module_manufacturer_constraint_device_parent_same_manufacturer(self):
|
|
3425
|
+
"""Test that modules are allowed when requires_first_party_modules is True and manufacturers match."""
|
|
3426
|
+
device_manufacturer = self.device.device_type.manufacturer
|
|
3427
|
+
module_type = ModuleType.objects.create(manufacturer=device_manufacturer, model="Same Manufacturer Module")
|
|
3428
|
+
module_bay = ModuleBay.objects.create(
|
|
3429
|
+
parent_device=self.device, position="test2", requires_first_party_modules=True
|
|
3430
|
+
)
|
|
3431
|
+
module = Module(
|
|
3432
|
+
module_type=module_type,
|
|
3433
|
+
parent_module_bay=module_bay,
|
|
3434
|
+
status=self.status,
|
|
3435
|
+
)
|
|
3436
|
+
|
|
3437
|
+
module.full_clean()
|
|
3438
|
+
module.save()
|
|
3439
|
+
|
|
3440
|
+
def test_module_manufacturer_constraint_device_parent_different_manufacturer(self):
|
|
3441
|
+
"""Test that modules are rejected when requires_first_party_modules is True and manufacturers don't match."""
|
|
3442
|
+
manufacturer = Manufacturer.objects.create(name="Different Manufacturer")
|
|
3443
|
+
module_type = ModuleType.objects.create(manufacturer=manufacturer, model="Different Module")
|
|
3444
|
+
module_bay = ModuleBay.objects.create(
|
|
3445
|
+
parent_device=self.device, position="test3", requires_first_party_modules=True
|
|
3446
|
+
)
|
|
3447
|
+
module = Module(
|
|
3448
|
+
module_type=module_type,
|
|
3449
|
+
parent_module_bay=module_bay,
|
|
3450
|
+
status=self.status,
|
|
3451
|
+
)
|
|
3452
|
+
|
|
3453
|
+
with self.assertRaises(ValidationError) as context:
|
|
3454
|
+
module.full_clean()
|
|
3455
|
+
|
|
3456
|
+
self.assertIn("module_type", context.exception.message_dict)
|
|
3457
|
+
self.assertIn(
|
|
3458
|
+
"The selected module bay requires a module type from the same manufacturer as the parent device or module",
|
|
3459
|
+
context.exception.message_dict["module_type"],
|
|
3460
|
+
)
|
|
3461
|
+
|
|
3462
|
+
def test_module_manufacturer_constraint_module_parent_same_manufacturer(self):
|
|
3463
|
+
"""Test that modules are allowed when requires_first_party_modules is True and manufacturers match."""
|
|
3464
|
+
manufacturer = Manufacturer.objects.create(name="Parent Manufacturer")
|
|
3465
|
+
parent_module_type = ModuleType.objects.create(manufacturer=manufacturer, model="Parent Module")
|
|
3466
|
+
ModuleBayTemplate.objects.create(module_type=parent_module_type, position="child1")
|
|
3467
|
+
|
|
3468
|
+
parent_module = Module.objects.create(
|
|
3469
|
+
module_type=parent_module_type,
|
|
3470
|
+
location=self.location,
|
|
3471
|
+
status=self.status,
|
|
3472
|
+
)
|
|
3473
|
+
child_module_type = ModuleType.objects.create(manufacturer=manufacturer, model="Child Module")
|
|
3474
|
+
parent_module_bay = parent_module.module_bays.first()
|
|
3475
|
+
parent_module_bay.requires_first_party_modules = True
|
|
3476
|
+
parent_module_bay.save()
|
|
3477
|
+
|
|
3478
|
+
child_module = Module(
|
|
3479
|
+
module_type=child_module_type,
|
|
3480
|
+
parent_module_bay=parent_module_bay,
|
|
3481
|
+
status=self.status,
|
|
3482
|
+
)
|
|
3483
|
+
|
|
3484
|
+
child_module.full_clean()
|
|
3485
|
+
child_module.save()
|
|
3486
|
+
|
|
3487
|
+
def test_module_manufacturer_constraint_module_parent_different_manufacturer(self):
|
|
3488
|
+
"""Test that modules are rejected when requires_first_party_modules is True and manufacturers don't match."""
|
|
3489
|
+
parent_manufacturer = Manufacturer.objects.create(name="Parent Manufacturer")
|
|
3490
|
+
parent_module_type = ModuleType.objects.create(manufacturer=parent_manufacturer, model="Parent Module")
|
|
3491
|
+
ModuleBayTemplate.objects.create(module_type=parent_module_type, position="child2")
|
|
3492
|
+
|
|
3493
|
+
parent_module = Module.objects.create(
|
|
3494
|
+
module_type=parent_module_type,
|
|
3495
|
+
location=self.location,
|
|
3496
|
+
status=self.status,
|
|
3497
|
+
)
|
|
3498
|
+
child_manufacturer = Manufacturer.objects.create(name="Child Manufacturer")
|
|
3499
|
+
child_module_type = ModuleType.objects.create(manufacturer=child_manufacturer, model="Child Module")
|
|
3500
|
+
parent_module_bay = parent_module.module_bays.first()
|
|
3501
|
+
parent_module_bay.requires_first_party_modules = True
|
|
3502
|
+
parent_module_bay.save()
|
|
3503
|
+
|
|
3504
|
+
child_module = Module(
|
|
3505
|
+
module_type=child_module_type,
|
|
3506
|
+
parent_module_bay=parent_module_bay,
|
|
3507
|
+
status=self.status,
|
|
3508
|
+
)
|
|
3509
|
+
|
|
3510
|
+
with self.assertRaises(ValidationError) as context:
|
|
3511
|
+
child_module.full_clean()
|
|
3512
|
+
|
|
3513
|
+
self.assertIn("module_type", context.exception.message_dict)
|
|
3514
|
+
self.assertIn(
|
|
3515
|
+
"The selected module bay requires a module type from the same manufacturer as the parent device or module",
|
|
3516
|
+
context.exception.message_dict["module_type"],
|
|
3517
|
+
)
|
|
3518
|
+
|
|
3519
|
+
def test_module_manufacturer_constraint_no_parent_module_bay(self):
|
|
3520
|
+
"""Test that manufacturer constraint validation is skipped when parent_module_bay is None."""
|
|
3521
|
+
manufacturer = Manufacturer.objects.create(name="Any Manufacturer")
|
|
3522
|
+
module_type = ModuleType.objects.create(manufacturer=manufacturer, model="Any Module")
|
|
3523
|
+
module = Module(
|
|
3524
|
+
module_type=module_type,
|
|
3525
|
+
location=self.location,
|
|
3526
|
+
status=self.status,
|
|
3527
|
+
)
|
|
3528
|
+
|
|
3529
|
+
module.full_clean()
|
|
3530
|
+
module.save()
|
|
3531
|
+
|
|
3407
3532
|
|
|
3408
3533
|
class ModuleTypeTestCase(ModelTestCases.BaseModelTestCase):
|
|
3409
3534
|
model = ModuleType
|
|
@@ -3507,3 +3632,24 @@ class VirtualDeviceContextTestCase(ModelTestCases.BaseModelTestCase):
|
|
|
3507
3632
|
vdc.validated_save()
|
|
3508
3633
|
|
|
3509
3634
|
self.assertIn("Virtual Device Context's device cannot be changed once created", str(err.exception))
|
|
3635
|
+
|
|
3636
|
+
|
|
3637
|
+
class ModuleFamilyTestCase(ModelTestCases.BaseModelTestCase):
|
|
3638
|
+
"""Test cases for the ModuleFamily model."""
|
|
3639
|
+
|
|
3640
|
+
model = ModuleFamily
|
|
3641
|
+
|
|
3642
|
+
def setUp(self):
|
|
3643
|
+
"""Create a ModuleFamily for use in test methods."""
|
|
3644
|
+
self.module_family = ModuleFamily.objects.create(
|
|
3645
|
+
name="Test Module Family", description="A module family for testing"
|
|
3646
|
+
)
|
|
3647
|
+
|
|
3648
|
+
def test_create_modulefamily(self):
|
|
3649
|
+
"""Test the creation of a ModuleFamily instance."""
|
|
3650
|
+
self.assertEqual(self.module_family.name, "Test Module Family")
|
|
3651
|
+
self.assertEqual(self.module_family.description, "A module family for testing")
|
|
3652
|
+
|
|
3653
|
+
def test_modulefamily_str(self):
|
|
3654
|
+
"""Test string representation of ModuleFamily."""
|
|
3655
|
+
self.assertEqual(str(self.module_family), "Test Module Family")
|
|
@@ -85,6 +85,7 @@ from nautobot.dcim.models import (
|
|
|
85
85
|
Module,
|
|
86
86
|
ModuleBay,
|
|
87
87
|
ModuleBayTemplate,
|
|
88
|
+
ModuleFamily,
|
|
88
89
|
ModuleType,
|
|
89
90
|
Platform,
|
|
90
91
|
PowerFeed,
|
|
@@ -2007,6 +2008,7 @@ class ModuleBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
|
|
|
2007
2008
|
def setUpTestData(cls):
|
|
2008
2009
|
device_type = DeviceType.objects.first()
|
|
2009
2010
|
module_type = ModuleType.objects.first()
|
|
2011
|
+
module_family = ModuleFamily.objects.create(name="Test Module Family")
|
|
2010
2012
|
|
|
2011
2013
|
cls.form_data = {
|
|
2012
2014
|
"device_type": device_type.pk,
|
|
@@ -2015,6 +2017,7 @@ class ModuleBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
|
|
|
2015
2017
|
"position": "Test modulebaytemplate position",
|
|
2016
2018
|
"description": "Test modulebaytemplate description",
|
|
2017
2019
|
"label": "Test modulebaytemplate label",
|
|
2020
|
+
"module_family": module_family.pk,
|
|
2018
2021
|
}
|
|
2019
2022
|
|
|
2020
2023
|
cls.bulk_create_data = {
|
|
@@ -2023,10 +2026,12 @@ class ModuleBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
|
|
|
2023
2026
|
"position_pattern": "Test Module Bay Template Position [10-12]",
|
|
2024
2027
|
"label_pattern": "Test modulebaytemplate label [1-3]",
|
|
2025
2028
|
"description": "Test modulebaytemplate description",
|
|
2029
|
+
"module_family": module_family.pk,
|
|
2026
2030
|
}
|
|
2027
2031
|
|
|
2028
2032
|
cls.bulk_edit_data = {
|
|
2029
2033
|
"description": "Description changed",
|
|
2034
|
+
"module_family": module_family.pk,
|
|
2030
2035
|
}
|
|
2031
2036
|
|
|
2032
2037
|
test_instance = cls.model.objects.first()
|
|
@@ -2037,6 +2042,7 @@ class ModuleBayTemplateTestCase(ViewTestCases.DeviceComponentTemplateViewTestCas
|
|
|
2037
2042
|
"position": "new test position",
|
|
2038
2043
|
"label": "new test label",
|
|
2039
2044
|
"description": "new test description",
|
|
2045
|
+
"module_family": module_family.pk,
|
|
2040
2046
|
}
|
|
2041
2047
|
|
|
2042
2048
|
|
|
@@ -2560,6 +2566,16 @@ class DeviceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2560
2566
|
|
|
2561
2567
|
class ModuleTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
2562
2568
|
model = Module
|
|
2569
|
+
custom_action_required_permissions = {
|
|
2570
|
+
"dcim:module_consoleports": ["dcim.view_module", "dcim.view_consoleport"],
|
|
2571
|
+
"dcim:module_consoleserverports": ["dcim.view_module", "dcim.view_consoleserverport"],
|
|
2572
|
+
"dcim:module_powerports": ["dcim.view_module", "dcim.view_powerport"],
|
|
2573
|
+
"dcim:module_poweroutlets": ["dcim.view_module", "dcim.view_poweroutlet"],
|
|
2574
|
+
"dcim:module_interfaces": ["dcim.view_module", "dcim.view_interface"],
|
|
2575
|
+
"dcim:module_rearports": ["dcim.view_module", "dcim.view_rearport"],
|
|
2576
|
+
"dcim:module_frontports": ["dcim.view_module", "dcim.view_frontport"],
|
|
2577
|
+
"dcim:module_modulebays": ["dcim.view_module", "dcim.view_modulebay"],
|
|
2578
|
+
}
|
|
2563
2579
|
|
|
2564
2580
|
@classmethod
|
|
2565
2581
|
def setUpTestData(cls):
|
|
@@ -2668,50 +2684,6 @@ class ModuleTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2668
2684
|
"status": statuses[2].pk,
|
|
2669
2685
|
}
|
|
2670
2686
|
|
|
2671
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2672
|
-
def test_module_consoleports(self):
|
|
2673
|
-
module = Module.objects.first()
|
|
2674
|
-
|
|
2675
|
-
ConsolePort.objects.create(module=module, name="Console Port 1")
|
|
2676
|
-
ConsolePort.objects.create(module=module, name="Console Port 2")
|
|
2677
|
-
ConsolePort.objects.create(module=module, name="Console Port 3")
|
|
2678
|
-
|
|
2679
|
-
url = reverse("dcim:module_consoleports", kwargs={"pk": module.pk})
|
|
2680
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2681
|
-
|
|
2682
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2683
|
-
def test_module_consoleserverports(self):
|
|
2684
|
-
module = Module.objects.first()
|
|
2685
|
-
|
|
2686
|
-
ConsoleServerPort.objects.create(module=module, name="Console Server Port 1")
|
|
2687
|
-
ConsoleServerPort.objects.create(module=module, name="Console Server Port 2")
|
|
2688
|
-
ConsoleServerPort.objects.create(module=module, name="Console Server Port 3")
|
|
2689
|
-
|
|
2690
|
-
url = reverse("dcim:module_consoleserverports", kwargs={"pk": module.pk})
|
|
2691
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2692
|
-
|
|
2693
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2694
|
-
def test_module_powerports(self):
|
|
2695
|
-
module = Module.objects.first()
|
|
2696
|
-
|
|
2697
|
-
PowerPort.objects.create(module=module, name="Power Port 1")
|
|
2698
|
-
PowerPort.objects.create(module=module, name="Power Port 2")
|
|
2699
|
-
PowerPort.objects.create(module=module, name="Power Port 3")
|
|
2700
|
-
|
|
2701
|
-
url = reverse("dcim:module_powerports", kwargs={"pk": module.pk})
|
|
2702
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2703
|
-
|
|
2704
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2705
|
-
def test_module_poweroutlets(self):
|
|
2706
|
-
module = Module.objects.first()
|
|
2707
|
-
|
|
2708
|
-
PowerOutlet.objects.create(module=module, name="Power Outlet 1")
|
|
2709
|
-
PowerOutlet.objects.create(module=module, name="Power Outlet 2")
|
|
2710
|
-
PowerOutlet.objects.create(module=module, name="Power Outlet 3")
|
|
2711
|
-
|
|
2712
|
-
url = reverse("dcim:module_poweroutlets", kwargs={"pk": module.pk})
|
|
2713
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2714
|
-
|
|
2715
2687
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2716
2688
|
def test_module_interfaces(self):
|
|
2717
2689
|
module = Module.objects.filter(interfaces__isnull=False).first()
|
|
@@ -2793,59 +2765,6 @@ class ModuleTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
2793
2765
|
sorted(interface_ips),
|
|
2794
2766
|
)
|
|
2795
2767
|
|
|
2796
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2797
|
-
def test_module_rearports(self):
|
|
2798
|
-
module = Module.objects.first()
|
|
2799
|
-
|
|
2800
|
-
RearPort.objects.create(module=module, name="Rear Port 1")
|
|
2801
|
-
RearPort.objects.create(module=module, name="Rear Port 2")
|
|
2802
|
-
RearPort.objects.create(module=module, name="Rear Port 3")
|
|
2803
|
-
|
|
2804
|
-
url = reverse("dcim:module_rearports", kwargs={"pk": module.pk})
|
|
2805
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2806
|
-
|
|
2807
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2808
|
-
def test_module_frontports(self):
|
|
2809
|
-
module = Module.objects.first()
|
|
2810
|
-
rear_ports = (
|
|
2811
|
-
RearPort.objects.create(module=module, name="Rear Port 1"),
|
|
2812
|
-
RearPort.objects.create(module=module, name="Rear Port 2"),
|
|
2813
|
-
RearPort.objects.create(module=module, name="Rear Port 3"),
|
|
2814
|
-
)
|
|
2815
|
-
|
|
2816
|
-
FrontPort.objects.create(
|
|
2817
|
-
module=module,
|
|
2818
|
-
name="Front Port 1",
|
|
2819
|
-
rear_port=rear_ports[0],
|
|
2820
|
-
rear_port_position=1,
|
|
2821
|
-
)
|
|
2822
|
-
FrontPort.objects.create(
|
|
2823
|
-
module=module,
|
|
2824
|
-
name="Front Port 2",
|
|
2825
|
-
rear_port=rear_ports[1],
|
|
2826
|
-
rear_port_position=1,
|
|
2827
|
-
)
|
|
2828
|
-
FrontPort.objects.create(
|
|
2829
|
-
module=module,
|
|
2830
|
-
name="Front Port 3",
|
|
2831
|
-
rear_port=rear_ports[2],
|
|
2832
|
-
rear_port_position=1,
|
|
2833
|
-
)
|
|
2834
|
-
|
|
2835
|
-
url = reverse("dcim:module_frontports", kwargs={"pk": module.pk})
|
|
2836
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2837
|
-
|
|
2838
|
-
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2839
|
-
def test_module_modulebays(self):
|
|
2840
|
-
module = Module.objects.first()
|
|
2841
|
-
|
|
2842
|
-
ModuleBay.objects.create(parent_module=module, name="Test View Module Bay 1")
|
|
2843
|
-
ModuleBay.objects.create(parent_module=module, name="Test View Module Bay 2")
|
|
2844
|
-
ModuleBay.objects.create(parent_module=module, name="Test View Module Bay 3")
|
|
2845
|
-
|
|
2846
|
-
url = reverse("dcim:module_modulebays", kwargs={"pk": module.pk})
|
|
2847
|
-
self.assertHttpStatus(self.client.get(url), 200)
|
|
2848
|
-
|
|
2849
2768
|
|
|
2850
2769
|
class ConsolePortTestCase(ViewTestCases.DeviceComponentViewTestCase):
|
|
2851
2770
|
model = ConsolePort
|
|
@@ -4587,6 +4506,15 @@ class InterfaceRedundancyGroupTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
4587
4506
|
class SoftwareImageFileTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
4588
4507
|
model = SoftwareImageFile
|
|
4589
4508
|
filterset = SoftwareImageFileFilterSet
|
|
4509
|
+
custom_action_required_permissions = {
|
|
4510
|
+
"dcim:softwareimagefile_devices": ["dcim.view_softwareimagefile", "dcim.view_device"],
|
|
4511
|
+
"dcim:softwareimagefile_device_types": ["dcim.view_softwareimagefile", "dcim.view_devicetype"],
|
|
4512
|
+
"dcim:softwareimagefile_virtual_machines": [
|
|
4513
|
+
"dcim.view_softwareimagefile",
|
|
4514
|
+
"virtualization.view_virtualmachine",
|
|
4515
|
+
],
|
|
4516
|
+
"dcim:softwareimagefile_inventory_items": ["dcim.view_softwareimagefile", "dcim.view_inventoryitem"],
|
|
4517
|
+
}
|
|
4590
4518
|
|
|
4591
4519
|
@classmethod
|
|
4592
4520
|
def setUpTestData(cls):
|
|
@@ -4659,6 +4587,12 @@ class SoftwareVersionTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
4659
4587
|
class ControllerTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
4660
4588
|
model = Controller
|
|
4661
4589
|
filterset = ControllerFilterSet
|
|
4590
|
+
custom_action_required_permissions = {
|
|
4591
|
+
"dcim:controller_wirelessnetworks": [
|
|
4592
|
+
"dcim.view_controller",
|
|
4593
|
+
"wireless.view_controllermanageddevicegroupwirelessnetworkassignment",
|
|
4594
|
+
],
|
|
4595
|
+
}
|
|
4662
4596
|
|
|
4663
4597
|
@classmethod
|
|
4664
4598
|
def setUpTestData(cls):
|
|
@@ -4695,6 +4629,16 @@ class ControllerTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
4695
4629
|
class ControllerManagedDeviceGroupTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
4696
4630
|
model = ControllerManagedDeviceGroup
|
|
4697
4631
|
filterset = ControllerManagedDeviceGroupFilterSet
|
|
4632
|
+
custom_action_required_permissions = {
|
|
4633
|
+
"dcim:controllermanageddevicegroup_wireless_networks": [
|
|
4634
|
+
"dcim.view_controllermanageddevicegroup",
|
|
4635
|
+
"wireless.view_controllermanageddevicegroupwirelessnetworkassignment",
|
|
4636
|
+
],
|
|
4637
|
+
"dcim:controllermanageddevicegroup_radio_profiles": [
|
|
4638
|
+
"dcim.view_controllermanageddevicegroup",
|
|
4639
|
+
"wireless.view_radioprofile",
|
|
4640
|
+
],
|
|
4641
|
+
}
|
|
4698
4642
|
|
|
4699
4643
|
@classmethod
|
|
4700
4644
|
def setUpTestData(cls):
|
|
@@ -4781,3 +4725,32 @@ class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
4781
4725
|
vdc.refresh_from_db()
|
|
4782
4726
|
self.assertEqual(vdc.primary_ip6, ip_v6)
|
|
4783
4727
|
self.assertEqual(vdc.primary_ip4, ip_v4)
|
|
4728
|
+
|
|
4729
|
+
|
|
4730
|
+
class ModuleFamilyTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
4731
|
+
"""Test cases for ModuleFamily views."""
|
|
4732
|
+
|
|
4733
|
+
model = ModuleFamily
|
|
4734
|
+
|
|
4735
|
+
@classmethod
|
|
4736
|
+
def setUpTestData(cls):
|
|
4737
|
+
"""Create test data for ModuleFamily views."""
|
|
4738
|
+
ModuleFamily.objects.create(name="Module Family 1", description="First Module Family")
|
|
4739
|
+
ModuleFamily.objects.create(name="Module Family 2", description="Second Module Family")
|
|
4740
|
+
ModuleFamily.objects.create(name="Module Family 3", description="Third Module Family")
|
|
4741
|
+
|
|
4742
|
+
cls.form_data = {
|
|
4743
|
+
"name": "Module Family X",
|
|
4744
|
+
"description": "A new module family",
|
|
4745
|
+
}
|
|
4746
|
+
|
|
4747
|
+
cls.csv_data = (
|
|
4748
|
+
"name,description",
|
|
4749
|
+
"Module Family 4,Fourth Module Family",
|
|
4750
|
+
"Module Family 5,Fifth Module Family",
|
|
4751
|
+
"Module Family 6,Sixth Module Family",
|
|
4752
|
+
)
|
|
4753
|
+
|
|
4754
|
+
cls.bulk_edit_data = {
|
|
4755
|
+
"description": "Modified description",
|
|
4756
|
+
}
|
nautobot/dcim/urls.py
CHANGED
|
@@ -34,12 +34,14 @@ router.register("device-redundancy-groups", views.DeviceRedundancyGroupUIViewSet
|
|
|
34
34
|
router.register("device-types", views.DeviceTypeUIViewSet)
|
|
35
35
|
router.register("interface-redundancy-groups", views.InterfaceRedundancyGroupUIViewSet)
|
|
36
36
|
router.register("interface-redundancy-groups-associations", views.InterfaceRedundancyGroupAssociationUIViewSet)
|
|
37
|
+
router.register("locations", views.LocationUIViewSet)
|
|
37
38
|
router.register("location-types", views.LocationTypeUIViewSet)
|
|
38
39
|
router.register("manufacturers", views.ManufacturerUIViewSet)
|
|
39
|
-
router.register("module-bays", views.ModuleBayUIViewSet)
|
|
40
40
|
router.register("module-bay-templates", views.ModuleBayTemplateUIViewSet)
|
|
41
|
-
router.register("
|
|
41
|
+
router.register("module-bays", views.ModuleBayUIViewSet)
|
|
42
|
+
router.register("module-families", views.ModuleFamilyUIViewSet)
|
|
42
43
|
router.register("module-types", views.ModuleTypeUIViewSet)
|
|
44
|
+
router.register("modules", views.ModuleUIViewSet)
|
|
43
45
|
router.register("platforms", views.PlatformUIViewSet)
|
|
44
46
|
router.register("power-feeds", views.PowerFeedUIViewSet)
|
|
45
47
|
router.register("power-panels", views.PowerPanelUIViewSet)
|
|
@@ -51,26 +53,6 @@ router.register("virtual-device-contexts", views.VirtualDeviceContextUIViewSet)
|
|
|
51
53
|
|
|
52
54
|
urlpatterns = [
|
|
53
55
|
# Locations
|
|
54
|
-
path("locations/", views.LocationListView.as_view(), name="location_list"),
|
|
55
|
-
path("locations/add/", views.LocationEditView.as_view(), name="location_add"),
|
|
56
|
-
path("locations/edit/", views.LocationBulkEditView.as_view(), name="location_bulk_edit"),
|
|
57
|
-
path("locations/import/", views.LocationBulkImportView.as_view(), name="location_import"), # 3.0 TODO: remove
|
|
58
|
-
path("locations/delete/", views.LocationBulkDeleteView.as_view(), name="location_bulk_delete"),
|
|
59
|
-
path("locations/<uuid:pk>/", views.LocationView.as_view(), name="location"),
|
|
60
|
-
path("locations/<uuid:pk>/edit/", views.LocationEditView.as_view(), name="location_edit"),
|
|
61
|
-
path("locations/<uuid:pk>/delete/", views.LocationDeleteView.as_view(), name="location_delete"),
|
|
62
|
-
path(
|
|
63
|
-
"locations/<uuid:pk>/changelog/",
|
|
64
|
-
ObjectChangeLogView.as_view(),
|
|
65
|
-
name="location_changelog",
|
|
66
|
-
kwargs={"model": Location},
|
|
67
|
-
),
|
|
68
|
-
path(
|
|
69
|
-
"locations/<uuid:pk>/notes/",
|
|
70
|
-
ObjectNotesView.as_view(),
|
|
71
|
-
name="location_notes",
|
|
72
|
-
kwargs={"model": Location},
|
|
73
|
-
),
|
|
74
56
|
path(
|
|
75
57
|
"locations/<uuid:pk>/migrate-data-to-contact/",
|
|
76
58
|
views.MigrateLocationDataToContactView.as_view(),
|