nautobot 2.4.5__py3-none-any.whl → 2.4.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/forms.py +2 -0
- nautobot/circuits/templates/circuits/providernetwork.html +1 -1
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +2 -55
- nautobot/circuits/views.py +20 -23
- nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +2 -40
- nautobot/cloud/views.py +12 -0
- nautobot/core/api/mixins.py +10 -0
- nautobot/core/api/urls.py +2 -2
- nautobot/core/api/views.py +39 -1
- nautobot/core/celery/encoders.py +2 -2
- nautobot/core/forms/__init__.py +2 -0
- nautobot/core/forms/fields.py +23 -7
- nautobot/core/forms/utils.py +1 -0
- nautobot/core/forms/widgets.py +18 -0
- nautobot/core/jobs/bulk_actions.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +1 -1
- nautobot/core/models/name_color_content_types.py +9 -0
- nautobot/core/models/validators.py +7 -0
- nautobot/core/settings.py +0 -14
- nautobot/core/settings.yaml +0 -28
- nautobot/core/tables.py +6 -1
- nautobot/core/templates/generic/object_retrieve.html +1 -1
- nautobot/core/templates/widgets/sluginput.html +5 -1
- nautobot/core/templatetags/helpers.py +15 -1
- nautobot/core/testing/api.py +18 -0
- nautobot/core/testing/integration.py +6 -2
- nautobot/core/tests/nautobot_config.py +0 -2
- nautobot/core/tests/runner.py +17 -140
- nautobot/core/tests/test_api.py +4 -4
- nautobot/core/tests/test_authentication.py +83 -4
- nautobot/core/tests/test_forms.py +11 -8
- nautobot/core/tests/test_graphql.py +9 -0
- nautobot/core/tests/test_jobs.py +7 -0
- nautobot/core/ui/object_detail.py +47 -3
- nautobot/core/utils/lookup.py +2 -2
- nautobot/dcim/factory.py +2 -0
- nautobot/dcim/filters/__init__.py +5 -0
- nautobot/dcim/forms.py +27 -1
- nautobot/dcim/migrations/0068_alter_softwareimagefile_download_url.py +19 -0
- nautobot/dcim/migrations/0069_softwareimagefile_external_integration.py +25 -0
- nautobot/dcim/models/devices.py +9 -2
- nautobot/dcim/models/locations.py +9 -0
- nautobot/dcim/tables/devices.py +1 -0
- nautobot/dcim/templates/dcim/device_list.html +1 -1
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/manufacturer.html +1 -63
- nautobot/dcim/templates/dcim/module_list.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +4 -0
- nautobot/dcim/tests/integration/test_module_bay_position.py +125 -0
- nautobot/dcim/tests/test_api.py +74 -31
- nautobot/dcim/tests/test_filters.py +2 -0
- nautobot/dcim/tests/test_models.py +78 -0
- nautobot/dcim/tests/test_views.py +7 -1
- nautobot/dcim/urls.py +1 -45
- nautobot/dcim/views.py +35 -66
- nautobot/extras/choices.py +4 -0
- nautobot/extras/filters/__init__.py +6 -0
- nautobot/extras/forms/forms.py +83 -11
- nautobot/extras/models/customfields.py +10 -9
- nautobot/extras/plugins/marketplace_manifest.yml +18 -0
- nautobot/extras/signals.py +43 -4
- nautobot/extras/tables.py +4 -5
- nautobot/extras/tasks.py +4 -2
- nautobot/extras/templates/extras/contact_retrieve.html +1 -58
- nautobot/extras/templates/extras/exporttemplate.html +1 -53
- nautobot/extras/templates/extras/inc/panel_changelog.html +1 -1
- nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
- nautobot/extras/templates/extras/status.html +1 -37
- nautobot/extras/templates/extras/team_retrieve.html +1 -58
- nautobot/extras/tests/integration/test_notes.py +1 -1
- nautobot/extras/tests/test_api.py +22 -7
- nautobot/extras/tests/test_changelog.py +4 -4
- nautobot/extras/tests/test_customfields.py +27 -0
- nautobot/extras/tests/test_plugins.py +19 -13
- nautobot/extras/tests/test_relationships.py +9 -0
- nautobot/extras/tests/test_tags.py +2 -2
- nautobot/extras/tests/test_views.py +37 -6
- nautobot/extras/urls.py +3 -100
- nautobot/extras/views.py +111 -133
- nautobot/ipam/tables.py +7 -2
- nautobot/ipam/templates/ipam/namespace_retrieve.html +0 -41
- nautobot/ipam/templates/ipam/service.html +2 -46
- nautobot/ipam/templates/ipam/service_edit.html +1 -17
- nautobot/ipam/templates/ipam/service_retrieve.html +7 -0
- nautobot/ipam/tests/migration/__init__.py +0 -0
- nautobot/ipam/tests/migration/test_migrations.py +510 -0
- nautobot/ipam/tests/test_api.py +66 -36
- nautobot/ipam/tests/test_filters.py +0 -10
- nautobot/ipam/tests/test_views.py +44 -2
- nautobot/ipam/urls.py +2 -47
- nautobot/ipam/utils/migrations.py +185 -152
- nautobot/ipam/utils/testing.py +177 -0
- nautobot/ipam/views.py +95 -157
- nautobot/project-static/css/base.css +5 -0
- nautobot/project-static/docs/404.html +0 -2
- nautobot/project-static/docs/apps/index.html +0 -2
- nautobot/project-static/docs/apps/nautobot-apps.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +62 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +47 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +18 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +70 -5
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +0 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +0 -2
- nautobot/project-static/docs/development/apps/api/configuration-view.html +0 -2
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/global-search.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/graphql.html +0 -2
- nautobot/project-static/docs/development/apps/api/models/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +0 -2
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +0 -2
- nautobot/project-static/docs/development/apps/api/prometheus.html +0 -2
- nautobot/project-static/docs/development/apps/api/setup.html +0 -2
- nautobot/project-static/docs/development/apps/api/testing.html +0 -89
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +0 -2
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/base-template.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/index.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/notes.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +0 -2
- nautobot/project-static/docs/development/apps/api/views/urls.html +0 -2
- nautobot/project-static/docs/development/apps/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/code-updates.html +0 -2
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +1 -3
- nautobot/project-static/docs/development/apps/migration/from-v1.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +0 -2
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +0 -2
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +0 -2
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +0 -2
- nautobot/project-static/docs/development/core/application-registry.html +0 -2
- nautobot/project-static/docs/development/core/best-practices.html +3 -5
- nautobot/project-static/docs/development/core/bootstrap-ui.html +0 -2
- nautobot/project-static/docs/development/core/caching.html +0 -2
- nautobot/project-static/docs/development/core/controllers.html +0 -2
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +0 -2
- nautobot/project-static/docs/development/core/generic-views.html +0 -2
- nautobot/project-static/docs/development/core/getting-started.html +78 -109
- nautobot/project-static/docs/development/core/homepage.html +0 -2
- nautobot/project-static/docs/development/core/index.html +0 -2
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +0 -2
- nautobot/project-static/docs/development/core/model-checklist.html +0 -2
- nautobot/project-static/docs/development/core/model-features.html +0 -2
- nautobot/project-static/docs/development/core/natural-keys.html +0 -2
- nautobot/project-static/docs/development/core/navigation-menu.html +0 -2
- nautobot/project-static/docs/development/core/release-checklist.html +1 -3
- nautobot/project-static/docs/development/core/role-internals.html +0 -2
- nautobot/project-static/docs/development/core/settings.html +0 -2
- nautobot/project-static/docs/development/core/style-guide.html +1 -3
- nautobot/project-static/docs/development/core/templates.html +0 -2
- nautobot/project-static/docs/development/core/testing.html +24 -200
- nautobot/project-static/docs/development/core/ui-component-framework.html +0 -2
- nautobot/project-static/docs/development/core/user-preferences.html +0 -2
- nautobot/project-static/docs/development/index.html +0 -2
- nautobot/project-static/docs/development/jobs/index.html +0 -2
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +0 -2
- nautobot/project-static/docs/index.html +0 -2
- nautobot/project-static/docs/media/user-guide/administration/getting-started/nautobot-cloud.png +0 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +1 -3
- nautobot/project-static/docs/overview/design_philosophy.html +0 -2
- nautobot/project-static/docs/release-notes/index.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.4.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.5.html +0 -2
- nautobot/project-static/docs/release-notes/version-1.6.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.0.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.1.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.2.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.3.html +0 -2
- nautobot/project-static/docs/release-notes/version-2.4.html +364 -3
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +290 -290
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +0 -2
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +2 -50
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +71 -2
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +0 -2
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +3 -3
- nautobot/project-static/docs/user-guide/administration/installation/index.html +257 -18
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +0 -2
- nautobot/project-static/docs/user-guide/administration/installation/services.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +0 -2
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/security/notices.html +0 -2
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +1 -3
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +0 -2
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +2 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +4 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +0 -2
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +11 -13
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +8 -10
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +1 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +40 -27
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +4 -6
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +77 -7
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +0 -3
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +1 -3
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +0 -2
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +0 -2
- nautobot/project-static/docs/user-guide/index.html +89 -4
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +0 -2
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +207 -124
- nautobot/project-static/js/forms.js +88 -37
- nautobot/project-static/js/homepage_layout.js +12 -3
- nautobot/virtualization/forms.py +20 -0
- nautobot/virtualization/templates/virtualization/clustergroup.html +1 -39
- nautobot/virtualization/templates/virtualization/clustertype.html +1 -0
- nautobot/virtualization/tests/test_api.py +14 -3
- nautobot/virtualization/tests/test_views.py +10 -2
- nautobot/virtualization/urls.py +10 -93
- nautobot/virtualization/views.py +33 -72
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/METADATA +6 -5
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/RECORD +407 -402
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/WHEEL +1 -1
- nautobot/core/tests/performance_baselines.yml +0 -8900
- nautobot/dcim/templates/dcim/modulebay_create.html +0 -39
- nautobot/ipam/tests/test_migrations.py +0 -462
- /nautobot/ipam/templates/ipam/{namespace_ipaddresses.html → namespace_ip_addresses.html} +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/NOTICE +0 -0
- {nautobot-2.4.5.dist-info → nautobot-2.4.7.dist-info}/entry_points.txt +0 -0
nautobot/ipam/tests/test_api.py
CHANGED
|
@@ -163,16 +163,6 @@ class VRFDeviceAssignmentTest(APIViewTestCases.APIViewTestCase):
|
|
|
163
163
|
virtual_machine=cls.test_vm,
|
|
164
164
|
rd="65000:4",
|
|
165
165
|
)
|
|
166
|
-
VRFDeviceAssignment.objects.create(
|
|
167
|
-
vrf=cls.vrfs[0],
|
|
168
|
-
virtual_device_context=cls.vdcs[0],
|
|
169
|
-
name="VRFDeviceAssignment 1",
|
|
170
|
-
rd="65000:5",
|
|
171
|
-
)
|
|
172
|
-
VRFDeviceAssignment.objects.create(
|
|
173
|
-
vrf=cls.vrfs[0],
|
|
174
|
-
virtual_device_context=cls.vdcs[1],
|
|
175
|
-
)
|
|
176
166
|
|
|
177
167
|
cls.update_data = {
|
|
178
168
|
"name": "VRFDeviceAssignment 2",
|
|
@@ -207,21 +197,30 @@ class VRFDeviceAssignmentTest(APIViewTestCases.APIViewTestCase):
|
|
|
207
197
|
|
|
208
198
|
def test_creating_invalid_vrf_device_assignments(self):
|
|
209
199
|
# Add object-level permission
|
|
210
|
-
self.add_permissions(
|
|
200
|
+
self.add_permissions(
|
|
201
|
+
"ipam.add_vrfdeviceassignment",
|
|
202
|
+
"dcim.view_device",
|
|
203
|
+
"dcim.view_virtualdevicecontext",
|
|
204
|
+
"ipam.view_vrf",
|
|
205
|
+
"virtualization.view_virtualmachine",
|
|
206
|
+
)
|
|
207
|
+
existing_vrf_device = VRFDeviceAssignment.objects.filter(device__isnull=False).first()
|
|
208
|
+
existing_vrf_vm = VRFDeviceAssignment.objects.filter(virtual_machine__isnull=False).first()
|
|
209
|
+
existing_vrf_vdc = VRFDeviceAssignment.objects.filter(virtual_device_context__isnull=False).first()
|
|
211
210
|
duplicate_create_data = [
|
|
212
211
|
{
|
|
213
|
-
"vrf":
|
|
214
|
-
"device":
|
|
212
|
+
"vrf": existing_vrf_device.vrf.pk,
|
|
213
|
+
"device": existing_vrf_device.device.pk,
|
|
215
214
|
"rd": "65000:6",
|
|
216
215
|
},
|
|
217
216
|
{
|
|
218
|
-
"vrf":
|
|
219
|
-
"virtual_machine":
|
|
217
|
+
"vrf": existing_vrf_vm.vrf.pk,
|
|
218
|
+
"virtual_machine": existing_vrf_vm.virtual_machine.pk,
|
|
220
219
|
"rd": "65000:6",
|
|
221
220
|
},
|
|
222
221
|
{
|
|
223
|
-
"vrf":
|
|
224
|
-
"virtual_device_context":
|
|
222
|
+
"vrf": existing_vrf_vdc.vrf.pk,
|
|
223
|
+
"virtual_device_context": existing_vrf_vdc.virtual_device_context.pk,
|
|
225
224
|
"rd": "65000:6",
|
|
226
225
|
},
|
|
227
226
|
]
|
|
@@ -311,7 +310,7 @@ class VRFPrefixAssignmentTest(APIViewTestCases.APIViewTestCase):
|
|
|
311
310
|
"vrf": self.vrfs[0].pk,
|
|
312
311
|
"prefix": None,
|
|
313
312
|
}
|
|
314
|
-
self.add_permissions("ipam.add_vrfprefixassignment")
|
|
313
|
+
self.add_permissions("ipam.add_vrfprefixassignment", "ipam.view_prefix", "ipam.view_vrf")
|
|
315
314
|
response = self.client.post(self._get_list_url(), duplicate_create_data, format="json", **self.header)
|
|
316
315
|
self.assertContains(
|
|
317
316
|
response, "The fields vrf, prefix must make a unique set.", status_code=status.HTTP_400_BAD_REQUEST
|
|
@@ -420,7 +419,16 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
420
419
|
"""
|
|
421
420
|
Tests for the 2.0/2.1 REST API of Prefixes.
|
|
422
421
|
"""
|
|
423
|
-
self.add_permissions(
|
|
422
|
+
self.add_permissions(
|
|
423
|
+
"dcim.view_location",
|
|
424
|
+
"ipam.view_prefix",
|
|
425
|
+
"ipam.add_prefix",
|
|
426
|
+
"ipam.change_prefix",
|
|
427
|
+
"ipam.view_ipaddress",
|
|
428
|
+
"ipam.view_namespace",
|
|
429
|
+
"ipam.view_rir",
|
|
430
|
+
"extras.view_status",
|
|
431
|
+
)
|
|
424
432
|
|
|
425
433
|
with self.subTest("valid GET"):
|
|
426
434
|
prefix = Prefix.objects.annotate(location_count=Count("locations")).filter(location_count=1).first()
|
|
@@ -516,7 +524,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
516
524
|
else:
|
|
517
525
|
self.fail("Suitable prefix fixture not found")
|
|
518
526
|
url = reverse("ipam-api:prefix-available-prefixes", kwargs={"pk": prefix.pk})
|
|
519
|
-
self.add_permissions("ipam.add_prefix")
|
|
527
|
+
self.add_permissions("ipam.add_prefix", "ipam.view_namespace", "extras.view_status", "extras.add_customfield")
|
|
520
528
|
|
|
521
529
|
# Create four available prefixes with individual requests
|
|
522
530
|
child_prefix_length = prefix.prefix_length + 2
|
|
@@ -566,7 +574,9 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
566
574
|
self.fail("Suitable prefix fixture not found")
|
|
567
575
|
|
|
568
576
|
url = reverse("ipam-api:prefix-available-prefixes", kwargs={"pk": prefix.pk})
|
|
569
|
-
self.add_permissions(
|
|
577
|
+
self.add_permissions(
|
|
578
|
+
"ipam.view_prefix", "ipam.add_prefix", "extras.view_status", "extras.add_customfield", "ipam.view_namespace"
|
|
579
|
+
)
|
|
570
580
|
|
|
571
581
|
# Try to create five prefixes (only four are available)
|
|
572
582
|
child_prefix_length = prefix.prefix_length + 2
|
|
@@ -626,7 +636,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
626
636
|
description="This is the Prefix created for whole network.",
|
|
627
637
|
)
|
|
628
638
|
url = reverse("ipam-api:prefix-available-prefixes", kwargs={"pk": prefix.pk})
|
|
629
|
-
self.add_permissions("ipam.view_prefix")
|
|
639
|
+
self.add_permissions("ipam.view_prefix", "ipam.view_namespace", "extras.view_status")
|
|
630
640
|
self.add_permissions(
|
|
631
641
|
"ipam.add_prefix", constraints={"description__startswith": "This is the Prefix created for"}
|
|
632
642
|
)
|
|
@@ -683,9 +693,10 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
683
693
|
description="This is the Prefix created for whole network.",
|
|
684
694
|
)
|
|
685
695
|
url = reverse("ipam-api:prefix-available-prefixes", kwargs={"pk": prefix.pk})
|
|
686
|
-
self.add_permissions("ipam.view_prefix")
|
|
696
|
+
self.add_permissions("ipam.view_prefix", "ipam.view_namespace", "extras.view_status")
|
|
687
697
|
self.add_permissions(
|
|
688
|
-
"ipam.add_prefix",
|
|
698
|
+
"ipam.add_prefix",
|
|
699
|
+
constraints={"description__startswith": "This is the Prefix created for"},
|
|
689
700
|
)
|
|
690
701
|
|
|
691
702
|
# Test invalid request
|
|
@@ -812,7 +823,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
812
823
|
namespace=self.namespace,
|
|
813
824
|
)
|
|
814
825
|
url = reverse("ipam-api:prefix-available-ips", kwargs={"pk": prefix.pk})
|
|
815
|
-
self.add_permissions("ipam.view_prefix", "ipam.add_ipaddress", "extras.view_status")
|
|
826
|
+
self.add_permissions("ipam.view_prefix", "ipam.add_ipaddress", "ipam.view_namespace", "extras.view_status")
|
|
816
827
|
|
|
817
828
|
data = {
|
|
818
829
|
"status": self.status.pk,
|
|
@@ -839,7 +850,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
839
850
|
cf = CustomField.objects.create(key="ipcf", label="IP Custom Field", type="text")
|
|
840
851
|
cf.content_types.add(ContentType.objects.get_for_model(IPAddress))
|
|
841
852
|
url = reverse("ipam-api:prefix-available-ips", kwargs={"pk": prefix.pk})
|
|
842
|
-
self.add_permissions("ipam.view_prefix", "ipam.add_ipaddress", "extras.view_status")
|
|
853
|
+
self.add_permissions("ipam.view_prefix", "ipam.view_namespace", "ipam.add_ipaddress", "extras.view_status")
|
|
843
854
|
|
|
844
855
|
# Create all six available IPs with individual requests
|
|
845
856
|
for i in range(1, 7):
|
|
@@ -875,7 +886,13 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
875
886
|
cf = CustomField.objects.create(key="ipcf", label="IP Custom Field", type="text")
|
|
876
887
|
cf.content_types.add(ContentType.objects.get_for_model(IPAddress))
|
|
877
888
|
url = reverse("ipam-api:prefix-available-ips", kwargs={"pk": prefix.pk})
|
|
878
|
-
self.add_permissions(
|
|
889
|
+
self.add_permissions(
|
|
890
|
+
"ipam.view_prefix",
|
|
891
|
+
"ipam.add_ipaddress",
|
|
892
|
+
"ipam.view_namespace",
|
|
893
|
+
"extras.view_customfield",
|
|
894
|
+
"extras.view_status",
|
|
895
|
+
)
|
|
879
896
|
|
|
880
897
|
# Try to create seven IPs (only six are available)
|
|
881
898
|
data = [
|
|
@@ -906,7 +923,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
906
923
|
description="This is the Prefix created for whole network.",
|
|
907
924
|
)
|
|
908
925
|
url = reverse("ipam-api:prefix-available-ips", kwargs={"pk": prefix.pk})
|
|
909
|
-
self.add_permissions("ipam.view_prefix", "ipam.view_ipaddress")
|
|
926
|
+
self.add_permissions("ipam.view_prefix", "ipam.view_ipaddress", "ipam.view_namespace", "extras.view_status")
|
|
910
927
|
self.add_permissions(
|
|
911
928
|
"ipam.add_ipaddress", constraints={"description__startswith": "This is the IP created for"}
|
|
912
929
|
)
|
|
@@ -959,7 +976,7 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|
|
959
976
|
description="This is a Prefix created for whole network.",
|
|
960
977
|
)
|
|
961
978
|
url = reverse("ipam-api:prefix-available-ips", kwargs={"pk": prefix.pk})
|
|
962
|
-
self.add_permissions("ipam.view_prefix", "ipam.view_ipaddress")
|
|
979
|
+
self.add_permissions("ipam.view_prefix", "ipam.view_ipaddress", "ipam.view_namespace", "extras.view_status")
|
|
963
980
|
self.add_permissions(
|
|
964
981
|
"ipam.add_ipaddress", constraints={"description__startswith": "This is the IP created for"}
|
|
965
982
|
)
|
|
@@ -1183,7 +1200,7 @@ class IPAddressTest(APIViewTestCases.APIViewTestCase):
|
|
|
1183
1200
|
|
|
1184
1201
|
def test_create_requires_parent_or_namespace(self):
|
|
1185
1202
|
"""Test that missing parent/namespace fields result in an error."""
|
|
1186
|
-
self.add_permissions("ipam.add_ipaddress")
|
|
1203
|
+
self.add_permissions("ipam.add_ipaddress", "extras.view_status")
|
|
1187
1204
|
data = {
|
|
1188
1205
|
"address": "192.168.0.10/32",
|
|
1189
1206
|
"status": self.statuses[0].pk,
|
|
@@ -1214,7 +1231,7 @@ class IPAddressTest(APIViewTestCases.APIViewTestCase):
|
|
|
1214
1231
|
def test_create_multiple_outside_nat_success(self):
|
|
1215
1232
|
"""Validate NAT inside address can tie to multiple NAT outside addresses."""
|
|
1216
1233
|
# Create the two outside NAT IP Addresses tied back to the single inside NAT address
|
|
1217
|
-
self.add_permissions("ipam.add_ipaddress", "ipam.view_ipaddress")
|
|
1234
|
+
self.add_permissions("ipam.add_ipaddress", "ipam.view_ipaddress", "ipam.view_namespace", "extras.view_status")
|
|
1218
1235
|
nat_inside = IPAddress.objects.filter(nat_outside_list__isnull=True).first()
|
|
1219
1236
|
# Create NAT outside with above address IP as inside NAT
|
|
1220
1237
|
ip1 = self.client.post(
|
|
@@ -1251,7 +1268,9 @@ class IPAddressTest(APIViewTestCases.APIViewTestCase):
|
|
|
1251
1268
|
self.assertEqual(response.data["nat_outside_list"][1]["address"], "192.168.0.20/24")
|
|
1252
1269
|
|
|
1253
1270
|
def test_creating_ipaddress_with_an_invalid_parent(self):
|
|
1254
|
-
self.add_permissions(
|
|
1271
|
+
self.add_permissions(
|
|
1272
|
+
"ipam.add_ipaddress", "extras.view_status", "ipam.view_prefix", "ipam.view_ipaddress", "ipam.view_namespace"
|
|
1273
|
+
)
|
|
1255
1274
|
prefixes = (
|
|
1256
1275
|
Prefix.objects.create(prefix="10.0.0.0/8", status=self.statuses[0], namespace=self.namespace),
|
|
1257
1276
|
Prefix.objects.create(prefix="192.168.0.0/25", status=self.statuses[0], namespace=self.namespace),
|
|
@@ -1403,6 +1422,8 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|
|
1403
1422
|
"ipam.view_vlangroup",
|
|
1404
1423
|
"ipam.view_vlan",
|
|
1405
1424
|
"ipam.add_vlan",
|
|
1425
|
+
"extras.view_status",
|
|
1426
|
+
"extras.view_customfield",
|
|
1406
1427
|
)
|
|
1407
1428
|
|
|
1408
1429
|
# Create all nine available VLANs with individual requests
|
|
@@ -1445,6 +1466,7 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|
|
1445
1466
|
"ipam.view_vlangroup",
|
|
1446
1467
|
"ipam.view_vlan",
|
|
1447
1468
|
"ipam.add_vlan",
|
|
1469
|
+
"extras.view_status",
|
|
1448
1470
|
)
|
|
1449
1471
|
|
|
1450
1472
|
# Try to create ten VLANs (only nine are available)
|
|
@@ -1492,6 +1514,7 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|
|
1492
1514
|
"ipam.view_vlangroup",
|
|
1493
1515
|
"ipam.view_vlan",
|
|
1494
1516
|
"ipam.add_vlan",
|
|
1517
|
+
"extras.view_status",
|
|
1495
1518
|
)
|
|
1496
1519
|
|
|
1497
1520
|
# Try to create VLANs with specified VLAN IDs. Also, explicitly (and redundantly) specify a VLAN Group.
|
|
@@ -1562,6 +1585,7 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|
|
1562
1585
|
self.add_permissions(
|
|
1563
1586
|
"ipam.view_vlangroup",
|
|
1564
1587
|
"ipam.view_vlan",
|
|
1588
|
+
"extras.view_status",
|
|
1565
1589
|
)
|
|
1566
1590
|
self.add_permissions("ipam.add_vlan", constraints={"description__startswith": "This is the VLAN created for"})
|
|
1567
1591
|
|
|
@@ -1609,6 +1633,7 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
|
|
1609
1633
|
self.add_permissions(
|
|
1610
1634
|
"ipam.view_vlangroup",
|
|
1611
1635
|
"ipam.view_vlan",
|
|
1636
|
+
"extras.view_status",
|
|
1612
1637
|
)
|
|
1613
1638
|
self.add_permissions("ipam.add_vlan", constraints={"description__startswith": "This is the VLAN created for"})
|
|
1614
1639
|
|
|
@@ -1714,9 +1739,14 @@ class VLANTest(APIViewTestCases.APIViewTestCase):
|
|
|
1714
1739
|
def test_vlan_2_1_api_version_response(self):
|
|
1715
1740
|
"""Assert location can be used in VLAN API create/retrieve."""
|
|
1716
1741
|
|
|
1717
|
-
self.add_permissions(
|
|
1718
|
-
|
|
1719
|
-
|
|
1742
|
+
self.add_permissions(
|
|
1743
|
+
"dcim.view_location",
|
|
1744
|
+
"ipam.view_vlan",
|
|
1745
|
+
"ipam.add_vlan",
|
|
1746
|
+
"ipam.change_vlan",
|
|
1747
|
+
"ipam.view_vlangroup",
|
|
1748
|
+
"extras.view_status",
|
|
1749
|
+
)
|
|
1720
1750
|
with self.subTest("Assert GET"):
|
|
1721
1751
|
vlan = VLAN.objects.annotate(locations_count=Count("locations")).filter(locations_count=1).first()
|
|
1722
1752
|
url = reverse("ipam-api:vlan-detail", kwargs={"pk": vlan.pk})
|
|
@@ -1878,7 +1908,7 @@ class ServiceTest(APIViewTestCases.APIViewTestCase):
|
|
|
1878
1908
|
|
|
1879
1909
|
Ref: https://github.com/nautobot/nautobot/issues/265
|
|
1880
1910
|
"""
|
|
1881
|
-
self.add_permissions("ipam.add_service")
|
|
1911
|
+
self.add_permissions("ipam.add_service", "dcim.view_device")
|
|
1882
1912
|
url = reverse("ipam-api:service-list")
|
|
1883
1913
|
device = self.devices[0]
|
|
1884
1914
|
|
|
@@ -1108,16 +1108,6 @@ class VRFDeviceAssignmentTestCase(FilterTestCases.FilterTestCase):
|
|
|
1108
1108
|
virtual_machine=cls.test_vm_2,
|
|
1109
1109
|
rd="65000:4",
|
|
1110
1110
|
)
|
|
1111
|
-
VRFDeviceAssignment.objects.create(
|
|
1112
|
-
vrf=cls.vrfs[0],
|
|
1113
|
-
virtual_device_context=cls.vdcs[0],
|
|
1114
|
-
name="VRFDeviceAssignment 1",
|
|
1115
|
-
rd="65000:5",
|
|
1116
|
-
)
|
|
1117
|
-
VRFDeviceAssignment.objects.create(
|
|
1118
|
-
vrf=cls.vrfs[0],
|
|
1119
|
-
virtual_device_context=cls.vdcs[1],
|
|
1120
|
-
)
|
|
1121
1111
|
|
|
1122
1112
|
|
|
1123
1113
|
class VLANGroupTestCase(FilterTestCases.FilterTestCase):
|
|
@@ -6,6 +6,7 @@ from django.db.models import Count
|
|
|
6
6
|
from django.test import override_settings
|
|
7
7
|
from django.urls import reverse
|
|
8
8
|
from django.utils.html import strip_tags
|
|
9
|
+
from django.utils.http import urlencode
|
|
9
10
|
from django.utils.timezone import make_aware
|
|
10
11
|
from netaddr import IPNetwork
|
|
11
12
|
|
|
@@ -145,6 +146,25 @@ class RIRTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
|
|
|
145
146
|
# Ensure that we have at least one RIR with no prefixes that can be used for the "delete_object" tests.
|
|
146
147
|
RIR.objects.create(name="RIR XYZ")
|
|
147
148
|
|
|
149
|
+
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
|
|
150
|
+
def test_list_objects_with_permission(self):
|
|
151
|
+
"""Test rendering of LinkedCountColumn for related fields without display_field override."""
|
|
152
|
+
response = super().test_list_objects_with_permission()
|
|
153
|
+
response_body = extract_page_body(response.content.decode(response.charset))
|
|
154
|
+
|
|
155
|
+
prefix_list_url = reverse(get_route_for_model(Prefix, "list"))
|
|
156
|
+
|
|
157
|
+
for rir in self._get_queryset().all():
|
|
158
|
+
if str(rir.pk) in response_body:
|
|
159
|
+
count = rir.prefixes.count()
|
|
160
|
+
if count > 1:
|
|
161
|
+
self.assertBodyContains(
|
|
162
|
+
response,
|
|
163
|
+
f'<a href="{prefix_list_url}?{urlencode({"rir": rir.name})}" class="badge">{count}</a>',
|
|
164
|
+
)
|
|
165
|
+
elif count == 1:
|
|
166
|
+
self.assertBodyContains(response, hyperlinked_object(rir.prefixes.first()))
|
|
167
|
+
|
|
148
168
|
|
|
149
169
|
class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase, ViewTestCases.ListObjectsViewTestCase):
|
|
150
170
|
model = Prefix
|
|
@@ -194,7 +214,7 @@ class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase, ViewTestCases.List
|
|
|
194
214
|
|
|
195
215
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=[])
|
|
196
216
|
def test_list_objects_with_permission(self):
|
|
197
|
-
"""Test rendering of LinkedCountColumn for related fields."""
|
|
217
|
+
"""Test rendering of LinkedCountColumn for related fields with display_field override."""
|
|
198
218
|
response = super().test_list_objects_with_permission()
|
|
199
219
|
response_body = extract_page_body(response.content.decode(response.charset))
|
|
200
220
|
|
|
@@ -208,7 +228,7 @@ class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase, ViewTestCases.List
|
|
|
208
228
|
response, f'<a href="{locations_list_url}?prefixes={prefix.pk}" class="badge">{count}</a>'
|
|
209
229
|
)
|
|
210
230
|
elif count == 1:
|
|
211
|
-
self.assertBodyContains(response, hyperlinked_object(prefix.locations.first()))
|
|
231
|
+
self.assertBodyContains(response, hyperlinked_object(prefix.locations.first(), "name"))
|
|
212
232
|
|
|
213
233
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
214
234
|
def test_empty_queryset(self):
|
|
@@ -1239,3 +1259,25 @@ class ServiceTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
1239
1259
|
}
|
|
1240
1260
|
response = self.client.post(**request)
|
|
1241
1261
|
self.assertBodyContains(response, "A service must be associated with either a device or a virtual machine.")
|
|
1262
|
+
|
|
1263
|
+
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
1264
|
+
def test_port_bulk_edit_invalid(self):
|
|
1265
|
+
self.add_permissions("ipam.change_service")
|
|
1266
|
+
url = self._get_url("bulk_edit")
|
|
1267
|
+
pk_list = list(self._get_queryset().values_list("pk", flat=True)[:3])
|
|
1268
|
+
|
|
1269
|
+
data = {
|
|
1270
|
+
"pk": pk_list,
|
|
1271
|
+
"protocol": ServiceProtocolChoices.PROTOCOL_UDP,
|
|
1272
|
+
"ports": "[106,107]", # String representation of the list
|
|
1273
|
+
"description": "New description",
|
|
1274
|
+
"_apply": True,
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
response = self.client.post(url, data)
|
|
1278
|
+
response_content = response.content.decode(response.charset)
|
|
1279
|
+
self.assertHttpStatus(response, 200)
|
|
1280
|
+
self.assertInHTML(
|
|
1281
|
+
' <strong class="panel-title">Ports</strong>: <ul class="errorlist"><li>invalid literal for int() with base 10: '[106'</li></ul>',
|
|
1282
|
+
response_content,
|
|
1283
|
+
)
|
nautobot/ipam/urls.py
CHANGED
|
@@ -7,7 +7,6 @@ from . import views
|
|
|
7
7
|
from .models import (
|
|
8
8
|
IPAddress,
|
|
9
9
|
Prefix,
|
|
10
|
-
Service,
|
|
11
10
|
VLAN,
|
|
12
11
|
VLANGroup,
|
|
13
12
|
)
|
|
@@ -17,27 +16,12 @@ app_name = "ipam"
|
|
|
17
16
|
router = NautobotUIViewSetRouter()
|
|
18
17
|
router.register("ip-address-to-interface", views.IPAddressToInterfaceUIViewSet)
|
|
19
18
|
router.register("namespaces", views.NamespaceUIViewSet)
|
|
19
|
+
router.register("rirs", views.RIRUIViewSet)
|
|
20
20
|
router.register("route-targets", views.RouteTargetUIViewSet)
|
|
21
|
+
router.register("services", views.ServiceUIViewSet)
|
|
21
22
|
router.register("vrfs", views.VRFUIViewSet)
|
|
22
|
-
router.register("rirs", views.RIRUIViewSet)
|
|
23
23
|
|
|
24
24
|
urlpatterns = [
|
|
25
|
-
# Namespaces
|
|
26
|
-
path(
|
|
27
|
-
"namespaces/<uuid:pk>/ip-addresses/",
|
|
28
|
-
views.NamespaceIPAddressesView.as_view(),
|
|
29
|
-
name="namespace_ipaddresses",
|
|
30
|
-
),
|
|
31
|
-
path(
|
|
32
|
-
"namespaces/<uuid:pk>/prefixes/",
|
|
33
|
-
views.NamespacePrefixesView.as_view(),
|
|
34
|
-
name="namespace_prefixes",
|
|
35
|
-
),
|
|
36
|
-
path(
|
|
37
|
-
"namespaces/<uuid:pk>/vrfs/",
|
|
38
|
-
views.NamespaceVRFsView.as_view(),
|
|
39
|
-
name="namespace_vrfs",
|
|
40
|
-
),
|
|
41
25
|
# Prefixes
|
|
42
26
|
path("prefixes/", views.PrefixListView.as_view(), name="prefix_list"),
|
|
43
27
|
path("prefixes/add/", views.PrefixEditView.as_view(), name="prefix_add"),
|
|
@@ -222,35 +206,6 @@ urlpatterns = [
|
|
|
222
206
|
name="vlan_notes",
|
|
223
207
|
kwargs={"model": VLAN},
|
|
224
208
|
),
|
|
225
|
-
# Services
|
|
226
|
-
path("services/", views.ServiceListView.as_view(), name="service_list"),
|
|
227
|
-
path("services/add/", views.ServiceEditView.as_view(), name="service_add"),
|
|
228
|
-
path("services/import/", views.ServiceBulkImportView.as_view(), name="service_import"), # 3.0 TODO: remove, unused
|
|
229
|
-
path("services/edit/", views.ServiceBulkEditView.as_view(), name="service_bulk_edit"),
|
|
230
|
-
path(
|
|
231
|
-
"services/delete/",
|
|
232
|
-
views.ServiceBulkDeleteView.as_view(),
|
|
233
|
-
name="service_bulk_delete",
|
|
234
|
-
),
|
|
235
|
-
path("services/<uuid:pk>/", views.ServiceView.as_view(), name="service"),
|
|
236
|
-
path("services/<uuid:pk>/edit/", views.ServiceEditView.as_view(), name="service_edit"),
|
|
237
|
-
path(
|
|
238
|
-
"services/<uuid:pk>/delete/",
|
|
239
|
-
views.ServiceDeleteView.as_view(),
|
|
240
|
-
name="service_delete",
|
|
241
|
-
),
|
|
242
|
-
path(
|
|
243
|
-
"services/<uuid:pk>/changelog/",
|
|
244
|
-
ObjectChangeLogView.as_view(),
|
|
245
|
-
name="service_changelog",
|
|
246
|
-
kwargs={"model": Service},
|
|
247
|
-
),
|
|
248
|
-
path(
|
|
249
|
-
"services/<uuid:pk>/notes/",
|
|
250
|
-
ObjectNotesView.as_view(),
|
|
251
|
-
name="service_notes",
|
|
252
|
-
kwargs={"model": Service},
|
|
253
|
-
),
|
|
254
209
|
]
|
|
255
210
|
|
|
256
211
|
urlpatterns += router.urls
|