nautobot 2.4.0b1__py3-none-any.whl → 2.4.2__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/__init__.py +1 -1
- nautobot/apps/api.py +8 -8
- nautobot/apps/change_logging.py +2 -2
- nautobot/apps/choices.py +4 -4
- nautobot/apps/events.py +3 -3
- nautobot/apps/factory.py +2 -2
- nautobot/apps/filters.py +1 -1
- nautobot/apps/forms.py +20 -20
- nautobot/apps/graphql.py +2 -2
- nautobot/apps/jobs.py +8 -8
- nautobot/apps/models.py +19 -19
- nautobot/apps/tables.py +1 -1
- nautobot/apps/testing.py +10 -10
- nautobot/apps/ui.py +2 -2
- nautobot/apps/utils.py +7 -7
- nautobot/apps/views.py +7 -7
- nautobot/circuits/api/serializers.py +1 -0
- nautobot/circuits/api/views.py +4 -8
- nautobot/circuits/tables.py +2 -1
- nautobot/circuits/templates/circuits/circuit_create.html +1 -7
- nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +43 -0
- nautobot/circuits/tests/integration/test_relationships.py +1 -1
- nautobot/circuits/views.py +3 -3
- nautobot/cloud/api/views.py +6 -10
- nautobot/cloud/models.py +1 -1
- nautobot/cloud/views.py +0 -16
- nautobot/core/api/constants.py +11 -0
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/filter_backends.py +3 -9
- nautobot/core/api/schema.py +13 -2
- nautobot/core/api/serializers.py +40 -34
- nautobot/core/api/views.py +56 -4
- nautobot/core/apps/__init__.py +0 -5
- nautobot/core/celery/log.py +4 -4
- nautobot/core/celery/schedulers.py +2 -2
- nautobot/core/choices.py +2 -2
- nautobot/core/events/__init__.py +3 -3
- nautobot/core/filters.py +67 -35
- nautobot/core/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +14 -11
- nautobot/core/forms/forms.py +33 -2
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +28 -7
- nautobot/core/jobs/bulk_actions.py +285 -0
- nautobot/core/jobs/cleanup.py +48 -12
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/models/__init__.py +3 -1
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +6 -3
- nautobot/core/settings.py +29 -2
- nautobot/core/settings.yaml +21 -0
- nautobot/core/tables.py +79 -61
- nautobot/core/templates/about.html +67 -0
- nautobot/core/templates/generic/object_bulk_destroy.html +1 -1
- nautobot/core/templates/inc/media.html +3 -0
- nautobot/core/templates/inc/nav_menu.html +1 -0
- nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
- nautobot/core/templates/inc/tenant_table_row.html +11 -0
- nautobot/core/templates/nautobot_config.py.j2 +13 -0
- nautobot/core/templates/search.html +7 -0
- nautobot/core/templates/utilities/render_jinja2.html +1 -1
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +7 -0
- nautobot/core/templatetags/helpers.py +11 -2
- nautobot/core/testing/__init__.py +8 -8
- nautobot/core/testing/api.py +170 -15
- nautobot/core/testing/filters.py +45 -10
- nautobot/core/testing/forms.py +2 -0
- nautobot/core/testing/integration.py +514 -5
- nautobot/core/testing/mixins.py +7 -2
- nautobot/core/testing/views.py +44 -29
- nautobot/core/tests/integration/test_app_home.py +0 -1
- nautobot/core/tests/integration/test_app_navbar.py +0 -1
- nautobot/core/tests/integration/test_filters.py +0 -2
- nautobot/core/tests/integration/test_home.py +0 -1
- nautobot/core/tests/integration/test_navbar.py +0 -1
- nautobot/core/tests/integration/test_view_authentication.py +1 -0
- nautobot/core/tests/runner.py +1 -1
- nautobot/core/tests/test_api.py +98 -1
- nautobot/core/tests/test_csv.py +25 -3
- nautobot/core/tests/test_filters.py +209 -246
- nautobot/core/tests/test_forms.py +1 -0
- nautobot/core/tests/test_jobs.py +492 -1
- nautobot/core/tests/test_models.py +9 -0
- nautobot/core/tests/test_settings_schema.py +7 -0
- nautobot/core/tests/test_tables.py +100 -0
- nautobot/core/tests/test_utils.py +63 -1
- nautobot/core/tests/test_views.py +30 -3
- nautobot/core/ui/nav.py +1 -0
- nautobot/core/ui/object_detail.py +15 -1
- nautobot/core/urls.py +11 -0
- nautobot/core/utils/git.py +7 -2
- nautobot/core/utils/lookup.py +11 -8
- nautobot/core/utils/querysets.py +64 -0
- nautobot/core/utils/requests.py +24 -9
- nautobot/core/views/__init__.py +42 -0
- nautobot/core/views/generic.py +131 -197
- nautobot/core/views/mixins.py +136 -41
- nautobot/core/views/renderers.py +6 -6
- nautobot/core/views/utils.py +2 -2
- nautobot/dcim/api/serializers.py +56 -64
- nautobot/dcim/api/views.py +47 -113
- nautobot/dcim/constants.py +6 -13
- nautobot/dcim/factory.py +6 -1
- nautobot/dcim/filters/__init__.py +31 -2
- nautobot/dcim/forms.py +48 -17
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
- nautobot/dcim/models/__init__.py +1 -1
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +22 -20
- nautobot/dcim/models/devices.py +10 -1
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +6 -5
- nautobot/dcim/models/racks.py +4 -4
- nautobot/dcim/tables/__init__.py +3 -3
- nautobot/dcim/tables/devices.py +9 -6
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/tables/racks.py +1 -1
- nautobot/dcim/templates/dcim/cable.html +1 -1
- nautobot/dcim/templates/dcim/controller_create.html +1 -7
- nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
- nautobot/dcim/templates/dcim/device/base.html +1 -1
- nautobot/dcim/templates/dcim/device.html +3 -11
- nautobot/dcim/templates/dcim/device_component.html +1 -1
- nautobot/dcim/templates/dcim/device_edit.html +36 -37
- nautobot/dcim/templates/dcim/devicetype.html +1 -1
- nautobot/dcim/templates/dcim/location.html +2 -10
- nautobot/dcim/templates/dcim/location_edit.html +1 -7
- nautobot/dcim/templates/dcim/locationtype.html +1 -1
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/manufacturer.html +1 -1
- nautobot/dcim/templates/dcim/platform.html +1 -1
- nautobot/dcim/templates/dcim/powerfeed.html +1 -1
- nautobot/dcim/templates/dcim/powerpanel.html +1 -1
- nautobot/dcim/templates/dcim/rack.html +2 -10
- nautobot/dcim/templates/dcim/rack_edit.html +1 -7
- nautobot/dcim/templates/dcim/rackgroup.html +1 -1
- nautobot/dcim/templates/dcim/rackreservation.html +3 -11
- nautobot/dcim/templates/dcim/virtualchassis.html +1 -1
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
- nautobot/dcim/tests/integration/test_controller.py +62 -0
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
- nautobot/dcim/tests/integration/test_device_bulk_operations.py +30 -0
- nautobot/dcim/tests/integration/test_location_bulk_operations.py +43 -0
- nautobot/dcim/tests/test_api.py +16 -5
- nautobot/dcim/tests/test_filters.py +33 -0
- nautobot/dcim/tests/test_forms.py +51 -2
- nautobot/dcim/tests/test_graphql.py +52 -0
- nautobot/dcim/tests/test_jobs.py +118 -0
- nautobot/dcim/tests/test_models.py +52 -9
- nautobot/dcim/tests/test_views.py +30 -84
- nautobot/dcim/views.py +13 -28
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +123 -85
- nautobot/extras/api/views.py +33 -30
- nautobot/extras/constants.py +3 -0
- nautobot/extras/datasources/git.py +125 -0
- nautobot/extras/filters/__init__.py +8 -6
- nautobot/extras/forms/base.py +2 -2
- nautobot/extras/forms/forms.py +139 -31
- nautobot/extras/forms/mixins.py +14 -6
- nautobot/extras/group_sync.py +3 -3
- nautobot/extras/health_checks.py +1 -2
- nautobot/extras/jobs.py +85 -18
- nautobot/extras/managers.py +3 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
- nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
- nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
- nautobot/extras/migrations/0122_add_graphqlquery_owner_content_type.py +34 -0
- nautobot/extras/models/__init__.py +1 -1
- nautobot/extras/models/contacts.py +1 -1
- nautobot/extras/models/customfields.py +41 -23
- nautobot/extras/models/datasources.py +85 -0
- nautobot/extras/models/groups.py +11 -9
- nautobot/extras/models/jobs.py +23 -4
- nautobot/extras/models/models.py +17 -2
- nautobot/extras/models/relationships.py +17 -5
- nautobot/extras/plugins/__init__.py +13 -2
- nautobot/extras/plugins/marketplace_manifest.yml +84 -79
- nautobot/extras/plugins/tables.py +16 -14
- nautobot/extras/plugins/views.py +65 -69
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/signals.py +15 -1
- nautobot/extras/tables.py +7 -5
- nautobot/extras/templates/extras/computedfield.html +1 -1
- nautobot/extras/templates/extras/configcontext.html +1 -1
- nautobot/extras/templates/extras/configcontextschema.html +1 -1
- nautobot/extras/templates/extras/customfield.html +1 -1
- nautobot/extras/templates/extras/customlink.html +1 -1
- nautobot/extras/templates/extras/dynamicgroup.html +2 -10
- nautobot/extras/templates/extras/exporttemplate.html +1 -1
- nautobot/extras/templates/extras/gitrepository.html +1 -1
- nautobot/extras/templates/extras/graphqlquery.html +1 -1
- nautobot/extras/templates/extras/job_detail.html +17 -1
- nautobot/extras/templates/extras/job_edit.html +1 -0
- nautobot/extras/templates/extras/jobbutton_retrieve.html +1 -1
- nautobot/extras/templates/extras/jobhook.html +1 -1
- nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
- nautobot/extras/templates/extras/jobresult.html +1 -1
- nautobot/extras/templates/extras/marketplace.html +29 -11
- nautobot/extras/templates/extras/objectchange.html +1 -1
- nautobot/extras/templates/extras/plugin_detail.html +33 -16
- nautobot/extras/templates/extras/plugins_tiles.html +21 -10
- nautobot/extras/templates/extras/relationship.html +1 -63
- nautobot/extras/templates/extras/role_retrieve.html +1 -1
- nautobot/extras/templates/extras/scheduledjob.html +1 -1
- nautobot/extras/templates/extras/secret.html +1 -1
- nautobot/extras/templates/extras/secretsgroup.html +1 -1
- nautobot/extras/templates/extras/status.html +1 -1
- nautobot/extras/templates/extras/tag.html +1 -1
- nautobot/extras/templates/extras/webhook.html +1 -1
- nautobot/extras/templatetags/job_buttons.py +4 -4
- nautobot/extras/test_jobs/api_test_job.py +1 -1
- nautobot/extras/test_jobs/atomic_transaction.py +2 -2
- nautobot/extras/test_jobs/dry_run.py +1 -1
- nautobot/extras/test_jobs/fail.py +5 -5
- nautobot/extras/test_jobs/file_output.py +1 -1
- nautobot/extras/test_jobs/file_upload_fail.py +1 -1
- nautobot/extras/test_jobs/file_upload_pass.py +1 -1
- nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
- nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
- nautobot/extras/test_jobs/log_redaction.py +1 -1
- nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
- nautobot/extras/test_jobs/modify_db.py +1 -1
- nautobot/extras/test_jobs/object_var_optional.py +1 -1
- nautobot/extras/test_jobs/object_var_required.py +1 -1
- nautobot/extras/test_jobs/object_vars.py +1 -1
- nautobot/extras/test_jobs/pass.py +3 -3
- nautobot/extras/test_jobs/profiling.py +1 -1
- nautobot/extras/test_jobs/relative_import.py +3 -3
- nautobot/extras/test_jobs/singleton.py +16 -0
- nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
- nautobot/extras/test_jobs/task_queues.py +1 -1
- nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_interfaces.gql +8 -0
- nautobot/extras/tests/git_data/01-valid-files/graphql_queries/device_names.gql +5 -0
- nautobot/extras/tests/git_data/02-invalid-files/graphql_queries/bad_device_names.gql +5 -0
- nautobot/extras/tests/git_helper.py +9 -1
- nautobot/extras/tests/integration/__init__.py +29 -16
- nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
- nautobot/extras/tests/test_api.py +19 -13
- nautobot/extras/tests/test_customfields.py +50 -52
- nautobot/extras/tests/test_datasources.py +29 -1
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +6 -6
- nautobot/extras/tests/test_forms.py +33 -1
- nautobot/extras/tests/test_jobs.py +178 -32
- nautobot/extras/tests/test_models.py +299 -10
- nautobot/extras/tests/test_plugins.py +62 -9
- nautobot/extras/tests/test_relationships.py +120 -9
- nautobot/extras/tests/test_utils.py +22 -1
- nautobot/extras/tests/test_views.py +56 -194
- nautobot/extras/utils.py +20 -10
- nautobot/extras/views.py +85 -110
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +41 -33
- nautobot/ipam/api/views.py +68 -117
- nautobot/ipam/factory.py +1 -1
- nautobot/ipam/filters.py +3 -2
- nautobot/ipam/lookups.py +101 -62
- nautobot/ipam/models.py +74 -18
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tables.py +25 -9
- nautobot/ipam/templates/ipam/ipaddress.html +2 -10
- nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
- nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
- nautobot/ipam/templates/ipam/prefix.html +2 -10
- nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
- nautobot/ipam/templates/ipam/rir.html +1 -1
- nautobot/ipam/templates/ipam/routetarget.html +1 -1
- nautobot/ipam/templates/ipam/service.html +1 -1
- nautobot/ipam/templates/ipam/vlan.html +2 -10
- nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
- nautobot/ipam/templates/ipam/vlangroup.html +1 -1
- nautobot/ipam/templates/ipam/vrf.html +1 -1
- nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
- nautobot/ipam/tests/test_api.py +436 -3
- nautobot/ipam/tests/test_forms.py +49 -47
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_models.py +119 -34
- nautobot/ipam/tests/test_querysets.py +63 -1
- nautobot/ipam/tests/test_utils.py +41 -2
- nautobot/ipam/tests/test_views.py +3 -0
- nautobot/ipam/utils/__init__.py +54 -17
- nautobot/ipam/views.py +61 -87
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
- nautobot/project-static/docs/404.html +131 -14
- nautobot/project-static/docs/apps/index.html +131 -14
- nautobot/project-static/docs/apps/nautobot-apps.html +132 -16
- nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.60a45f97.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.60a45f97.min.js.map} +2 -2
- nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js → search.f8cc74c7.min.js} +1 -1
- nautobot/project-static/docs/assets/javascripts/workers/{search.6ce7567c.min.js.map → search.f8cc74c7.min.js.map} +1 -1
- nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css → main.a40c8224.min.css} +1 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +147 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +144 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +459 -132
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +175 -28
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +180 -31
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +138 -16
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +137 -15
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +164 -27
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +187 -38
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +193 -31
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +216 -48
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +324 -75
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +666 -175
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +194 -46
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +538 -177
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +578 -221
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +145 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +156 -25
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +492 -65
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +705 -215
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +943 -422
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +144 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +619 -200
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +474 -159
- nautobot/project-static/docs/development/apps/api/configuration-view.html +131 -14
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +131 -14
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +131 -14
- nautobot/project-static/docs/development/apps/api/models/global-search.html +131 -14
- nautobot/project-static/docs/development/apps/api/models/graphql.html +131 -14
- nautobot/project-static/docs/development/apps/api/models/index.html +131 -14
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +131 -14
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +153 -17
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +131 -14
- nautobot/project-static/docs/development/apps/api/prometheus.html +131 -14
- nautobot/project-static/docs/development/apps/api/setup.html +131 -14
- nautobot/project-static/docs/development/apps/api/testing.html +131 -14
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +131 -14
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +131 -14
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +131 -14
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +131 -14
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/base-template.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/index.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/notes.html +131 -14
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +137 -16
- nautobot/project-static/docs/development/apps/api/views/urls.html +131 -14
- nautobot/project-static/docs/development/apps/index.html +131 -14
- nautobot/project-static/docs/development/apps/migration/code-updates.html +131 -14
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +131 -14
- nautobot/project-static/docs/development/apps/migration/from-v1.html +131 -14
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +131 -14
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +131 -14
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +131 -14
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +131 -14
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +135 -18
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +131 -14
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +297 -25
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +131 -14
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +131 -14
- nautobot/project-static/docs/development/core/application-registry.html +131 -14
- nautobot/project-static/docs/development/core/best-practices.html +131 -14
- nautobot/project-static/docs/development/core/bootstrap-ui.html +131 -14
- nautobot/project-static/docs/development/core/caching.html +131 -14
- nautobot/project-static/docs/development/core/controllers.html +131 -14
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +158 -84
- nautobot/project-static/docs/development/core/generic-views.html +131 -14
- nautobot/project-static/docs/development/core/getting-started.html +334 -234
- nautobot/project-static/docs/development/core/homepage.html +134 -17
- nautobot/project-static/docs/development/core/index.html +131 -14
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9829 -0
- nautobot/project-static/docs/development/core/model-checklist.html +141 -22
- nautobot/project-static/docs/development/core/model-features.html +131 -14
- nautobot/project-static/docs/development/core/natural-keys.html +131 -14
- nautobot/project-static/docs/development/core/navigation-menu.html +131 -14
- nautobot/project-static/docs/development/core/release-checklist.html +134 -17
- nautobot/project-static/docs/development/core/role-internals.html +131 -14
- nautobot/project-static/docs/development/core/settings.html +131 -14
- nautobot/project-static/docs/development/core/style-guide.html +134 -17
- nautobot/project-static/docs/development/core/templates.html +132 -15
- nautobot/project-static/docs/development/core/testing.html +131 -14
- nautobot/project-static/docs/development/core/ui-component-framework.html +454 -283
- nautobot/project-static/docs/development/core/user-preferences.html +131 -14
- nautobot/project-static/docs/development/index.html +131 -14
- nautobot/project-static/docs/development/jobs/index.html +301 -132
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +131 -14
- nautobot/project-static/docs/index.html +139 -33
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +132 -17
- nautobot/project-static/docs/overview/design_philosophy.html +131 -14
- nautobot/project-static/docs/release-notes/index.html +137 -22
- nautobot/project-static/docs/release-notes/version-1.0.html +319 -203
- nautobot/project-static/docs/release-notes/version-1.1.html +316 -200
- nautobot/project-static/docs/release-notes/version-1.2.html +391 -275
- nautobot/project-static/docs/release-notes/version-1.3.html +417 -301
- nautobot/project-static/docs/release-notes/version-1.4.html +502 -387
- nautobot/project-static/docs/release-notes/version-1.5.html +690 -576
- nautobot/project-static/docs/release-notes/version-1.6.html +989 -457
- nautobot/project-static/docs/release-notes/version-2.0.html +613 -499
- nautobot/project-static/docs/release-notes/version-2.1.html +448 -334
- nautobot/project-static/docs/release-notes/version-2.2.html +441 -327
- nautobot/project-static/docs/release-notes/version-2.3.html +1171 -451
- nautobot/project-static/docs/release-notes/version-2.4.html +800 -111
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +303 -287
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +131 -14
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +131 -14
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +133 -16
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +131 -14
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +131 -14
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +195 -18
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +134 -17
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +131 -14
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +133 -16
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +131 -14
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +131 -14
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +131 -14
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +151 -18
- nautobot/project-static/docs/user-guide/administration/installation/index.html +131 -14
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +132 -15
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +131 -14
- nautobot/project-static/docs/user-guide/administration/installation/services.html +131 -14
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +131 -14
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +131 -14
- nautobot/project-static/docs/user-guide/administration/security/index.html +9420 -0
- nautobot/project-static/docs/user-guide/administration/security/notices.html +9843 -0
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +131 -14
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +134 -18
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +131 -14
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +135 -22
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +134 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +131 -14
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +134 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +236 -34
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +131 -14
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +134 -17
- nautobot/project-static/docs/{development/core/local-k8s.html → user-guide/feature-guides/wireless-networks-and-controllers.html} +632 -566
- nautobot/project-static/docs/user-guide/index.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +135 -18
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +451 -16
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +135 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +134 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9797 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +132 -15
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +179 -35
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +159 -15
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +131 -14
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +131 -14
- nautobot/project-static/js/forms.js +1 -1
- nautobot/tenancy/api/views.py +9 -13
- nautobot/tenancy/templates/tenancy/tenant.html +1 -2
- nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
- nautobot/tenancy/views.py +4 -2
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +5 -4
- nautobot/users/api/views.py +3 -3
- nautobot/virtualization/api/serializers.py +4 -4
- nautobot/virtualization/api/views.py +5 -24
- nautobot/virtualization/filters.py +20 -3
- nautobot/virtualization/models.py +1 -1
- nautobot/virtualization/tables.py +2 -2
- nautobot/virtualization/templates/virtualization/cluster.html +1 -1
- nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
- nautobot/virtualization/templates/virtualization/clustergroup.html +1 -1
- nautobot/virtualization/templates/virtualization/clustertype.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -10
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
- nautobot/virtualization/templates/virtualization/vminterface.html +1 -1
- nautobot/virtualization/tests/test_filters.py +17 -0
- nautobot/wireless/filters.py +2 -2
- nautobot/wireless/forms.py +1 -1
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
- nautobot/wireless/tests/integration/__init__.py +0 -0
- nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
- nautobot/wireless/tests/test_filters.py +29 -1
- nautobot/wireless/tests/test_views.py +22 -1
- nautobot/wireless/views.py +0 -10
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/METADATA +9 -9
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/RECORD +667 -610
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/WHEEL +1 -1
- nautobot/core/fixtures/user-data.json +0 -59
- /nautobot/project-static/docs/assets/stylesheets/{main.6f8fc17f.min.css.map → main.a40c8224.min.css.map} +0 -0
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/NOTICE +0 -0
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.2.dist-info}/entry_points.txt +0 -0
|
@@ -30,6 +30,7 @@ from nautobot.extras.models import (
|
|
|
30
30
|
DynamicGroup,
|
|
31
31
|
ExportTemplate,
|
|
32
32
|
GitRepository,
|
|
33
|
+
GraphQLQuery,
|
|
33
34
|
Job,
|
|
34
35
|
JobQueue,
|
|
35
36
|
JobResult,
|
|
@@ -935,6 +936,120 @@ def delete_git_export_templates(repository_record, job_result, preserve=None):
|
|
|
935
936
|
job_result.log(msg, level_choice=LogLevelChoices.LOG_WARNING, grouping="export templates")
|
|
936
937
|
|
|
937
938
|
|
|
939
|
+
#
|
|
940
|
+
# GraphQL handling
|
|
941
|
+
#
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def refresh_git_graphql_queries(repository_record, job_result, delete=False):
|
|
945
|
+
"""Callback function for GitRepository updates - refresh all GraphQLQuery managed by this repository."""
|
|
946
|
+
if "extras.graphqlquery" in repository_record.provided_contents and not delete:
|
|
947
|
+
update_git_graphql_queries(repository_record, job_result)
|
|
948
|
+
else:
|
|
949
|
+
delete_git_graphql_queries(repository_record, job_result)
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
logger = logging.getLogger(__name__)
|
|
953
|
+
|
|
954
|
+
|
|
955
|
+
def update_git_graphql_queries(repository_record, job_result):
|
|
956
|
+
"""Refresh any GraphQL queries provided by this Git repository."""
|
|
957
|
+
graphql_query_path = os.path.join(repository_record.filesystem_path, "graphql_queries")
|
|
958
|
+
git_repository_content_type = ContentType.objects.get_for_model(GitRepository)
|
|
959
|
+
graphql_queries = []
|
|
960
|
+
|
|
961
|
+
if os.path.isdir(graphql_query_path):
|
|
962
|
+
for file in os.listdir(graphql_query_path):
|
|
963
|
+
file_path = os.path.join(graphql_query_path, file)
|
|
964
|
+
if not os.path.isfile(file_path):
|
|
965
|
+
continue
|
|
966
|
+
|
|
967
|
+
# Remove `.gql` extension from the name if it exists
|
|
968
|
+
query_name = file.rsplit(".gql", 1)[0] if file.endswith(".gql") else file
|
|
969
|
+
|
|
970
|
+
try:
|
|
971
|
+
with open(file_path, "r") as fd:
|
|
972
|
+
query_content = fd.read().strip()
|
|
973
|
+
|
|
974
|
+
graphql_query, created = GraphQLQuery.objects.get_or_create(
|
|
975
|
+
name=query_name,
|
|
976
|
+
owner_content_type=git_repository_content_type,
|
|
977
|
+
owner_object_id=repository_record.pk,
|
|
978
|
+
defaults={"query": query_content},
|
|
979
|
+
)
|
|
980
|
+
modified = graphql_query.query != query_content
|
|
981
|
+
graphql_queries.append(query_name)
|
|
982
|
+
# Only attempt to update if the content has changed
|
|
983
|
+
if modified:
|
|
984
|
+
try:
|
|
985
|
+
graphql_query.query = query_content
|
|
986
|
+
graphql_query.validated_save()
|
|
987
|
+
msg = (
|
|
988
|
+
f"Successfully created GraphQL query: {query_name}"
|
|
989
|
+
if created
|
|
990
|
+
else f"Successfully updated GraphQL query: {query_name}"
|
|
991
|
+
)
|
|
992
|
+
logger.info(msg)
|
|
993
|
+
job_result.log(
|
|
994
|
+
msg, obj=graphql_query, level_choice=LogLevelChoices.LOG_INFO, grouping="graphql queries"
|
|
995
|
+
)
|
|
996
|
+
except Exception as exc:
|
|
997
|
+
# Log validation error and retain the existing query
|
|
998
|
+
error_msg = (
|
|
999
|
+
f"Invalid GraphQL syntax for query '{query_name}'. "
|
|
1000
|
+
f"Retaining the existing query. Error: {exc}"
|
|
1001
|
+
)
|
|
1002
|
+
logger.error(error_msg)
|
|
1003
|
+
job_result.log(error_msg, level_choice=LogLevelChoices.LOG_ERROR, grouping="graphql queries")
|
|
1004
|
+
continue
|
|
1005
|
+
else:
|
|
1006
|
+
msg = f"No changes to GraphQL query: {query_name}"
|
|
1007
|
+
logger.info(msg)
|
|
1008
|
+
job_result.log(
|
|
1009
|
+
msg, obj=graphql_query, level_choice=LogLevelChoices.LOG_INFO, grouping="graphql queries"
|
|
1010
|
+
)
|
|
1011
|
+
|
|
1012
|
+
except Exception as exc:
|
|
1013
|
+
# Check if a query with the same name already exists
|
|
1014
|
+
existing_query = GraphQLQuery.objects.filter(name=query_name).first()
|
|
1015
|
+
if existing_query and existing_query.owner_object_id != repository_record.pk:
|
|
1016
|
+
error_msg = (
|
|
1017
|
+
f"GraphQL query '{query_name}' already exists "
|
|
1018
|
+
f"Please rename the query in the repository and try again."
|
|
1019
|
+
)
|
|
1020
|
+
else:
|
|
1021
|
+
error_msg = f"Error processing GraphQL query file '{file}': {exc}"
|
|
1022
|
+
|
|
1023
|
+
# Log the error
|
|
1024
|
+
logger.error(error_msg)
|
|
1025
|
+
job_result.log(error_msg, level_choice=LogLevelChoices.LOG_ERROR, grouping="graphql queries")
|
|
1026
|
+
|
|
1027
|
+
# Delete any queries not in the preserved list
|
|
1028
|
+
delete_git_graphql_queries(repository_record, job_result, preserve=graphql_queries)
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
def delete_git_graphql_queries(repository_record, job_result, preserve=None):
|
|
1032
|
+
"""Delete GraphQL queries owned by the given Git repository that are not in the preserve list."""
|
|
1033
|
+
git_repository_content_type = ContentType.objects.get_for_model(GitRepository)
|
|
1034
|
+
if preserve is None:
|
|
1035
|
+
preserve = []
|
|
1036
|
+
|
|
1037
|
+
for graphql_query in GraphQLQuery.objects.filter(
|
|
1038
|
+
owner_content_type=git_repository_content_type,
|
|
1039
|
+
owner_object_id=repository_record.pk,
|
|
1040
|
+
):
|
|
1041
|
+
if graphql_query.name not in preserve:
|
|
1042
|
+
try:
|
|
1043
|
+
graphql_query.delete()
|
|
1044
|
+
msg = f"Deleted GraphQL query: {graphql_query.name}"
|
|
1045
|
+
logger.warning(msg)
|
|
1046
|
+
job_result.log(msg, level_choice=LogLevelChoices.LOG_WARNING, grouping="graphql queries")
|
|
1047
|
+
except Exception as exc:
|
|
1048
|
+
error_msg = f"Unable to delete '{graphql_query.name}': {exc}"
|
|
1049
|
+
logger.error(error_msg)
|
|
1050
|
+
job_result.log(error_msg, level_choice=LogLevelChoices.LOG_ERROR, grouping="graphql queries")
|
|
1051
|
+
|
|
1052
|
+
|
|
938
1053
|
# Register built-in callbacks for data types potentially provided by a GitRepository
|
|
939
1054
|
register_datasource_contents(
|
|
940
1055
|
[
|
|
@@ -978,5 +1093,15 @@ register_datasource_contents(
|
|
|
978
1093
|
callback=refresh_git_export_templates,
|
|
979
1094
|
),
|
|
980
1095
|
),
|
|
1096
|
+
(
|
|
1097
|
+
"extras.gitrepository",
|
|
1098
|
+
DatasourceContent(
|
|
1099
|
+
name="graphql queries",
|
|
1100
|
+
content_identifier="extras.graphqlquery",
|
|
1101
|
+
icon="mdi-graphql",
|
|
1102
|
+
weight=400,
|
|
1103
|
+
callback=refresh_git_graphql_queries,
|
|
1104
|
+
),
|
|
1105
|
+
),
|
|
981
1106
|
]
|
|
982
1107
|
)
|
|
@@ -119,13 +119,13 @@ __all__ = (
|
|
|
119
119
|
"CustomFieldDateFilter",
|
|
120
120
|
"CustomFieldFilterMixin",
|
|
121
121
|
"CustomFieldJSONFilter",
|
|
122
|
+
"CustomFieldModelFilterSet",
|
|
123
|
+
"CustomFieldModelFilterSetMixin",
|
|
122
124
|
"CustomFieldMultiSelectFilter",
|
|
123
125
|
"CustomFieldMultiValueCharFilter",
|
|
124
126
|
"CustomFieldMultiValueDateFilter",
|
|
125
127
|
"CustomFieldMultiValueNumberFilter",
|
|
126
128
|
"CustomFieldNumberFilter",
|
|
127
|
-
"CustomFieldModelFilterSet",
|
|
128
|
-
"CustomFieldModelFilterSetMixin",
|
|
129
129
|
"CustomLinkFilterSet",
|
|
130
130
|
"DynamicGroupFilterSet",
|
|
131
131
|
"DynamicGroupMembershipFilterSet",
|
|
@@ -136,25 +136,25 @@ __all__ = (
|
|
|
136
136
|
"ImageAttachmentFilterSet",
|
|
137
137
|
"JobFilterSet",
|
|
138
138
|
"JobLogEntryFilterSet",
|
|
139
|
-
"JobQueueFilterSet",
|
|
140
139
|
"JobQueueAssignmentFilterSet",
|
|
140
|
+
"JobQueueFilterSet",
|
|
141
141
|
"JobResultFilterSet",
|
|
142
142
|
"LocalContextFilterSet",
|
|
143
143
|
"LocalContextModelFilterSetMixin",
|
|
144
|
-
"MetadataTypeFilterSet",
|
|
145
144
|
"MetadataChoiceFilterSet",
|
|
145
|
+
"MetadataTypeFilterSet",
|
|
146
146
|
"NautobotFilterSet",
|
|
147
147
|
"NoteFilterSet",
|
|
148
148
|
"ObjectChangeFilterSet",
|
|
149
|
+
"RelationshipAssociationFilterSet",
|
|
149
150
|
"RelationshipFilter",
|
|
150
151
|
"RelationshipFilterSet",
|
|
151
|
-
"RelationshipAssociationFilterSet",
|
|
152
152
|
"RoleFilterSet",
|
|
153
153
|
"RoleModelFilterSetMixin",
|
|
154
154
|
"ScheduledJobFilterSet",
|
|
155
155
|
"SecretFilterSet",
|
|
156
|
-
"SecretsGroupFilterSet",
|
|
157
156
|
"SecretsGroupAssociationFilterSet",
|
|
157
|
+
"SecretsGroupFilterSet",
|
|
158
158
|
"StatusFilter",
|
|
159
159
|
"StatusFilterSet",
|
|
160
160
|
"StatusModelFilterSetMixin",
|
|
@@ -874,6 +874,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
|
|
|
874
874
|
"is_job_button_receiver",
|
|
875
875
|
"soft_time_limit",
|
|
876
876
|
"time_limit",
|
|
877
|
+
"is_singleton",
|
|
877
878
|
"grouping_override",
|
|
878
879
|
"name_override",
|
|
879
880
|
"approval_required_override",
|
|
@@ -883,6 +884,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
|
|
|
883
884
|
"soft_time_limit_override",
|
|
884
885
|
"time_limit_override",
|
|
885
886
|
"has_sensitive_variables_override",
|
|
887
|
+
"is_singleton_override",
|
|
886
888
|
"tags",
|
|
887
889
|
]
|
|
888
890
|
|
nautobot/extras/forms/base.py
CHANGED
nautobot/extras/forms/forms.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import logging
|
|
2
3
|
|
|
4
|
+
from celery import chain
|
|
3
5
|
from django import forms
|
|
4
6
|
from django.conf import settings
|
|
5
7
|
from django.contrib.auth import get_user_model
|
|
@@ -7,7 +9,7 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
7
9
|
from django.core.exceptions import ValidationError
|
|
8
10
|
from django.core.validators import MinValueValidator
|
|
9
11
|
from django.db.models.fields import TextField
|
|
10
|
-
from django.forms import inlineformset_factory, ModelMultipleChoiceField
|
|
12
|
+
from django.forms import inlineformset_factory, ModelMultipleChoiceField, MultipleHiddenInput
|
|
11
13
|
from django.urls.base import reverse
|
|
12
14
|
from django.utils.timezone import get_current_timezone_name
|
|
13
15
|
|
|
@@ -35,6 +37,7 @@ from nautobot.core.forms import (
|
|
|
35
37
|
TagFilterField,
|
|
36
38
|
)
|
|
37
39
|
from nautobot.core.forms.constants import BOOLEAN_WITH_BLANK_CHOICES
|
|
40
|
+
from nautobot.core.forms.forms import ConfirmationForm
|
|
38
41
|
from nautobot.core.utils.deprecation import class_deprecated_in_favor_of
|
|
39
42
|
from nautobot.dcim.models import Device, DeviceRedundancyGroup, DeviceType, Location, Platform
|
|
40
43
|
from nautobot.extras.choices import (
|
|
@@ -88,9 +91,12 @@ from nautobot.extras.models import (
|
|
|
88
91
|
Webhook,
|
|
89
92
|
)
|
|
90
93
|
from nautobot.extras.registry import registry
|
|
94
|
+
from nautobot.extras.signals import change_context_state
|
|
95
|
+
from nautobot.extras.tasks import delete_custom_field_data
|
|
91
96
|
from nautobot.extras.utils import (
|
|
92
97
|
ChangeLoggedModelsQuery,
|
|
93
98
|
FeatureQuery,
|
|
99
|
+
get_worker_count,
|
|
94
100
|
RoleModelsQuery,
|
|
95
101
|
TaggableClassesQuery,
|
|
96
102
|
)
|
|
@@ -111,87 +117,90 @@ from .mixins import (
|
|
|
111
117
|
TagsBulkEditFormMixin,
|
|
112
118
|
)
|
|
113
119
|
|
|
120
|
+
logger = logging.getLogger(__name__)
|
|
121
|
+
|
|
114
122
|
__all__ = (
|
|
115
123
|
"BaseDynamicGroupMembershipFormSet",
|
|
116
|
-
"ComputedFieldForm",
|
|
117
124
|
"ComputedFieldFilterForm",
|
|
118
|
-
"
|
|
125
|
+
"ComputedFieldForm",
|
|
119
126
|
"ConfigContextBulkEditForm",
|
|
120
127
|
"ConfigContextFilterForm",
|
|
121
|
-
"
|
|
128
|
+
"ConfigContextForm",
|
|
122
129
|
"ConfigContextSchemaBulkEditForm",
|
|
123
130
|
"ConfigContextSchemaFilterForm",
|
|
124
|
-
"
|
|
125
|
-
"CustomFieldFilterForm",
|
|
126
|
-
"CustomFieldModelCSVForm",
|
|
131
|
+
"ConfigContextSchemaForm",
|
|
127
132
|
"CustomFieldBulkCreateForm", # 2.0 TODO remove this deprecated class
|
|
133
|
+
"CustomFieldBulkDeleteForm",
|
|
128
134
|
"CustomFieldChoiceFormSet",
|
|
129
|
-
"
|
|
135
|
+
"CustomFieldFilterForm",
|
|
136
|
+
"CustomFieldForm",
|
|
137
|
+
"CustomFieldModelCSVForm",
|
|
130
138
|
"CustomLinkFilterForm",
|
|
139
|
+
"CustomLinkForm",
|
|
131
140
|
"DynamicGroupBulkAssignForm",
|
|
132
|
-
"DynamicGroupForm",
|
|
133
141
|
"DynamicGroupFilterForm",
|
|
142
|
+
"DynamicGroupForm",
|
|
134
143
|
"DynamicGroupMembershipFormSet",
|
|
135
|
-
"ExportTemplateForm",
|
|
136
144
|
"ExportTemplateFilterForm",
|
|
145
|
+
"ExportTemplateForm",
|
|
146
|
+
"ExternalIntegrationBulkEditForm",
|
|
137
147
|
"ExternalIntegrationFilterForm",
|
|
138
148
|
"ExternalIntegrationForm",
|
|
139
|
-
"ExternalIntegrationBulkEditForm",
|
|
140
|
-
"GitRepositoryForm",
|
|
141
149
|
"GitRepositoryBulkEditForm",
|
|
142
150
|
"GitRepositoryFilterForm",
|
|
143
|
-
"
|
|
151
|
+
"GitRepositoryForm",
|
|
144
152
|
"GraphQLQueryFilterForm",
|
|
153
|
+
"GraphQLQueryForm",
|
|
145
154
|
"ImageAttachmentForm",
|
|
146
|
-
"JobForm",
|
|
147
155
|
"JobBulkEditForm",
|
|
148
|
-
"JobButtonForm",
|
|
149
156
|
"JobButtonBulkEditForm",
|
|
150
157
|
"JobButtonFilterForm",
|
|
158
|
+
"JobButtonForm",
|
|
151
159
|
"JobEditForm",
|
|
152
160
|
"JobFilterForm",
|
|
153
|
-
"
|
|
161
|
+
"JobForm",
|
|
154
162
|
"JobHookFilterForm",
|
|
163
|
+
"JobHookForm",
|
|
155
164
|
"JobQueueBulkEditForm",
|
|
156
165
|
"JobQueueFilterForm",
|
|
157
166
|
"JobQueueForm",
|
|
158
|
-
"JobScheduleForm",
|
|
159
167
|
"JobResultFilterForm",
|
|
168
|
+
"JobScheduleForm",
|
|
160
169
|
"LocalContextFilterForm",
|
|
161
|
-
"LocalContextModelForm",
|
|
162
170
|
"LocalContextModelBulkEditForm",
|
|
171
|
+
"LocalContextModelForm",
|
|
172
|
+
"MetadataChoiceFormSet",
|
|
163
173
|
"MetadataTypeBulkEditForm",
|
|
164
|
-
"MetadataTypeForm",
|
|
165
174
|
"MetadataTypeFilterForm",
|
|
166
|
-
"
|
|
167
|
-
"NoteForm",
|
|
175
|
+
"MetadataTypeForm",
|
|
168
176
|
"NoteFilterForm",
|
|
177
|
+
"NoteForm",
|
|
169
178
|
"ObjectChangeFilterForm",
|
|
170
179
|
"ObjectMetadataFilterForm",
|
|
171
180
|
"PasswordInputWithPlaceholder",
|
|
172
|
-
"RelationshipForm",
|
|
173
|
-
"RelationshipFilterForm",
|
|
174
181
|
"RelationshipAssociationFilterForm",
|
|
182
|
+
"RelationshipFilterForm",
|
|
183
|
+
"RelationshipForm",
|
|
175
184
|
"RoleBulkEditForm",
|
|
176
185
|
"RoleFilterForm",
|
|
177
186
|
"RoleForm",
|
|
178
187
|
"SavedViewForm",
|
|
179
188
|
"SavedViewModalForm",
|
|
180
189
|
"ScheduledJobFilterForm",
|
|
181
|
-
"SecretForm",
|
|
182
190
|
"SecretFilterForm",
|
|
183
|
-
"
|
|
184
|
-
"SecretsGroupFilterForm",
|
|
191
|
+
"SecretForm",
|
|
185
192
|
"SecretsGroupAssociationFormSet",
|
|
193
|
+
"SecretsGroupFilterForm",
|
|
194
|
+
"SecretsGroupForm",
|
|
186
195
|
"StaticGroupAssociationFilterForm",
|
|
187
|
-
"StatusForm",
|
|
188
|
-
"StatusFilterForm",
|
|
189
196
|
"StatusBulkEditForm",
|
|
190
|
-
"
|
|
191
|
-
"
|
|
197
|
+
"StatusFilterForm",
|
|
198
|
+
"StatusForm",
|
|
192
199
|
"TagBulkEditForm",
|
|
193
|
-
"
|
|
200
|
+
"TagFilterForm",
|
|
201
|
+
"TagForm",
|
|
194
202
|
"WebhookFilterForm",
|
|
203
|
+
"WebhookForm",
|
|
195
204
|
)
|
|
196
205
|
|
|
197
206
|
|
|
@@ -491,6 +500,44 @@ class CustomFieldBulkCreateForm(CustomFieldModelBulkEditFormMixin):
|
|
|
491
500
|
"""No longer needed as a separate class - use CustomFieldModelBulkEditFormMixin instead."""
|
|
492
501
|
|
|
493
502
|
|
|
503
|
+
class CustomFieldBulkDeleteForm(ConfirmationForm):
|
|
504
|
+
def __init__(self, *args, delete_all=False, **kwargs):
|
|
505
|
+
super().__init__(*args, **kwargs)
|
|
506
|
+
queryset = CustomField.objects.all()
|
|
507
|
+
self.fields["pk"] = ModelMultipleChoiceField(
|
|
508
|
+
queryset=queryset, widget=MultipleHiddenInput, required=not delete_all
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
def construct_custom_field_delete_tasks(self, queryset):
|
|
512
|
+
"""
|
|
513
|
+
Helper method to construct a list of celery tasks to execute when bulk deleting custom fields.
|
|
514
|
+
"""
|
|
515
|
+
change_context = change_context_state.get()
|
|
516
|
+
if change_context is None:
|
|
517
|
+
context = None
|
|
518
|
+
else:
|
|
519
|
+
context = change_context.as_dict(queryset)
|
|
520
|
+
context["context_detail"] = "bulk delete custom field data"
|
|
521
|
+
tasks = [
|
|
522
|
+
delete_custom_field_data.si(obj.key, set(obj.content_types.values_list("pk", flat=True)), context)
|
|
523
|
+
for obj in queryset
|
|
524
|
+
]
|
|
525
|
+
return tasks
|
|
526
|
+
|
|
527
|
+
def perform_pre_delete(self, queryset):
|
|
528
|
+
"""
|
|
529
|
+
Remove all Custom Field Keys/Values from _custom_field_data of the related ContentType in the background.
|
|
530
|
+
"""
|
|
531
|
+
if not get_worker_count():
|
|
532
|
+
logger.error("Celery worker process not running. Object custom fields may fail to reflect this deletion.")
|
|
533
|
+
return
|
|
534
|
+
tasks = self.construct_custom_field_delete_tasks(queryset)
|
|
535
|
+
# Executing the tasks in the background sequentially using chain() aligns with how a single
|
|
536
|
+
# CustomField object is deleted. We decided to not check the result because it needs at least one worker
|
|
537
|
+
# to be active and comes with extra performance penalty.
|
|
538
|
+
chain(*tasks).apply_async()
|
|
539
|
+
|
|
540
|
+
|
|
494
541
|
#
|
|
495
542
|
# Custom Links
|
|
496
543
|
#
|
|
@@ -990,6 +1037,8 @@ class JobEditForm(NautobotModelForm):
|
|
|
990
1037
|
"job_queues",
|
|
991
1038
|
"default_job_queue_override",
|
|
992
1039
|
"default_job_queue",
|
|
1040
|
+
"is_singleton",
|
|
1041
|
+
"is_singleton_override",
|
|
993
1042
|
"tags",
|
|
994
1043
|
]
|
|
995
1044
|
|
|
@@ -1089,6 +1138,11 @@ class JobBulkEditForm(NautobotBulkEditForm):
|
|
|
1089
1138
|
required=False,
|
|
1090
1139
|
help_text="Default Job Queue the job runs on if no Job Queue is specified",
|
|
1091
1140
|
)
|
|
1141
|
+
is_singleton = forms.NullBooleanField(
|
|
1142
|
+
required=False,
|
|
1143
|
+
widget=BulkEditNullBooleanSelect,
|
|
1144
|
+
help_text="Whether this job should fail to run if another instance of this job is already running",
|
|
1145
|
+
)
|
|
1092
1146
|
# Flags to indicate whether the above properties are inherited from the source code or overridden by the database
|
|
1093
1147
|
# Text field overrides
|
|
1094
1148
|
clear_grouping_override = forms.BooleanField(
|
|
@@ -1132,10 +1186,62 @@ class JobBulkEditForm(NautobotBulkEditForm):
|
|
|
1132
1186
|
required=False,
|
|
1133
1187
|
help_text="If checked, the values of has sensitive variables will be reverted to the default values defined in each Job's source code",
|
|
1134
1188
|
)
|
|
1189
|
+
is_singleton_override = forms.BooleanField(
|
|
1190
|
+
required=False,
|
|
1191
|
+
help_text="If checked, the values of is singleton will be reverted to the default values defined in each Job's source code",
|
|
1192
|
+
)
|
|
1135
1193
|
|
|
1136
1194
|
class Meta:
|
|
1137
1195
|
model = Job
|
|
1138
1196
|
|
|
1197
|
+
def post_save(self, obj):
|
|
1198
|
+
super().post_save(obj)
|
|
1199
|
+
|
|
1200
|
+
cleaned_data = self.cleaned_data
|
|
1201
|
+
|
|
1202
|
+
# Handle text related fields
|
|
1203
|
+
for overridable_field in JOB_OVERRIDABLE_FIELDS:
|
|
1204
|
+
override_field = overridable_field + "_override"
|
|
1205
|
+
clear_override_field = "clear_" + overridable_field + "_override"
|
|
1206
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1207
|
+
override_value = cleaned_data.get(overridable_field)
|
|
1208
|
+
if reset_override:
|
|
1209
|
+
setattr(obj, override_field, False)
|
|
1210
|
+
elif not reset_override and override_value not in [None, ""]:
|
|
1211
|
+
setattr(obj, override_field, True)
|
|
1212
|
+
setattr(obj, overridable_field, override_value)
|
|
1213
|
+
|
|
1214
|
+
# Handle job queues
|
|
1215
|
+
clear_override_field = "clear_job_queues_override"
|
|
1216
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1217
|
+
if reset_override:
|
|
1218
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1219
|
+
job_queues = []
|
|
1220
|
+
for queue_name in meta_task_queues:
|
|
1221
|
+
try:
|
|
1222
|
+
job_queues.append(JobQueue.objects.get(name=queue_name))
|
|
1223
|
+
except JobQueue.DoesNotExist:
|
|
1224
|
+
# Do we want to create the Job Queue for the users here if we do not have it in the database?
|
|
1225
|
+
pass
|
|
1226
|
+
obj.job_queues_override = False
|
|
1227
|
+
obj.job_queues.set(job_queues)
|
|
1228
|
+
elif cleaned_data["job_queues"]:
|
|
1229
|
+
obj.job_queues_override = True
|
|
1230
|
+
|
|
1231
|
+
# Handle default job queue
|
|
1232
|
+
clear_override_field = "clear_default_job_queue_override"
|
|
1233
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1234
|
+
if reset_override:
|
|
1235
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1236
|
+
obj.default_job_queue_override = False
|
|
1237
|
+
obj.default_job_queue, _ = JobQueue.objects.get_or_create(
|
|
1238
|
+
name=meta_task_queues[0] if meta_task_queues else settings.CELERY_TASK_DEFAULT_QUEUE
|
|
1239
|
+
)
|
|
1240
|
+
elif cleaned_data["default_job_queue"]:
|
|
1241
|
+
obj.default_job_queue_override = True
|
|
1242
|
+
|
|
1243
|
+
obj.validated_save()
|
|
1244
|
+
|
|
1139
1245
|
|
|
1140
1246
|
class JobFilterForm(BootstrapMixin, forms.Form):
|
|
1141
1247
|
model = Job
|
|
@@ -1779,6 +1885,8 @@ class RoleBulkEditForm(NautobotBulkEditForm):
|
|
|
1779
1885
|
|
|
1780
1886
|
pk = forms.ModelMultipleChoiceField(queryset=Role.objects.all(), widget=forms.MultipleHiddenInput)
|
|
1781
1887
|
color = forms.CharField(max_length=6, required=False, widget=ColorSelect())
|
|
1888
|
+
description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
|
|
1889
|
+
weight = forms.IntegerField(required=False)
|
|
1782
1890
|
content_types = MultipleContentTypeField(
|
|
1783
1891
|
queryset=RoleModelsQuery().as_queryset(), required=False, label="Content Type(s)"
|
|
1784
1892
|
)
|
nautobot/extras/forms/mixins.py
CHANGED
|
@@ -34,7 +34,7 @@ from nautobot.extras.utils import remove_prefix_from_cf_key
|
|
|
34
34
|
logger = logging.getLogger(__name__)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
__all__ = (
|
|
37
|
+
__all__ = ( # noqa:RUF022
|
|
38
38
|
"ContactTeamModelFilterFormMixin",
|
|
39
39
|
"CustomFieldModelBulkEditFormMixin",
|
|
40
40
|
"CustomFieldModelFilterFormMixin",
|
|
@@ -327,7 +327,7 @@ class RelationshipModelBulkEditFormMixin(BulkEditForm):
|
|
|
327
327
|
field_name,
|
|
328
328
|
instance,
|
|
329
329
|
)
|
|
330
|
-
if field_name in self.nullable_fields and field_name in nullified_fields:
|
|
330
|
+
if field_name in self.nullable_fields and nullified_fields and field_name in nullified_fields:
|
|
331
331
|
logger.debug("Deleting existing relationship associations for %s on %s", relationship, instance)
|
|
332
332
|
relationshipassociation_queryset.delete()
|
|
333
333
|
elif field_name in self.cleaned_data:
|
|
@@ -673,7 +673,7 @@ class RelationshipModelFormMixin(forms.ModelForm):
|
|
|
673
673
|
for peer_id in target_peer_ids:
|
|
674
674
|
relationship = self.fields[field_name].model
|
|
675
675
|
if not relationship.symmetric:
|
|
676
|
-
association = RelationshipAssociation(
|
|
676
|
+
association = RelationshipAssociation( # pylint: disable=repeated-keyword
|
|
677
677
|
relationship=relationship,
|
|
678
678
|
**{
|
|
679
679
|
f"{side}_type": self.obj_type,
|
|
@@ -837,13 +837,21 @@ class StatusModelFilterFormMixin(forms.Form):
|
|
|
837
837
|
self.order_fields(self.field_order) # Reorder fields again
|
|
838
838
|
|
|
839
839
|
|
|
840
|
-
class TagsBulkEditFormMixin(
|
|
840
|
+
class TagsBulkEditFormMixin(BulkEditForm):
|
|
841
841
|
def __init__(self, *args, **kwargs):
|
|
842
842
|
super().__init__(*args, **kwargs)
|
|
843
843
|
|
|
844
844
|
# Add add/remove tags fields
|
|
845
|
-
self.fields["add_tags"] = DynamicModelMultipleChoiceField(
|
|
846
|
-
|
|
845
|
+
self.fields["add_tags"] = DynamicModelMultipleChoiceField(
|
|
846
|
+
queryset=Tag.objects.all(),
|
|
847
|
+
query_params={"content_types": self.model._meta.label_lower},
|
|
848
|
+
required=False,
|
|
849
|
+
)
|
|
850
|
+
self.fields["remove_tags"] = DynamicModelMultipleChoiceField(
|
|
851
|
+
queryset=Tag.objects.all(),
|
|
852
|
+
query_params={"content_types": self.model._meta.label_lower},
|
|
853
|
+
required=False,
|
|
854
|
+
)
|
|
847
855
|
|
|
848
856
|
|
|
849
857
|
# 2.2 TODO: Names below are only for backward compatibility with Nautobot 1.3 and earlier. Remove in 2.2
|
nautobot/extras/group_sync.py
CHANGED
|
@@ -8,15 +8,15 @@ from django.contrib.auth.models import Group
|
|
|
8
8
|
logger = logging.getLogger(__name__)
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
CLAIMS_GROUP_NAME = getattr(settings, "
|
|
11
|
+
CLAIMS_GROUP_NAME = getattr(settings, "SSO_CLAIMS_GROUP", "groups")
|
|
12
12
|
""" Which claim to look at in the OAuth2/OIDC response
|
|
13
13
|
|
|
14
14
|
For Okta you can look at `Okta -> Authorization Servers -> Claims`. And a reasonable
|
|
15
15
|
default is "groups". For Azure a reasonable default is "roles".
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
SUPERUSER_GROUPS = getattr(settings, "
|
|
19
|
-
STAFF_GROUPS = getattr(settings, "
|
|
18
|
+
SUPERUSER_GROUPS = getattr(settings, "SSO_SUPERUSER_GROUPS", [])
|
|
19
|
+
STAFF_GROUPS = getattr(settings, "SSO_STAFF_GROUPS", [])
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def group_sync(uid, user=None, response=None, *args, **kwargs):
|
nautobot/extras/health_checks.py
CHANGED
|
@@ -160,5 +160,4 @@ class RedisBackend(RedisHealthCheck):
|
|
|
160
160
|
elif client_class == "django_redis.client.DefaultClient":
|
|
161
161
|
self.check_redis(redis_url=location, **options.get("CONNECTION_POOL_KWARGS", {}))
|
|
162
162
|
else:
|
|
163
|
-
|
|
164
|
-
self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
|
|
163
|
+
self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
|