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
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"""Utilities for testing IPAM functionality, including data migrations."""
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
|
|
5
|
+
from django.apps import apps
|
|
6
|
+
from netaddr import IPNetwork
|
|
7
|
+
|
|
8
|
+
# Calculate the probabilities to use for the maybe_subdivide() function defined below.
|
|
9
|
+
|
|
10
|
+
# Frequency of IPv4 (leaf, network) Prefixes by each given mask length in a "realistic" data set.
|
|
11
|
+
# Based loosely on a survey of one large real-world deployment's IP space usage
|
|
12
|
+
FREQUENCY_BY_MASK_LENGTH = [
|
|
13
|
+
0, # /0
|
|
14
|
+
0,
|
|
15
|
+
0,
|
|
16
|
+
0,
|
|
17
|
+
0, # /4
|
|
18
|
+
0,
|
|
19
|
+
0,
|
|
20
|
+
0,
|
|
21
|
+
0, # /8
|
|
22
|
+
0,
|
|
23
|
+
0,
|
|
24
|
+
0,
|
|
25
|
+
0, # /12
|
|
26
|
+
1,
|
|
27
|
+
2,
|
|
28
|
+
4,
|
|
29
|
+
16, # /16
|
|
30
|
+
8,
|
|
31
|
+
12,
|
|
32
|
+
16,
|
|
33
|
+
20, # /20
|
|
34
|
+
120,
|
|
35
|
+
150,
|
|
36
|
+
400,
|
|
37
|
+
5000, # /24
|
|
38
|
+
13000,
|
|
39
|
+
16000,
|
|
40
|
+
19000,
|
|
41
|
+
17000, # /28
|
|
42
|
+
16000,
|
|
43
|
+
32000,
|
|
44
|
+
4000,
|
|
45
|
+
1200, # /32
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
# Amount of IP space needed at each mask length (frequency at this length, plus the rollup of subdivided nets)
|
|
49
|
+
# Start calculation from the /32 frequency:
|
|
50
|
+
CUMULATIVE_BY_MASK_LENGTH = [FREQUENCY_BY_MASK_LENGTH[-1]]
|
|
51
|
+
# Then work backwards to each parent mask length
|
|
52
|
+
for mask_len in range(len(FREQUENCY_BY_MASK_LENGTH) - 2, -1, -1): # 31, ... 0
|
|
53
|
+
CUMULATIVE_BY_MASK_LENGTH.append(CUMULATIVE_BY_MASK_LENGTH[-1] // 2 + FREQUENCY_BY_MASK_LENGTH[mask_len])
|
|
54
|
+
# Reverse the list to get order by ascending prefix length, same as FREQUENCY_BY_MASK_LENGTH
|
|
55
|
+
CUMULATIVE_BY_MASK_LENGTH.reverse()
|
|
56
|
+
|
|
57
|
+
# Chance to stop subdividing at any given prefix length and create a network Prefix with this length
|
|
58
|
+
CHANCE_TO_STOP = [
|
|
59
|
+
0 if not cumulative else frequency / cumulative
|
|
60
|
+
for frequency, cumulative in zip(FREQUENCY_BY_MASK_LENGTH, CUMULATIVE_BY_MASK_LENGTH)
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def maybe_subdivide(network):
|
|
65
|
+
"""
|
|
66
|
+
Generator for recursively and probabilistically subdividing a network into subnets.
|
|
67
|
+
|
|
68
|
+
Yields:
|
|
69
|
+
IPNetwork: each constructed subdivision of the given network
|
|
70
|
+
"""
|
|
71
|
+
if random.random() < CHANCE_TO_STOP[network.prefixlen]: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
72
|
+
# Do not subdivide any further
|
|
73
|
+
yield network
|
|
74
|
+
else:
|
|
75
|
+
# Split it into its two child networks and recurse
|
|
76
|
+
subnets = network.subnet(network.prefixlen + 1)
|
|
77
|
+
for subnet in subnets:
|
|
78
|
+
yield from maybe_subdivide(subnet)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def maybe_random_instance(queryset, chance_of_none=0.75):
|
|
82
|
+
"""
|
|
83
|
+
Helper function - randomly return either a random instance of the given queryset or None.
|
|
84
|
+
"""
|
|
85
|
+
if random.random() < chance_of_none: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
86
|
+
return None
|
|
87
|
+
return random.choice(queryset) # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def create_prefixes_and_ips(initial_subnet: str, apps=apps, seed="Nautobot"): # pylint: disable=redefined-outer-name
|
|
91
|
+
"""
|
|
92
|
+
Create many (Nautobot 1.x) Prefix and IPAddress records under a given initial_subnet.
|
|
93
|
+
|
|
94
|
+
The specific records created are pseudo-random (consistent for any given `initial_subnet` and `seed` values),
|
|
95
|
+
but will *in general* consist of about 95% coverage of the subnet by non-overlapping Prefix partitions and about
|
|
96
|
+
5% coverage of the subnet by individual IPAddress records. Additionally, about 10% of Prefixes and IPAddresses
|
|
97
|
+
respectively will be duplicated one or more times.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
initial_subnet (str): The parent subnet ("10.0.0.0/16") that will encompass the Prefix and IPAddress records.
|
|
101
|
+
apps: Django application registry containing definitions of the (historical) Prefix, IPAddress, etc. models.
|
|
102
|
+
seed: Random generator seed to ensure reproducible pseudo-random construction of the data.
|
|
103
|
+
"""
|
|
104
|
+
IPAddress = apps.get_model("ipam", "IPAddress")
|
|
105
|
+
Prefix = apps.get_model("ipam", "Prefix")
|
|
106
|
+
Status = apps.get_model("extras", "Status")
|
|
107
|
+
Tenant = apps.get_model("tenancy", "Tenant")
|
|
108
|
+
VRF = apps.get_model("ipam", "VRF")
|
|
109
|
+
|
|
110
|
+
print(f"Seeding the PRNG with seed {seed}")
|
|
111
|
+
random.seed(seed) # suspicious-non-cryptographic-random-usage
|
|
112
|
+
|
|
113
|
+
status_active, _ = Status.objects.get_or_create(name="Active", defaults={"slug": "active"})
|
|
114
|
+
|
|
115
|
+
for i in range(1, 11):
|
|
116
|
+
Tenant.objects.create(name=f"{initial_subnet} Tenant {i}")
|
|
117
|
+
VRF.objects.create(name=f"{initial_subnet} VRF {i}", enforce_unique=False) # TODO should some enforce_unique?
|
|
118
|
+
|
|
119
|
+
all_tenants = list(Tenant.objects.all())
|
|
120
|
+
all_vrfs = list(VRF.objects.all())
|
|
121
|
+
|
|
122
|
+
print(f"Creating Prefixes to subdivide {initial_subnet}")
|
|
123
|
+
unique_prefix_count = 0
|
|
124
|
+
duplicate_prefix_count = 0
|
|
125
|
+
for subnet in maybe_subdivide(IPNetwork(initial_subnet)):
|
|
126
|
+
if random.random() < 0.95: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
127
|
+
# 95% chance to create any given Prefix
|
|
128
|
+
Prefix.objects.create(
|
|
129
|
+
network=str(subnet.network),
|
|
130
|
+
broadcast=str(subnet.broadcast if subnet.broadcast else subnet[-1]),
|
|
131
|
+
prefix_length=subnet.prefixlen,
|
|
132
|
+
status=status_active,
|
|
133
|
+
tenant=maybe_random_instance(all_tenants),
|
|
134
|
+
vrf=maybe_random_instance(all_vrfs),
|
|
135
|
+
)
|
|
136
|
+
unique_prefix_count += 1
|
|
137
|
+
while random.random() < 0.1: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
138
|
+
# 10% repeating chance to create a duplicate(s) of this Prefix
|
|
139
|
+
Prefix.objects.create(
|
|
140
|
+
network=str(subnet.network),
|
|
141
|
+
broadcast=str(subnet.broadcast if subnet.broadcast else subnet[-1]),
|
|
142
|
+
prefix_length=subnet.prefixlen,
|
|
143
|
+
status=status_active,
|
|
144
|
+
tenant=maybe_random_instance(all_tenants),
|
|
145
|
+
vrf=maybe_random_instance(all_vrfs),
|
|
146
|
+
)
|
|
147
|
+
duplicate_prefix_count += 1
|
|
148
|
+
print(f"Created {unique_prefix_count} unique Prefixes and {duplicate_prefix_count} duplicates")
|
|
149
|
+
|
|
150
|
+
print(f"Creating IPAddresses within {initial_subnet}")
|
|
151
|
+
unique_ip_count = 0
|
|
152
|
+
duplicate_ip_count = 0
|
|
153
|
+
for ip in IPNetwork(initial_subnet):
|
|
154
|
+
if random.random() < 0.05: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
155
|
+
# 5% chance to create any given IP address
|
|
156
|
+
network = IPNetwork(ip)
|
|
157
|
+
IPAddress.objects.create(
|
|
158
|
+
host=str(network.ip),
|
|
159
|
+
broadcast=str(network.broadcast if network.broadcast else network[-1]),
|
|
160
|
+
prefix_length=network.prefixlen,
|
|
161
|
+
status=status_active,
|
|
162
|
+
tenant=maybe_random_instance(all_tenants),
|
|
163
|
+
vrf=maybe_random_instance(all_vrfs),
|
|
164
|
+
)
|
|
165
|
+
unique_ip_count += 1
|
|
166
|
+
while random.random() < 0.1: # noqa: S311 # suspicious-non-cryptographic-random-usage
|
|
167
|
+
# 10% repeating chance to create a duplicate(s) of this IP
|
|
168
|
+
IPAddress.objects.create(
|
|
169
|
+
host=str(network.ip),
|
|
170
|
+
broadcast=str(network.broadcast if network.broadcast else network[-1]),
|
|
171
|
+
prefix_length=network.prefixlen,
|
|
172
|
+
status=status_active,
|
|
173
|
+
tenant=maybe_random_instance(all_tenants),
|
|
174
|
+
vrf=maybe_random_instance(all_vrfs),
|
|
175
|
+
)
|
|
176
|
+
duplicate_ip_count += 1
|
|
177
|
+
print(f"Created {unique_ip_count} unique IPAddresses and {duplicate_ip_count} duplicates")
|
nautobot/ipam/views.py
CHANGED
|
@@ -16,6 +16,8 @@ from django.utils.http import urlencode
|
|
|
16
16
|
from django.views.generic import View
|
|
17
17
|
from django_tables2 import RequestConfig
|
|
18
18
|
import netaddr
|
|
19
|
+
from rest_framework.decorators import action
|
|
20
|
+
from rest_framework.response import Response
|
|
19
21
|
|
|
20
22
|
from nautobot.cloud.tables import CloudNetworkTable
|
|
21
23
|
from nautobot.core.constants import MAX_PAGE_SIZE_DEFAULT
|
|
@@ -63,27 +65,7 @@ logger = logging.getLogger(__name__)
|
|
|
63
65
|
#
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
"""Return counts of all IPAM objects related to the given Namespace."""
|
|
68
|
-
return {
|
|
69
|
-
"vrf_count": instance.vrfs.restrict(request.user, "view").count(),
|
|
70
|
-
"prefix_count": instance.prefixes.restrict(request.user, "view").count(),
|
|
71
|
-
"ip_address_count": instance.ip_addresses.restrict(request.user, "view").count(),
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class NamespaceUIViewSet(
|
|
76
|
-
view_mixins.ObjectDetailViewMixin,
|
|
77
|
-
view_mixins.ObjectListViewMixin,
|
|
78
|
-
view_mixins.ObjectEditViewMixin,
|
|
79
|
-
view_mixins.ObjectDestroyViewMixin,
|
|
80
|
-
view_mixins.ObjectChangeLogViewMixin,
|
|
81
|
-
view_mixins.ObjectBulkCreateViewMixin, # 3.0 TODO: remove, no longer used
|
|
82
|
-
view_mixins.ObjectBulkDestroyViewMixin,
|
|
83
|
-
view_mixins.ObjectBulkUpdateViewMixin,
|
|
84
|
-
view_mixins.ObjectNotesViewMixin,
|
|
85
|
-
):
|
|
86
|
-
lookup_field = "pk"
|
|
68
|
+
class NamespaceUIViewSet(NautobotUIViewSet):
|
|
87
69
|
form_class = forms.NamespaceForm
|
|
88
70
|
bulk_update_form_class = forms.NamespaceBulkEditForm
|
|
89
71
|
filterset_class = filters.NamespaceFilterSet
|
|
@@ -91,134 +73,95 @@ class NamespaceUIViewSet(
|
|
|
91
73
|
queryset = Namespace.objects.all()
|
|
92
74
|
serializer_class = serializers.NamespaceSerializer
|
|
93
75
|
table_class = tables.NamespaceTable
|
|
76
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
77
|
+
panels=(object_detail.ObjectFieldsPanel(section=SectionChoices.LEFT_HALF, weight=100, fields="__all__"),),
|
|
78
|
+
extra_tabs=(
|
|
79
|
+
object_detail.DistinctViewTab(
|
|
80
|
+
weight=800,
|
|
81
|
+
tab_id="vrfs",
|
|
82
|
+
label="VRFs",
|
|
83
|
+
url_name="ipam:namespace_vrfs",
|
|
84
|
+
related_object_attribute="vrfs",
|
|
85
|
+
),
|
|
86
|
+
object_detail.DistinctViewTab(
|
|
87
|
+
weight=900,
|
|
88
|
+
tab_id="prefixes",
|
|
89
|
+
label="Prefixes",
|
|
90
|
+
url_name="ipam:namespace_prefixes",
|
|
91
|
+
related_object_attribute="prefixes",
|
|
92
|
+
),
|
|
93
|
+
object_detail.DistinctViewTab(
|
|
94
|
+
weight=1000,
|
|
95
|
+
tab_id="ip_addresses",
|
|
96
|
+
label="IP Addresses",
|
|
97
|
+
url_name="ipam:namespace_ip_addresses",
|
|
98
|
+
related_object_attribute="ip_addresses",
|
|
99
|
+
),
|
|
100
|
+
),
|
|
101
|
+
)
|
|
94
102
|
|
|
95
103
|
def get_extra_context(self, request, instance):
|
|
96
104
|
context = super().get_extra_context(request, instance)
|
|
97
|
-
|
|
98
|
-
if self.action == "retrieve":
|
|
99
|
-
context.update(get_namespace_related_counts(instance, request))
|
|
100
|
-
|
|
105
|
+
context.update({"object_detail_content": self.object_detail_content})
|
|
101
106
|
return context
|
|
102
107
|
|
|
108
|
+
@action(detail=True, url_path="vrfs")
|
|
109
|
+
def vrfs(self, request, *args, **kwargs):
|
|
110
|
+
instance = self.get_object()
|
|
111
|
+
vrfs = instance.vrfs.restrict(request.user, "view")
|
|
112
|
+
vrf_table = tables.VRFTable(
|
|
113
|
+
data=vrfs,
|
|
114
|
+
user=request.user,
|
|
115
|
+
exclude=["namespace"],
|
|
116
|
+
)
|
|
117
|
+
if request.user.has_perm("ipam.change_vrf") or request.user.has_perm("ipam.delete_vrf"):
|
|
118
|
+
vrf_table.columns.show("pk")
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def get_extra_context(self, request, instance):
|
|
109
|
-
# Find all IPAddresses belonging to this Namespace
|
|
110
|
-
ip_addresses = instance.ip_addresses.restrict(request.user, "view").select_related("role", "status", "tenant")
|
|
111
|
-
|
|
112
|
-
ip_address_table = tables.IPAddressTable(ip_addresses, exclude=["namespace"])
|
|
113
|
-
if request.user.has_perm("ipam.change_ipaddress") or request.user.has_perm("ipam.delete_ipaddress"):
|
|
114
|
-
ip_address_table.columns.show("pk")
|
|
115
|
-
|
|
116
|
-
paginate = {
|
|
117
|
-
"paginator_class": EnhancedPaginator,
|
|
118
|
-
"per_page": get_paginate_count(request),
|
|
119
|
-
}
|
|
120
|
-
RequestConfig(request, paginate).configure(ip_address_table)
|
|
121
|
-
|
|
122
|
-
# Compile permissions list for rendering the object table
|
|
123
|
-
permissions = {
|
|
124
|
-
"add": request.user.has_perm("ipam.add_ipaddress"),
|
|
125
|
-
"change": request.user.has_perm("ipam.change_ipaddress"),
|
|
126
|
-
"delete": request.user.has_perm("ipam.delete_ipaddress"),
|
|
127
|
-
}
|
|
128
|
-
bulk_querystring = f"namespace={instance.id}"
|
|
129
|
-
|
|
130
|
-
context = super().get_extra_context(request, instance)
|
|
131
|
-
context.update(
|
|
120
|
+
RequestConfig(
|
|
121
|
+
request, paginate={"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
122
|
+
).configure(vrf_table)
|
|
123
|
+
return Response(
|
|
132
124
|
{
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"bulk_querystring": bulk_querystring,
|
|
136
|
-
"active_tab": "ip-addresses",
|
|
125
|
+
"vrf_table": vrf_table,
|
|
126
|
+
"active_tab": "vrfs",
|
|
137
127
|
}
|
|
138
128
|
)
|
|
139
|
-
context.update(get_namespace_related_counts(instance, request))
|
|
140
|
-
|
|
141
|
-
return context
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class NamespacePrefixesView(generic.ObjectView):
|
|
145
|
-
queryset = Namespace.objects.all()
|
|
146
|
-
template_name = "ipam/namespace_prefixes.html"
|
|
147
129
|
|
|
148
|
-
|
|
149
|
-
|
|
130
|
+
@action(detail=True, url_path="prefixes")
|
|
131
|
+
def prefixes(self, request, *args, **kwargs):
|
|
132
|
+
instance = self.get_object()
|
|
150
133
|
prefixes = instance.prefixes.restrict(request.user, "view").select_related("status")
|
|
151
|
-
|
|
152
|
-
prefix_table = tables.PrefixTable(prefixes, exclude=["namespace"])
|
|
134
|
+
prefix_table = tables.PrefixTable(data=prefixes, user=request.user, exclude=["namespace"])
|
|
153
135
|
if request.user.has_perm("ipam.change_prefix") or request.user.has_perm("ipam.delete_prefix"):
|
|
154
136
|
prefix_table.columns.show("pk")
|
|
155
137
|
|
|
156
|
-
|
|
157
|
-
"paginator_class": EnhancedPaginator,
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
RequestConfig(request, paginate).configure(prefix_table)
|
|
161
|
-
|
|
162
|
-
# Compile permissions list for rendering the object table
|
|
163
|
-
permissions = {
|
|
164
|
-
"add": request.user.has_perm("ipam.add_prefix"),
|
|
165
|
-
"change": request.user.has_perm("ipam.change_prefix"),
|
|
166
|
-
"delete": request.user.has_perm("ipam.delete_prefix"),
|
|
167
|
-
}
|
|
168
|
-
bulk_querystring = f"namespace={instance.id}"
|
|
169
|
-
|
|
170
|
-
context = super().get_extra_context(request, instance)
|
|
171
|
-
context.update(
|
|
138
|
+
RequestConfig(
|
|
139
|
+
request, paginate={"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
140
|
+
).configure(prefix_table)
|
|
141
|
+
return Response(
|
|
172
142
|
{
|
|
173
143
|
"prefix_table": prefix_table,
|
|
174
|
-
"permissions": permissions,
|
|
175
|
-
"bulk_querystring": bulk_querystring,
|
|
176
144
|
"active_tab": "prefixes",
|
|
177
145
|
}
|
|
178
146
|
)
|
|
179
|
-
context.update(get_namespace_related_counts(instance, request))
|
|
180
|
-
|
|
181
|
-
return context
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
class NamespaceVRFsView(generic.ObjectView):
|
|
185
|
-
queryset = Namespace.objects.all()
|
|
186
|
-
template_name = "ipam/namespace_vrfs.html"
|
|
187
|
-
|
|
188
|
-
def get_extra_context(self, request, instance):
|
|
189
|
-
# Find all VRFs belonging to this Namespace
|
|
190
|
-
vrfs = instance.vrfs.restrict(request.user, "view")
|
|
191
|
-
|
|
192
|
-
vrf_table = tables.VRFTable(vrfs, exclude=["namespace"])
|
|
193
|
-
if request.user.has_perm("ipam.change_vrf") or request.user.has_perm("ipam.delete_vrf"):
|
|
194
|
-
vrf_table.columns.show("pk")
|
|
195
147
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
permissions = {
|
|
204
|
-
"add": request.user.has_perm("ipam.add_vrf"),
|
|
205
|
-
"change": request.user.has_perm("ipam.change_vrf"),
|
|
206
|
-
"delete": request.user.has_perm("ipam.delete_vrf"),
|
|
207
|
-
}
|
|
208
|
-
bulk_querystring = f"namespace={instance.id}"
|
|
148
|
+
@action(detail=True, url_path="ip-addresses", url_name="ip_addresses")
|
|
149
|
+
def ip_addresses(self, request, *args, **kwargs):
|
|
150
|
+
instance = self.get_object()
|
|
151
|
+
ip_addresses = instance.ip_addresses.restrict(request.user, "view").select_related("role", "status", "tenant")
|
|
152
|
+
ip_address_table = tables.IPAddressTable(data=ip_addresses, user=request.user, exclude=["namespace"])
|
|
153
|
+
if request.user.has_perm("ipam.change_ipaddress") or request.user.has_perm("ipam.delete_ipaddress"):
|
|
154
|
+
ip_address_table.columns.show("pk")
|
|
209
155
|
|
|
210
|
-
|
|
211
|
-
|
|
156
|
+
RequestConfig(
|
|
157
|
+
request, paginate={"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
158
|
+
).configure(ip_address_table)
|
|
159
|
+
return Response(
|
|
212
160
|
{
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"bulk_querystring": bulk_querystring,
|
|
216
|
-
"active_tab": "vrfs",
|
|
161
|
+
"ip_address_table": ip_address_table,
|
|
162
|
+
"active_tab": "ip_addresses",
|
|
217
163
|
}
|
|
218
164
|
)
|
|
219
|
-
context.update(get_namespace_related_counts(instance, request))
|
|
220
|
-
|
|
221
|
-
return context
|
|
222
165
|
|
|
223
166
|
|
|
224
167
|
#
|
|
@@ -1356,19 +1299,7 @@ class VLANBulkDeleteView(generic.BulkDeleteView):
|
|
|
1356
1299
|
#
|
|
1357
1300
|
|
|
1358
1301
|
|
|
1359
|
-
class
|
|
1360
|
-
queryset = Service.objects.all()
|
|
1361
|
-
filterset = filters.ServiceFilterSet
|
|
1362
|
-
filterset_form = forms.ServiceFilterForm
|
|
1363
|
-
table = tables.ServiceTable
|
|
1364
|
-
action_buttons = ("add", "import", "export")
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
class ServiceView(generic.ObjectView):
|
|
1368
|
-
queryset = Service.objects.prefetch_related("ip_addresses")
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
class ServiceEditView(generic.ObjectEditView):
|
|
1302
|
+
class ServiceEditView(generic.ObjectEditView): # This view is used to assign services to devices and VMs
|
|
1372
1303
|
queryset = Service.objects.prefetch_related("ip_addresses")
|
|
1373
1304
|
model_form = forms.ServiceForm
|
|
1374
1305
|
template_name = "ipam/service_edit.html"
|
|
@@ -1384,23 +1315,30 @@ class ServiceEditView(generic.ObjectEditView):
|
|
|
1384
1315
|
return obj
|
|
1385
1316
|
|
|
1386
1317
|
|
|
1387
|
-
class
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
queryset = Service.objects.
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
class ServiceBulkEditView(generic.BulkEditView):
|
|
1397
|
-
queryset = Service.objects.select_related("device", "virtual_machine")
|
|
1398
|
-
filterset = filters.ServiceFilterSet
|
|
1399
|
-
table = tables.ServiceTable
|
|
1400
|
-
form = forms.ServiceBulkEditForm
|
|
1401
|
-
|
|
1318
|
+
class ServiceUIViewSet(NautobotUIViewSet): # 3.0 TODO: remove, unused BulkImportView
|
|
1319
|
+
model = Service
|
|
1320
|
+
bulk_update_form_class = forms.ServiceBulkEditForm
|
|
1321
|
+
filterset_class = filters.ServiceFilterSet
|
|
1322
|
+
filterset_form_class = forms.ServiceFilterForm
|
|
1323
|
+
form_class = forms.ServiceForm
|
|
1324
|
+
queryset = Service.objects.select_related("device", "virtual_machine").prefetch_related("ip_addresses")
|
|
1325
|
+
serializer_class = serializers.ServiceSerializer
|
|
1326
|
+
table_class = tables.ServiceTable
|
|
1402
1327
|
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1328
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
1329
|
+
panels=(
|
|
1330
|
+
object_detail.ObjectFieldsPanel(
|
|
1331
|
+
section=SectionChoices.LEFT_HALF,
|
|
1332
|
+
weight=100,
|
|
1333
|
+
fields=["name", "parent", "protocol", "port_list", "description"],
|
|
1334
|
+
),
|
|
1335
|
+
object_detail.ObjectsTablePanel(
|
|
1336
|
+
weight=200,
|
|
1337
|
+
section=SectionChoices.RIGHT_HALF,
|
|
1338
|
+
table_class=tables.IPAddressTable,
|
|
1339
|
+
table_filter="services",
|
|
1340
|
+
select_related_fields=["tenant", "status", "role"],
|
|
1341
|
+
add_button_route=None,
|
|
1342
|
+
),
|
|
1343
|
+
)
|
|
1344
|
+
)
|
|
@@ -890,6 +890,11 @@ td span.hover_copy:hover .hover_copy_button {
|
|
|
890
890
|
cursor: move;
|
|
891
891
|
}
|
|
892
892
|
|
|
893
|
+
/* Make text in homepage panels selectable */
|
|
894
|
+
#draggable-homepage-panels .list-group-item {
|
|
895
|
+
user-select: text !important;
|
|
896
|
+
}
|
|
897
|
+
|
|
893
898
|
/* Make panel being dragged opaque */
|
|
894
899
|
.dragging {
|
|
895
900
|
opacity: 0.5;
|
|
@@ -9338,8 +9338,6 @@
|
|
|
9338
9338
|
|
|
9339
9339
|
<script src="../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9340
9340
|
|
|
9341
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9342
|
-
|
|
9343
9341
|
|
|
9344
9342
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9345
9343
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9271,8 +9271,6 @@
|
|
|
9271
9271
|
|
|
9272
9272
|
<script src="../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9273
9273
|
|
|
9274
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9275
|
-
|
|
9276
9274
|
|
|
9277
9275
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9278
9276
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9539,8 +9539,6 @@ Relationships, etc.</p>
|
|
|
9539
9539
|
|
|
9540
9540
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9541
9541
|
|
|
9542
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9543
|
-
|
|
9544
9542
|
|
|
9545
9543
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9546
9544
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9407,8 +9407,6 @@
|
|
|
9407
9407
|
|
|
9408
9408
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9409
9409
|
|
|
9410
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9411
|
-
|
|
9412
9410
|
|
|
9413
9411
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9414
9412
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -13563,8 +13563,6 @@ data any serializer fields that do not correspond to a specific model field</p>
|
|
|
13563
13563
|
|
|
13564
13564
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
13565
13565
|
|
|
13566
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
13567
|
-
|
|
13568
13566
|
|
|
13569
13567
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
13570
13568
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9839,8 +9839,6 @@ with web_request_context(user, context_detail="manual-fix"):
|
|
|
9839
9839
|
|
|
9840
9840
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9841
9841
|
|
|
9842
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9843
|
-
|
|
9844
9842
|
|
|
9845
9843
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9846
9844
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9924,8 +9924,6 @@ is equivalent to a Celery task state.</p>
|
|
|
9924
9924
|
|
|
9925
9925
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9926
9926
|
|
|
9927
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9928
|
-
|
|
9929
9927
|
|
|
9930
9928
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9931
9929
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9382,8 +9382,6 @@ and will generate warning logs.</p>
|
|
|
9382
9382
|
|
|
9383
9383
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9384
9384
|
|
|
9385
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9386
|
-
|
|
9387
9385
|
|
|
9388
9386
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9389
9387
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9307,8 +9307,6 @@
|
|
|
9307
9307
|
|
|
9308
9308
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9309
9309
|
|
|
9310
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9311
|
-
|
|
9312
9310
|
|
|
9313
9311
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9314
9312
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9586,8 +9586,6 @@ Returns:
|
|
|
9586
9586
|
|
|
9587
9587
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9588
9588
|
|
|
9589
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9590
|
-
|
|
9591
9589
|
|
|
9592
9590
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9593
9591
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9949,8 +9949,6 @@ EventBrokers, then call <code>register_event_broker()</code> for each one, as pa
|
|
|
9949
9949
|
|
|
9950
9950
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9951
9951
|
|
|
9952
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9953
|
-
|
|
9954
9952
|
|
|
9955
9953
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9956
9954
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -9797,8 +9797,6 @@ would trigger this exception upon access.</p>
|
|
|
9797
9797
|
|
|
9798
9798
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
9799
9799
|
|
|
9800
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
9801
|
-
|
|
9802
9800
|
|
|
9803
9801
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
9804
9802
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -10045,8 +10045,6 @@ status = random_instance(lambda: Status.objects.get_for_model(Object), allow_nul
|
|
|
10045
10045
|
|
|
10046
10046
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
10047
10047
|
|
|
10048
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
10049
|
-
|
|
10050
10048
|
|
|
10051
10049
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
10052
10050
|
document$.subscribe(() => { lightbox.reload() });
|
|
@@ -11539,8 +11539,6 @@ filter values while maintaining the field's built-in validation. Example: GET /a
|
|
|
11539
11539
|
|
|
11540
11540
|
<script src="../../../assets/javascripts/bundle.60a45f97.min.js"></script>
|
|
11541
11541
|
|
|
11542
|
-
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
11543
|
-
|
|
11544
11542
|
|
|
11545
11543
|
<script id="init-glightbox">const lightbox = GLightbox({"touchNavigation": true, "loop": false, "zoomable": true, "draggable": true, "openEffect": "zoom", "closeEffect": "zoom", "slideEffect": "slide"});
|
|
11546
11544
|
document$.subscribe(() => { lightbox.reload() });
|