nautobot 2.0.0a2__py3-none-any.whl → 2.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nautobot/__init__.py +1 -5
- nautobot/apps/api.py +6 -8
- nautobot/apps/forms.py +0 -2
- nautobot/apps/ui.py +0 -8
- nautobot/circuits/api/serializers.py +9 -119
- nautobot/circuits/api/urls.py +1 -1
- nautobot/circuits/api/views.py +0 -1
- nautobot/circuits/choices.py +0 -2
- nautobot/circuits/filters.py +7 -6
- nautobot/circuits/forms.py +3 -73
- nautobot/circuits/migrations/0001_initial_part_1.py +0 -1
- nautobot/circuits/migrations/0002_initial_part_2.py +0 -1
- nautobot/circuits/migrations/0003_auto_slug.py +0 -1
- nautobot/circuits/migrations/0004_increase_provider_account_length.py +0 -1
- nautobot/circuits/migrations/0005_providernetwork.py +0 -1
- nautobot/circuits/migrations/0006_cache_circuit_terminations.py +0 -1
- nautobot/circuits/migrations/0007_circuitterminations_primary_model.py +0 -1
- nautobot/circuits/migrations/0008_add_natural_indexing.py +0 -1
- nautobot/circuits/migrations/0009_circuittermination_location.py +0 -1
- nautobot/circuits/migrations/0010_rename_foreign_keys_and_related_names.py +0 -1
- nautobot/circuits/migrations/0011_remove_site_foreign_key_from_circuit_termination_class.py +0 -1
- nautobot/circuits/migrations/0012_created_datetime.py +0 -1
- nautobot/circuits/migrations/0013_alter_circuittermination__path.py +0 -1
- nautobot/circuits/migrations/0014_related_name_changes.py +1 -2
- nautobot/circuits/migrations/0015_remove_circuittype_provider_slug.py +20 -0
- nautobot/circuits/migrations/0016_tagsfield.py +34 -0
- nautobot/circuits/migrations/0017_fixup_null_statuses.py +22 -0
- nautobot/circuits/migrations/0018_status_nonnullable.py +22 -0
- nautobot/circuits/models.py +3 -93
- nautobot/circuits/navigation.py +14 -69
- nautobot/circuits/signals.py +0 -2
- nautobot/circuits/tables.py +42 -5
- nautobot/circuits/templates/circuits/circuit_retrieve.html +1 -1
- nautobot/circuits/templates/circuits/circuittermination_retrieve.html +1 -1
- nautobot/circuits/templates/circuits/circuittype_retrieve.html +1 -1
- nautobot/circuits/templates/circuits/provider_create.html +0 -1
- nautobot/circuits/templates/circuits/provider_retrieve.html +1 -1
- nautobot/circuits/tests/integration/test_relationships.py +13 -16
- nautobot/circuits/tests/test_api.py +13 -43
- nautobot/circuits/tests/test_filters.py +20 -15
- nautobot/circuits/tests/test_models.py +7 -3
- nautobot/circuits/tests/test_views.py +57 -67
- nautobot/circuits/views.py +18 -9
- nautobot/core/api/__init__.py +8 -2
- nautobot/core/api/authentication.py +0 -3
- nautobot/core/api/fields.py +15 -6
- nautobot/core/api/filter_backends.py +3 -2
- nautobot/core/api/metadata.py +237 -30
- nautobot/core/api/mixins.py +94 -0
- nautobot/core/api/pagination.py +3 -3
- nautobot/core/api/parsers.py +154 -0
- nautobot/core/api/renderers.py +153 -2
- nautobot/core/api/schema.py +47 -3
- nautobot/core/api/serializers.py +377 -37
- nautobot/core/api/urls.py +11 -3
- nautobot/core/api/utils.py +174 -2
- nautobot/core/api/versioning.py +32 -10
- nautobot/core/api/views.py +266 -75
- nautobot/core/apps/__init__.py +138 -221
- nautobot/core/celery/__init__.py +112 -41
- nautobot/core/celery/backends.py +19 -13
- nautobot/core/celery/control.py +46 -0
- nautobot/core/celery/encoders.py +53 -0
- nautobot/core/celery/log.py +38 -0
- nautobot/core/celery/schedulers.py +23 -4
- nautobot/core/celery/task.py +1 -16
- nautobot/core/checks.py +0 -27
- nautobot/core/choices.py +21 -113
- nautobot/core/{cli.py → cli/__init__.py} +1 -2
- nautobot/core/cli/__main__.py +3 -0
- nautobot/core/constants.py +25 -43
- nautobot/core/context_processors.py +12 -0
- nautobot/core/filters.py +2 -2
- nautobot/core/forms/__init__.py +0 -4
- nautobot/core/forms/fields.py +39 -68
- nautobot/core/forms/forms.py +27 -27
- nautobot/core/forms/utils.py +7 -59
- nautobot/core/forms/widgets.py +0 -1
- nautobot/core/graphql/__init__.py +2 -2
- nautobot/core/graphql/schema.py +4 -27
- nautobot/core/jobs/__init__.py +75 -0
- nautobot/core/management/commands/build_ui.py +255 -0
- nautobot/core/management/commands/celery.py +0 -1
- nautobot/core/management/commands/generate_test_data.py +18 -13
- nautobot/core/management/commands/post_upgrade.py +24 -24
- nautobot/core/management/commands/validate_models.py +0 -1
- nautobot/core/middleware.py +0 -1
- nautobot/core/models/__init__.py +26 -1
- nautobot/core/models/fields.py +24 -5
- nautobot/core/models/generics.py +2 -46
- nautobot/core/models/managers.py +5 -0
- nautobot/core/models/name_color_content_types.py +1 -19
- nautobot/core/models/tree_queries.py +14 -4
- nautobot/core/models/utils.py +9 -10
- nautobot/core/models/validators.py +17 -8
- nautobot/core/releases.py +8 -10
- nautobot/core/settings.py +81 -53
- nautobot/core/tables.py +5 -5
- nautobot/core/tasks.py +4 -7
- nautobot/core/templates/base.html +1 -49
- nautobot/core/templates/base_django.html +49 -0
- nautobot/core/templates/base_react.html +55 -0
- nautobot/core/templates/buttons/export.html +6 -4
- nautobot/core/templates/generic/object_bulk_create.html +10 -21
- nautobot/core/templates/generic/object_list.html +4 -1
- nautobot/core/templates/generic/object_retrieve_plugin_full_width.html +3 -0
- nautobot/core/templates/inc/footer.html +1 -0
- nautobot/core/templates/inc/javascript.html +0 -14
- nautobot/core/templates/inc/nav_menu.html +28 -33
- nautobot/core/templates/inc/object_details_advanced_panel.html +13 -0
- nautobot/core/templates/inc/relationships_table_rows.html +2 -2
- nautobot/core/templates/nautobot_config.py.j2 +8 -25
- nautobot/core/templates/plugin_template/__init__.py-tpl +1 -2
- nautobot/core/templates/rest_framework/api.html +8 -0
- nautobot/core/templatetags/buttons.py +32 -29
- nautobot/core/templatetags/helpers.py +1 -1
- nautobot/core/testing/__init__.py +47 -44
- nautobot/core/testing/api.py +365 -47
- nautobot/core/testing/filters.py +12 -7
- nautobot/core/testing/integration.py +1 -1
- nautobot/core/testing/migrations.py +2 -0
- nautobot/core/testing/mixins.py +22 -12
- nautobot/core/testing/schema.py +2 -1
- nautobot/core/testing/views.py +28 -51
- nautobot/core/tests/integration/test_filters.py +17 -8
- nautobot/core/tests/integration/test_navbar.py +11 -34
- nautobot/core/tests/integration/test_plugin_navbar.py +9 -103
- nautobot/core/tests/nautobot_config.py +2 -3
- nautobot/core/tests/runner.py +0 -1
- nautobot/core/tests/test_api.py +290 -24
- nautobot/core/tests/test_authentication.py +57 -14
- nautobot/core/tests/test_checks.py +0 -7
- nautobot/core/tests/test_choices.py +0 -1
- nautobot/core/tests/test_filters.py +117 -110
- nautobot/core/tests/test_forms.py +47 -110
- nautobot/core/tests/test_graphql.py +158 -135
- nautobot/core/tests/test_logging.py +4 -1
- nautobot/core/tests/test_managers.py +3 -5
- nautobot/core/tests/test_models.py +2 -0
- nautobot/core/tests/test_ordering.py +0 -2
- nautobot/core/tests/test_paginator.py +3 -1
- nautobot/core/tests/test_releases.py +12 -12
- nautobot/core/tests/test_templatetags_helpers.py +7 -4
- nautobot/core/tests/test_utils.py +112 -78
- nautobot/core/tests/test_views.py +12 -17
- nautobot/core/tests/test_views_utils.py +6 -9
- nautobot/core/utils/data.py +17 -0
- nautobot/core/utils/deprecation.py +13 -20
- nautobot/core/utils/filtering.py +53 -9
- nautobot/core/utils/git.py +12 -4
- nautobot/core/utils/lookup.py +3 -1
- nautobot/core/utils/requests.py +23 -116
- nautobot/core/views/__init__.py +1 -2
- nautobot/core/views/generic.py +131 -119
- nautobot/core/views/mixins.py +53 -62
- nautobot/core/views/paginator.py +0 -1
- nautobot/core/views/renderers.py +14 -12
- nautobot/core/views/utils.py +87 -4
- nautobot/dcim/api/serializers.py +160 -672
- nautobot/dcim/api/urls.py +1 -1
- nautobot/dcim/api/views.py +7 -46
- nautobot/dcim/choices.py +2 -25
- nautobot/dcim/elevations.py +0 -1
- nautobot/dcim/factory.py +15 -4
- nautobot/dcim/filters/__init__.py +42 -13
- nautobot/dcim/form_mixins.py +1 -27
- nautobot/dcim/forms.py +58 -797
- nautobot/dcim/management/commands/trace_paths.py +0 -1
- nautobot/dcim/migrations/0001_initial_part_1.py +0 -1
- nautobot/dcim/migrations/0002_initial_part_2.py +0 -1
- nautobot/dcim/migrations/0003_initial_part_3.py +0 -1
- nautobot/dcim/migrations/0004_initial_part_4.py +0 -1
- nautobot/dcim/migrations/0005_device_local_context_schema.py +0 -1
- nautobot/dcim/migrations/0006_auto_slug.py +0 -1
- nautobot/dcim/migrations/0007_device_secrets_group.py +0 -1
- nautobot/dcim/migrations/0008_increase_all_serial_lengths.py +0 -1
- nautobot/dcim/migrations/0009_add_natural_indexing.py +0 -1
- nautobot/dcim/migrations/0010_interface_status.py +0 -1
- nautobot/dcim/migrations/0011_interface_status_data_migration.py +0 -1
- nautobot/dcim/migrations/0012_interface_parent_bridge.py +0 -1
- nautobot/dcim/migrations/0013_location_location_type.py +0 -1
- nautobot/dcim/migrations/0014_location_status_data_migration.py +0 -1
- nautobot/dcim/migrations/0015_device_components__changeloggedmodel.py +0 -1
- nautobot/dcim/migrations/0016_device_components__timestamp_data_migration.py +0 -1
- nautobot/dcim/migrations/0017_locationtype_nestable.py +0 -1
- nautobot/dcim/migrations/0018_device_redundancy_group.py +0 -1
- nautobot/dcim/migrations/0019_device_redundancy_group_data_migration.py +0 -1
- nautobot/dcim/migrations/0020_move_site_fields_to_location_model.py +0 -1
- nautobot/dcim/migrations/0021_mptt_to_tree_queries.py +0 -1
- nautobot/dcim/migrations/0022_interface_mac_address_data_migration.py +0 -1
- nautobot/dcim/migrations/0023_alter_interface_mac_address.py +0 -1
- nautobot/dcim/migrations/0024_alter_device_and_rack_role_add_new_role.py +2 -2
- nautobot/dcim/migrations/0025_device_and_rack_roles_data_migrations.py +19 -14
- nautobot/dcim/migrations/0026_rename_device_and_rack_role.py +0 -1
- nautobot/dcim/migrations/0027_remove_device_role_and_rack_role.py +1 -2
- nautobot/dcim/migrations/0028_rename_foreignkey_fields.py +1 -2
- nautobot/dcim/migrations/0029_add_tree_managers_and_foreign_keys_pre_data_migration.py +0 -1
- nautobot/dcim/migrations/0030_migrate_region_and_site_data_to_locations.py +2 -2
- nautobot/dcim/migrations/0031_rename_path_end_point_related_name.py +0 -1
- nautobot/dcim/migrations/0032_remove_site_foreign_key_from_dcim_models.py +0 -1
- nautobot/dcim/migrations/0033_created_datetime.py +0 -1
- nautobot/dcim/migrations/0034_fixup_fks_and_related_names.py +0 -1
- nautobot/dcim/migrations/0035_related_name_changes.py +1 -2
- nautobot/dcim/migrations/0036_remove_region_and_site.py +1 -2
- nautobot/dcim/migrations/0037_interface_ip_addresses_m2m.py +0 -1
- nautobot/dcim/migrations/0038_alter_location_managers.py +0 -1
- nautobot/dcim/migrations/0039_remove_slug.py +24 -0
- nautobot/dcim/migrations/0040_tagsfield.py +109 -0
- nautobot/dcim/migrations/0041_ipam__namespaces.py +25 -0
- nautobot/dcim/migrations/0042_fixup_null_statuses.py +51 -0
- nautobot/dcim/migrations/0043_status_nonnullable.py +72 -0
- nautobot/dcim/models/cables.py +4 -35
- nautobot/dcim/models/device_component_templates.py +7 -2
- nautobot/dcim/models/device_components.py +26 -203
- nautobot/dcim/models/devices.py +30 -152
- nautobot/dcim/models/locations.py +3 -64
- nautobot/dcim/models/power.py +3 -51
- nautobot/dcim/models/racks.py +7 -86
- nautobot/dcim/navigation.py +141 -467
- nautobot/dcim/signals.py +0 -2
- nautobot/dcim/tables/devices.py +8 -5
- nautobot/dcim/tables/devicetypes.py +1 -1
- nautobot/dcim/tables/locations.py +2 -2
- nautobot/dcim/tables/power.py +2 -2
- nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/device.html +15 -4
- nautobot/dcim/templates/dcim/device_edit.html +6 -0
- nautobot/dcim/templates/dcim/deviceredundancygroup_create.html +0 -1
- nautobot/dcim/templates/dcim/devicetype.html +2 -2
- nautobot/dcim/templates/dcim/interface.html +4 -0
- nautobot/dcim/templates/dcim/interface_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/interface_edit.html +1 -0
- nautobot/dcim/templates/dcim/location.html +16 -1
- nautobot/dcim/templates/dcim/locationtype.html +15 -0
- nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/rackgroup.html +0 -12
- nautobot/dcim/tests/integration/test_cable_connect_form.py +4 -4
- nautobot/dcim/tests/test_api.py +202 -130
- nautobot/dcim/tests/test_cablepaths.py +47 -42
- nautobot/dcim/tests/test_filters.py +156 -134
- nautobot/dcim/tests/test_forms.py +12 -213
- nautobot/dcim/tests/test_graphql.py +8 -3
- nautobot/dcim/tests/test_migrations.py +6 -11
- nautobot/dcim/tests/test_models.py +208 -158
- nautobot/dcim/tests/test_natural_ordering.py +12 -14
- nautobot/dcim/tests/test_signals.py +7 -4
- nautobot/dcim/tests/test_views.py +270 -264
- nautobot/dcim/urls.py +21 -26
- nautobot/dcim/views.py +14 -156
- nautobot/docs/additional-features/caching.md +6 -87
- nautobot/docs/additional-features/job-scheduling-and-approvals.md +3 -0
- nautobot/docs/additional-features/jobs.md +179 -197
- nautobot/docs/administration/nautobot-server.md +9 -24
- nautobot/docs/administration/nautobot-shell.md +6 -6
- nautobot/docs/administration/replicating-nautobot.md +0 -10
- nautobot/docs/configuration/index.md +9 -9
- nautobot/docs/configuration/optional-settings.md +32 -61
- nautobot/docs/configuration/required-settings.md +11 -52
- nautobot/docs/development/application-registry.md +2 -13
- nautobot/docs/development/best-practices.md +2 -1
- nautobot/docs/development/docker-compose-advanced-use-cases.md +1 -1
- nautobot/docs/development/extending-models.md +15 -17
- nautobot/docs/development/generic-views.md +0 -2
- nautobot/docs/development/getting-started.md +56 -6
- nautobot/docs/development/navigation-menu.md +22 -93
- nautobot/docs/development/react-ui.md +105 -0
- nautobot/docs/development/release-checklist.md +3 -3
- nautobot/docs/development/role-internals.md +1 -3
- nautobot/docs/development/style-guide.md +6 -4
- nautobot/docs/development/templates.md +2 -1
- nautobot/docs/docker/index.md +16 -14
- nautobot/docs/index.md +7 -3
- nautobot/docs/installation/index.md +4 -1
- nautobot/docs/installation/migrating-from-netbox.md +12 -43
- nautobot/docs/installation/migrating-from-postgresql.md +1 -1
- nautobot/docs/installation/nautobot.md +1 -1
- nautobot/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
- nautobot/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
- nautobot/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
- nautobot/docs/installation/tables/v2-code-location-changes.yaml +241 -0
- nautobot/docs/installation/tables/v2-code-removals.yaml +67 -0
- nautobot/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
- nautobot/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
- nautobot/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
- nautobot/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
- nautobot/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
- nautobot/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
- nautobot/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
- nautobot/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
- nautobot/docs/installation/upgrading-from-nautobot-v1.md +190 -636
- nautobot/docs/installation/upgrading.md +5 -2
- nautobot/docs/models/dcim/device.md +3 -0
- nautobot/docs/models/dcim/deviceredundancygroup.md +3 -3
- nautobot/docs/models/extras/computedfield.md +4 -4
- nautobot/docs/models/extras/dynamicgroup.md +9 -9
- nautobot/docs/models/extras/gitrepository.md +3 -0
- nautobot/docs/models/extras/job.md +1 -0
- nautobot/docs/models/extras/jobbutton.md +18 -13
- nautobot/docs/models/extras/jobhook.md +7 -4
- nautobot/docs/models/extras/jobresult.md +6 -2
- nautobot/docs/models/extras/relationship.md +2 -2
- nautobot/docs/models/extras/status.md +6 -19
- nautobot/docs/models/ipam/ipaddress.md +3 -0
- nautobot/docs/models/ipam/vrf.md +0 -3
- nautobot/docs/models/virtualization/virtualmachine.md +3 -0
- nautobot/docs/plugins/development.md +92 -24
- nautobot/docs/release-notes/version-1.5.md +96 -0
- nautobot/docs/release-notes/version-2.0.md +216 -0
- nautobot/docs/requirements.txt +5 -4
- nautobot/docs/rest-api/overview.md +384 -215
- nautobot/docs/rest-api/ui-related-endpoints.md +9 -0
- nautobot/extras/admin.py +3 -5
- nautobot/extras/api/customfields.py +15 -39
- nautobot/extras/api/fields.py +0 -11
- nautobot/extras/api/mixins.py +45 -0
- nautobot/extras/api/relationships.py +63 -159
- nautobot/extras/api/serializers.py +165 -706
- nautobot/extras/api/urls.py +1 -1
- nautobot/extras/api/views.py +295 -282
- nautobot/extras/apps.py +4 -7
- nautobot/extras/choices.py +11 -22
- nautobot/extras/constants.py +9 -3
- nautobot/extras/datasources/__init__.py +2 -0
- nautobot/extras/datasources/git.py +135 -186
- nautobot/extras/datasources/registry.py +25 -35
- nautobot/extras/factory.py +1 -3
- nautobot/extras/filters/__init__.py +49 -47
- nautobot/extras/filters/mixins.py +10 -8
- nautobot/extras/forms/forms.py +72 -148
- nautobot/extras/forms/mixins.py +34 -57
- nautobot/extras/health_checks.py +0 -33
- nautobot/extras/jobs.py +387 -566
- nautobot/extras/management/__init__.py +55 -48
- nautobot/extras/management/commands/renaturalize.py +0 -1
- nautobot/extras/management/commands/runjob.py +24 -62
- nautobot/extras/management/commands/webhook_receiver.py +0 -1
- nautobot/extras/managers.py +30 -7
- nautobot/extras/migrations/0001_initial_part_1.py +0 -1
- nautobot/extras/migrations/0002_initial_part_2.py +0 -1
- nautobot/extras/migrations/0003_initial_part_3.py +0 -1
- nautobot/extras/migrations/0004_populate_default_status_records.py +0 -1
- nautobot/extras/migrations/0005_configcontext_device_types.py +0 -1
- nautobot/extras/migrations/0006_graphqlquery.py +0 -1
- nautobot/extras/migrations/0007_configcontextschema.py +0 -1
- nautobot/extras/migrations/0008_jobresult__custom_field_data.py +0 -1
- nautobot/extras/migrations/0009_computedfield.py +0 -1
- nautobot/extras/migrations/0010_change_cf_validation_max_min_field_to_bigint.py +0 -1
- nautobot/extras/migrations/0011_fileattachment_fileproxy.py +0 -1
- nautobot/extras/migrations/0012_healthchecktestmodel.py +0 -1
- nautobot/extras/migrations/0013_default_fallback_value_computedfield.py +0 -1
- nautobot/extras/migrations/0014_auto_slug.py +0 -1
- nautobot/extras/migrations/0015_scheduled_job.py +0 -1
- nautobot/extras/migrations/0016_secret.py +0 -1
- nautobot/extras/migrations/0017_joblogentry.py +0 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +0 -2
- nautobot/extras/migrations/0019_joblogentry__meta_options__related_name.py +0 -1
- nautobot/extras/migrations/0020_customfield_changelog.py +0 -1
- nautobot/extras/migrations/0021_customfield_changelog_data.py +0 -1
- nautobot/extras/migrations/0022_objectchange_object_datav2.py +0 -1
- nautobot/extras/migrations/0023_job_model.py +0 -1
- nautobot/extras/migrations/0024_job_data_migration.py +0 -1
- nautobot/extras/migrations/0025_add_advanced_ui_boolean_to_customfield_conputedfield_and_relationship.py +0 -1
- nautobot/extras/migrations/0026_job_add_gitrepository_fk.py +0 -1
- nautobot/extras/migrations/0027_job_gitrepository_data_migration.py +0 -1
- nautobot/extras/migrations/0028_job_reduce_source.py +0 -1
- nautobot/extras/migrations/0029_dynamicgroup.py +0 -1
- nautobot/extras/migrations/0030_webhook_alter_unique_together.py +0 -1
- nautobot/extras/migrations/0031_tag_content_types.py +0 -1
- nautobot/extras/migrations/0032_tag_content_types_data_migration.py +0 -1
- nautobot/extras/migrations/0033_add__optimized_indexing.py +0 -1
- nautobot/extras/migrations/0034_alter_fileattachment_mimetype.py +0 -1
- nautobot/extras/migrations/0035_scheduledjob_crontab.py +0 -1
- nautobot/extras/migrations/0036_job_add_has_sensitive_variables.py +0 -1
- nautobot/extras/migrations/0037_configcontextschema__remove_name_unique__create_constraint_unique_name_owner.py +0 -1
- nautobot/extras/migrations/0038_configcontext_locations.py +0 -1
- nautobot/extras/migrations/0039_objectchange__add_change_context.py +0 -1
- nautobot/extras/migrations/0040_dynamicgroup__dynamicgroupmembership.py +0 -1
- nautobot/extras/migrations/0041_jobresult_job_kwargs.py +0 -1
- nautobot/extras/migrations/0042_job__add_is_job_hook_receiver.py +0 -1
- nautobot/extras/migrations/0043_note.py +0 -1
- nautobot/extras/migrations/0044_add_job_hook.py +0 -1
- nautobot/extras/migrations/0045_add_custom_field_slug.py +0 -1
- nautobot/extras/migrations/0046_populate_custom_field_slug_label.py +0 -1
- nautobot/extras/migrations/0047_enforce_custom_field_slug.py +0 -1
- nautobot/extras/migrations/0048_alter_objectchange_change_context_detail.py +0 -1
- nautobot/extras/migrations/0049_alter_tag_slug.py +0 -1
- nautobot/extras/migrations/0050_customfield_grouping.py +0 -1
- nautobot/extras/migrations/0051_add_job_task_queues.py +0 -1
- nautobot/extras/migrations/0052_configcontext_device_redundancy_groups.py +0 -1
- nautobot/extras/migrations/0053_relationship_required_on.py +0 -1
- nautobot/extras/migrations/0054_scheduledjob_kwargs_request_user_change.py +0 -1
- nautobot/extras/migrations/0055_configcontext_dynamic_groups.py +0 -1
- nautobot/extras/migrations/0056_objectchange_add_reverse_time_idx.py +0 -1
- nautobot/extras/migrations/0057_jobbutton.py +0 -1
- nautobot/extras/migrations/0058_jobresult_add_time_status_idxs.py +38 -0
- nautobot/extras/migrations/{0058_joblogentry_scheduledjob_webhook_data_migration.py → 0059_joblogentry_scheduledjob_webhook_data_migration.py} +1 -2
- nautobot/extras/migrations/{0059_alter_joblogentry_scheduledjob_webhook_fields.py → 0060_alter_joblogentry_scheduledjob_webhook_fields.py} +1 -2
- nautobot/extras/migrations/{0060_role_and_alter_status.py → 0061_role_and_alter_status.py} +1 -8
- nautobot/extras/migrations/{0061_collect_roles_from_related_apps_roles.py → 0062_collect_roles_from_related_apps_roles.py} +33 -33
- nautobot/extras/migrations/{0062_alter_role_options.py → 0063_alter_role_options.py} +1 -2
- nautobot/extras/migrations/{0063_alter_configcontext_and_add_new_role.py → 0064_alter_configcontext_and_add_new_role.py} +1 -2
- nautobot/extras/migrations/0065_configcontext_data_migrations.py +44 -0
- nautobot/extras/migrations/{0065_rename_configcontext_role.py → 0066_rename_configcontext_role.py} +1 -2
- nautobot/extras/migrations/{0066_jobresult__add_celery_fields.py → 0067_jobresult__add_celery_fields.py} +36 -3
- nautobot/extras/migrations/{0067_created_datetime.py → 0068_created_datetime.py} +1 -2
- nautobot/extras/migrations/{0068_remove_site_and_region_attributes_from_config_context.py → 0069_remove_site_and_region_attributes_from_config_context.py} +1 -2
- nautobot/extras/migrations/{0069_replace_related_names.py → 0070_replace_related_names.py} +1 -1
- nautobot/extras/migrations/{0070_rename_model_fields.py → 0071_rename_model_fields.py} +1 -2
- nautobot/extras/migrations/0072_job__unique_name_data_migration.py +86 -0
- nautobot/extras/migrations/{0072_job__unique_name.py → 0073_job__unique_name.py} +13 -10
- nautobot/extras/migrations/{0073_remove_gitrepository_fields.py → 0074_remove_gitrepository_fields.py} +1 -2
- nautobot/extras/migrations/{0074_rename_slug_to_key_for_custom_field.py → 0075_rename_slug_to_key_for_custom_field.py} +1 -1
- nautobot/extras/migrations/{0075_migrate_custom_field_data.py → 0076_migrate_custom_field_data.py} +1 -1
- nautobot/extras/migrations/{0076_remove_name_field_and_make_label_field_non_nullable.py → 0077_remove_name_field_and_make_label_field_non_nullable.py} +1 -1
- nautobot/extras/migrations/0078_remove_slug.py +45 -0
- nautobot/extras/migrations/0079_tagsfield.py +28 -0
- nautobot/extras/migrations/0080_rename_relationship_slug_to_key.py +17 -0
- nautobot/extras/migrations/0081_rename_relationship_name_to_label.py +29 -0
- nautobot/extras/migrations/0082_ensure_relationship_keys_are_unique.py +43 -0
- nautobot/extras/migrations/0083_rename_computed_field_slug_to_key.py +21 -0
- nautobot/extras/migrations/0084_taggeditem_cleanup.py +43 -0
- nautobot/extras/migrations/0085_taggeditem_uniqueness.py +22 -0
- nautobot/extras/migrations/0086_job__celery_task_fields__dryrun_support.py +81 -0
- nautobot/extras/migrations/0087_job__commit_default_data_migration.py +26 -0
- nautobot/extras/migrations/0088_joblogentry__log_level_default.py +17 -0
- nautobot/extras/migrations/0089_joblogentry__log_level_data_migration.py +34 -0
- nautobot/extras/migrations/0090_scheduledjob__data_migration.py +57 -0
- nautobot/extras/models/__init__.py +2 -3
- nautobot/extras/models/change_logging.py +0 -36
- nautobot/extras/models/customfields.py +39 -33
- nautobot/extras/models/datasources.py +48 -50
- nautobot/extras/models/groups.py +5 -12
- nautobot/extras/models/jobs.py +190 -323
- nautobot/extras/models/mixins.py +0 -71
- nautobot/extras/models/models.py +1 -22
- nautobot/extras/models/relationships.py +20 -21
- nautobot/extras/models/roles.py +0 -23
- nautobot/extras/models/secrets.py +2 -31
- nautobot/extras/models/statuses.py +6 -5
- nautobot/extras/models/tags.py +2 -17
- nautobot/extras/navigation.py +89 -307
- nautobot/extras/plugins/__init__.py +3 -121
- nautobot/extras/plugins/utils.py +0 -3
- nautobot/extras/plugins/validators.py +5 -4
- nautobot/extras/plugins/views.py +16 -4
- nautobot/extras/querysets.py +1 -7
- nautobot/extras/registry.py +3 -0
- nautobot/extras/signals.py +26 -60
- nautobot/extras/tables.py +42 -49
- nautobot/extras/tasks.py +0 -12
- nautobot/extras/templates/extras/configcontext.html +1 -1
- nautobot/extras/templates/extras/configcontextschema.html +16 -1
- nautobot/extras/templates/extras/customfield.html +0 -13
- nautobot/extras/templates/extras/dynamicgroup_edit.html +0 -1
- nautobot/extras/templates/extras/gitrepository.html +3 -3
- nautobot/extras/templates/extras/inc/jobresult.html +10 -0
- nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
- nautobot/extras/templates/extras/job.html +35 -25
- nautobot/extras/templates/extras/job_approval_request.html +15 -30
- nautobot/extras/templates/extras/job_detail.html +13 -31
- nautobot/extras/templates/extras/job_edit.html +14 -17
- nautobot/extras/templates/extras/jobresult.html +24 -6
- nautobot/extras/templates/extras/objectchange_list.html +1 -1
- nautobot/extras/templates/extras/scheduledjob.html +2 -2
- nautobot/extras/templates/extras/secret.html +28 -0
- nautobot/extras/templates/extras/secret_edit.html +0 -1
- nautobot/extras/templates/extras/secretsgroup_edit.html +0 -1
- nautobot/extras/templatetags/custom_links.py +0 -2
- nautobot/extras/templatetags/job_buttons.py +1 -0
- nautobot/extras/templatetags/plugins.py +0 -1
- nautobot/extras/{tests/example_jobs → test_jobs}/api_test_job.py +13 -6
- nautobot/extras/test_jobs/atomic_transaction.py +53 -0
- nautobot/extras/test_jobs/dry_run.py +29 -0
- nautobot/extras/{tests/example_jobs/test_duplicate_name.py → test_jobs/duplicate_name.py} +4 -0
- nautobot/extras/test_jobs/duplicate_name2.py +9 -0
- nautobot/extras/test_jobs/fail.py +23 -0
- nautobot/extras/{tests/example_jobs/test_field_default.py → test_jobs/field_default.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_field_order.py → test_jobs/field_order.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_file_upload_fail.py → test_jobs/file_upload_fail.py} +11 -6
- nautobot/extras/test_jobs/file_upload_pass.py +25 -0
- nautobot/extras/test_jobs/has_sensitive_variables.py +25 -0
- nautobot/extras/test_jobs/ipaddress_vars.py +66 -0
- nautobot/extras/test_jobs/job_button_receiver.py +28 -0
- nautobot/extras/test_jobs/job_hook_receiver.py +29 -0
- nautobot/extras/test_jobs/job_variables.py +88 -0
- nautobot/extras/test_jobs/location_with_custom_field.py +45 -0
- nautobot/extras/test_jobs/log_redaction.py +20 -0
- nautobot/extras/test_jobs/log_skip_db_logging.py +17 -0
- nautobot/extras/test_jobs/modify_db.py +25 -0
- nautobot/extras/{tests/example_jobs/test_no_field_order.py → test_jobs/no_field_order.py} +4 -0
- nautobot/extras/test_jobs/object_var_optional.py +21 -0
- nautobot/extras/test_jobs/object_var_required.py +21 -0
- nautobot/extras/test_jobs/object_vars.py +26 -0
- nautobot/extras/test_jobs/pass.py +25 -0
- nautobot/extras/test_jobs/profiling.py +32 -0
- nautobot/extras/test_jobs/read_only_job.py +15 -0
- nautobot/extras/{tests/example_jobs/test_required_args.py → test_jobs/required_args.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_soft_time_limit_greater_than_time_limit.py → test_jobs/soft_time_limit_greater_than_time_limit.py} +5 -1
- nautobot/extras/{tests/example_jobs/test_task_queues.py → test_jobs/task_queues.py} +5 -1
- nautobot/extras/tests/integration/__init__.py +3 -3
- nautobot/extras/tests/integration/test_computedfields.py +1 -1
- nautobot/extras/tests/integration/test_configcontextschema.py +7 -5
- nautobot/extras/tests/integration/test_customfields.py +4 -2
- nautobot/extras/tests/integration/test_dynamicgroups.py +2 -2
- nautobot/extras/tests/integration/test_jobs.py +25 -27
- nautobot/extras/tests/integration/test_notes.py +8 -4
- nautobot/extras/tests/integration/test_plugins.py +4 -4
- nautobot/extras/tests/integration/test_relationships.py +2 -2
- nautobot/extras/tests/test_api.py +371 -381
- nautobot/extras/tests/test_changelog.py +17 -16
- nautobot/extras/tests/test_context_managers.py +5 -6
- nautobot/extras/tests/test_customfields.py +112 -73
- nautobot/extras/tests/test_datasources.py +191 -117
- nautobot/extras/tests/test_dynamicgroups.py +45 -68
- nautobot/extras/tests/test_filters.py +170 -130
- nautobot/extras/tests/test_forms.py +107 -109
- nautobot/extras/tests/{test_scripts.py → test_job_variables.py} +43 -49
- nautobot/extras/tests/test_jobs.py +271 -273
- nautobot/extras/tests/test_management.py +3 -6
- nautobot/extras/tests/test_migrations.py +5 -3
- nautobot/extras/tests/test_models.py +121 -173
- nautobot/extras/tests/test_notes.py +0 -1
- nautobot/extras/tests/test_plugins.py +55 -89
- nautobot/extras/tests/test_relationships.py +174 -130
- nautobot/extras/tests/test_tags.py +6 -12
- nautobot/extras/tests/test_utils.py +31 -1
- nautobot/extras/tests/test_views.py +223 -184
- nautobot/extras/tests/test_webhooks.py +16 -15
- nautobot/extras/urls.py +69 -69
- nautobot/extras/utils.py +137 -163
- nautobot/extras/views.py +81 -153
- nautobot/ipam/api/fields.py +17 -0
- nautobot/ipam/api/serializers.py +77 -164
- nautobot/ipam/api/urls.py +4 -1
- nautobot/ipam/api/views.py +28 -19
- nautobot/ipam/apps.py +1 -0
- nautobot/ipam/choices.py +5 -12
- nautobot/ipam/constants.py +1 -0
- nautobot/ipam/factory.py +41 -30
- nautobot/ipam/filters.py +58 -25
- nautobot/ipam/forms.py +82 -211
- nautobot/ipam/graphql/types.py +0 -9
- nautobot/ipam/lookups.py +13 -8
- nautobot/ipam/management/commands/__init__.py +0 -0
- nautobot/ipam/management/commands/fix_prefix_broadcast.py +17 -0
- nautobot/ipam/migrations/0001_initial_part_1.py +0 -1
- nautobot/ipam/migrations/0002_initial_part_2.py +0 -1
- nautobot/ipam/migrations/0003_remove_max_length.py +0 -1
- nautobot/ipam/migrations/0004_fixup_p2p_broadcast.py +0 -1
- nautobot/ipam/migrations/0005_auto_slug.py +0 -1
- nautobot/ipam/migrations/0006_ipaddress_nat_outside_list.py +0 -1
- nautobot/ipam/migrations/0007_add_natural_indexing.py +0 -1
- nautobot/ipam/migrations/0008_prefix_vlan_vlangroup_location.py +0 -1
- nautobot/ipam/migrations/0009_alter_vlan_name.py +0 -1
- nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -2
- nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +32 -39
- nautobot/ipam/migrations/0012_rename_ipam_roles.py +0 -1
- nautobot/ipam/migrations/0013_delete_role.py +0 -1
- nautobot/ipam/migrations/0014_rename_foreign_keys_and_related_names.py +0 -1
- nautobot/ipam/migrations/0015_prefix_add_type.py +0 -1
- nautobot/ipam/migrations/0016_prefix_type_data_migration.py +0 -3
- nautobot/ipam/migrations/0017_prefix_remove_is_pool.py +0 -1
- nautobot/ipam/migrations/0018_remove_site_foreign_key_from_ipam_models.py +0 -1
- nautobot/ipam/migrations/0019_created_datetime.py +0 -1
- nautobot/ipam/migrations/0020_related_name_changes.py +1 -2
- nautobot/ipam/migrations/0021_prefix_add_rir_and_date_allocated.py +0 -1
- nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +3 -5
- nautobot/ipam/migrations/0023_delete_aggregate.py +0 -1
- nautobot/ipam/migrations/0024_interface_to_ipaddress_m2m.py +0 -1
- nautobot/ipam/migrations/0025_interface_ipaddress_m2m_data_migration.py +0 -1
- nautobot/ipam/migrations/0026_ipaddress_remove_assigned_object.py +0 -1
- nautobot/ipam/migrations/0027_remove_rir_slug.py +16 -0
- nautobot/ipam/migrations/0028_tagsfield.py +44 -0
- nautobot/ipam/migrations/0029_ip_address_to_interface_uniqueness_constraints.py +18 -0
- nautobot/ipam/migrations/0030_ipam__namespaces.py +231 -0
- nautobot/ipam/migrations/0031_ipam__prefix__add_parent.py +58 -0
- nautobot/ipam/migrations/0032_ipam__namespaces_finish.py +63 -0
- nautobot/ipam/migrations/0033_fixup_null_statuses.py +26 -0
- nautobot/ipam/migrations/0034_status_nonnullable.py +36 -0
- nautobot/ipam/models.py +579 -368
- nautobot/ipam/navigation.py +36 -159
- nautobot/ipam/querysets.py +117 -90
- nautobot/ipam/signals.py +89 -0
- nautobot/ipam/tables.py +86 -28
- nautobot/ipam/templates/ipam/ipaddress.html +14 -30
- nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -0
- nautobot/ipam/templates/ipam/namespace_ipaddresses.html +11 -0
- nautobot/ipam/templates/ipam/namespace_prefixes.html +11 -0
- nautobot/ipam/templates/ipam/namespace_retrieve.html +42 -0
- nautobot/ipam/templates/ipam/namespace_vrfs.html +11 -0
- nautobot/ipam/templates/ipam/prefix.html +27 -33
- nautobot/ipam/templates/ipam/prefix_edit.html +7 -1
- nautobot/ipam/templates/ipam/vlangroup.html +0 -13
- nautobot/ipam/templates/ipam/vrf.html +6 -4
- nautobot/ipam/templates/ipam/vrf_edit.html +20 -2
- nautobot/ipam/tests/integration/test_prefixes.py +4 -27
- nautobot/ipam/tests/test_api.py +60 -61
- nautobot/ipam/tests/test_filters.py +187 -126
- nautobot/ipam/tests/test_forms.py +12 -6
- nautobot/ipam/tests/test_graphql.py +8 -6
- nautobot/ipam/tests/test_migrations.py +8 -13
- nautobot/ipam/tests/test_models.py +426 -274
- nautobot/ipam/tests/test_ordering.py +6 -3
- nautobot/ipam/tests/test_querysets.py +340 -96
- nautobot/ipam/tests/test_views.py +100 -55
- nautobot/ipam/urls.py +28 -5
- nautobot/ipam/{utils.py → utils/__init__.py} +2 -2
- nautobot/ipam/utils/migrations.py +713 -0
- nautobot/ipam/views.py +237 -122
- nautobot/project-static/docs/404.html +1399 -166
- nautobot/project-static/docs/additional-features/caching.html +1416 -320
- nautobot/project-static/docs/additional-features/change-logging.html +1389 -190
- nautobot/project-static/docs/additional-features/config-contexts.html +1389 -190
- nautobot/project-static/docs/additional-features/graphql.html +1389 -190
- nautobot/project-static/docs/additional-features/healthcheck.html +1389 -190
- nautobot/project-static/docs/additional-features/job-scheduling-and-approvals.html +1393 -190
- nautobot/project-static/docs/additional-features/jobs.html +1677 -460
- nautobot/project-static/docs/additional-features/napalm.html +1389 -190
- nautobot/project-static/docs/additional-features/prometheus-metrics.html +1389 -190
- nautobot/project-static/docs/additional-features/template-filters.html +1389 -190
- nautobot/project-static/docs/administration/celery-queues.html +1389 -190
- nautobot/project-static/docs/administration/nautobot-server.html +1553 -375
- nautobot/project-static/docs/administration/nautobot-shell.html +1395 -196
- nautobot/project-static/docs/administration/permissions.html +1389 -190
- nautobot/project-static/docs/administration/replicating-nautobot.html +1387 -207
- nautobot/project-static/docs/apps/index.html +1389 -190
- nautobot/project-static/docs/apps/nautobot-apps.html +1387 -175
- nautobot/project-static/docs/assets/javascripts/bundle.51198bba.min.js +29 -0
- nautobot/project-static/docs/assets/javascripts/bundle.51198bba.min.js.map +8 -0
- nautobot/project-static/docs/assets/javascripts/workers/{search.16e2a7d4.min.js → search.208ed371.min.js} +9 -15
- nautobot/project-static/docs/assets/javascripts/workers/{search.16e2a7d4.min.js.map → search.208ed371.min.js.map} +4 -4
- nautobot/project-static/docs/assets/stylesheets/main.ded33207.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.ded33207.min.css.map +1 -0
- nautobot/project-static/docs/assets/stylesheets/palette.a0c5b2b5.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/palette.a0c5b2b5.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +1775 -590
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +1389 -190
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +3588 -1922
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +1461 -262
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +1401 -170
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +1396 -191
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +2095 -894
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2357 -1194
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +2258 -940
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +1389 -190
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1400 -201
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +11068 -7861
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2867 -2224
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +1389 -190
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2641 -1573
- nautobot/project-static/docs/configuration/authentication/ldap.html +1389 -190
- nautobot/project-static/docs/configuration/authentication/remote.html +1389 -190
- nautobot/project-static/docs/configuration/authentication/sso.html +1389 -190
- nautobot/project-static/docs/configuration/index.html +1398 -199
- nautobot/project-static/docs/configuration/optional-settings.html +1418 -274
- nautobot/project-static/docs/configuration/required-settings.html +1419 -287
- nautobot/project-static/docs/core-functionality/circuits.html +1446 -247
- nautobot/project-static/docs/core-functionality/device-types.html +1448 -249
- nautobot/project-static/docs/core-functionality/devices.html +1452 -249
- nautobot/project-static/docs/core-functionality/ipam.html +1452 -253
- nautobot/project-static/docs/core-functionality/power.html +1448 -249
- nautobot/project-static/docs/core-functionality/secrets.html +1448 -249
- nautobot/project-static/docs/core-functionality/services.html +1448 -249
- nautobot/project-static/docs/core-functionality/sites-and-racks.html +1448 -249
- nautobot/project-static/docs/core-functionality/tenancy.html +1448 -249
- nautobot/project-static/docs/core-functionality/virtualization.html +1452 -249
- nautobot/project-static/docs/core-functionality/vlans.html +1448 -249
- nautobot/project-static/docs/development/application-registry.html +1393 -214
- nautobot/project-static/docs/development/best-practices.html +1392 -192
- nautobot/project-static/docs/development/docker-compose-advanced-use-cases.html +1390 -191
- nautobot/project-static/docs/development/extending-models.html +1443 -257
- nautobot/project-static/docs/development/generic-views.html +1403 -174
- nautobot/project-static/docs/development/getting-started.html +1568 -262
- nautobot/project-static/docs/development/homepage.html +1389 -190
- nautobot/project-static/docs/development/index.html +1389 -190
- nautobot/project-static/docs/development/model-features.html +1389 -190
- nautobot/project-static/docs/development/natural-keys.html +1389 -190
- nautobot/project-static/docs/development/navigation-menu.html +1451 -330
- nautobot/project-static/docs/development/react-ui.html +4199 -0
- nautobot/project-static/docs/development/release-checklist.html +1392 -193
- nautobot/project-static/docs/development/role-internals.html +1402 -172
- nautobot/project-static/docs/development/style-guide.html +1399 -199
- nautobot/project-static/docs/development/templates.html +1391 -191
- nautobot/project-static/docs/development/testing.html +1389 -190
- nautobot/project-static/docs/development/user-preferences.html +1389 -190
- nautobot/project-static/docs/docker/index.html +1408 -206
- nautobot/project-static/docs/index.html +1397 -180
- nautobot/project-static/docs/installation/centos.html +1401 -170
- nautobot/project-static/docs/installation/external-authentication.html +1389 -190
- nautobot/project-static/docs/installation/http-server.html +1389 -190
- nautobot/project-static/docs/installation/index.html +1394 -191
- nautobot/project-static/docs/installation/migrating-from-netbox.html +1452 -305
- nautobot/project-static/docs/installation/migrating-from-postgresql.html +1390 -191
- nautobot/project-static/docs/installation/nautobot.html +1390 -191
- nautobot/project-static/docs/installation/region-and-site-data-migration-guide.html +1389 -190
- nautobot/project-static/docs/installation/selinux-troubleshooting.html +1401 -170
- nautobot/project-static/docs/installation/services.html +1389 -190
- nautobot/project-static/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
- nautobot/project-static/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
- nautobot/project-static/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
- nautobot/project-static/docs/installation/tables/v2-code-location-changes.yaml +241 -0
- nautobot/project-static/docs/installation/tables/v2-code-removals.yaml +67 -0
- nautobot/project-static/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
- nautobot/project-static/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
- nautobot/project-static/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
- nautobot/project-static/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
- nautobot/project-static/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
- nautobot/project-static/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
- nautobot/project-static/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
- nautobot/project-static/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
- nautobot/project-static/docs/installation/ubuntu.html +1401 -170
- nautobot/project-static/docs/installation/upgrading-from-nautobot-v1.html +4254 -1923
- nautobot/project-static/docs/installation/upgrading.html +1395 -192
- nautobot/project-static/docs/models/circuits/circuit.html +1427 -174
- nautobot/project-static/docs/models/circuits/circuittermination.html +1427 -174
- nautobot/project-static/docs/models/circuits/circuittype.html +1427 -174
- nautobot/project-static/docs/models/circuits/provider.html +1427 -174
- nautobot/project-static/docs/models/circuits/providernetwork.html +1427 -174
- nautobot/project-static/docs/models/dcim/cable.html +1458 -174
- nautobot/project-static/docs/models/dcim/consoleport.html +1427 -174
- nautobot/project-static/docs/models/dcim/consoleporttemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/consoleserverport.html +1427 -174
- nautobot/project-static/docs/models/dcim/consoleserverporttemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/device.html +1431 -174
- nautobot/project-static/docs/models/dcim/devicebay.html +1427 -174
- nautobot/project-static/docs/models/dcim/devicebaytemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/deviceredundancygroup.html +1522 -177
- nautobot/project-static/docs/models/dcim/devicetype.html +1427 -174
- nautobot/project-static/docs/models/dcim/frontport.html +1427 -174
- nautobot/project-static/docs/models/dcim/frontporttemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/interface.html +1427 -174
- nautobot/project-static/docs/models/dcim/interfacetemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/inventoryitem.html +1427 -174
- nautobot/project-static/docs/models/dcim/location.html +1427 -174
- nautobot/project-static/docs/models/dcim/locationtype.html +1427 -174
- nautobot/project-static/docs/models/dcim/manufacturer.html +1427 -174
- nautobot/project-static/docs/models/dcim/platform.html +1427 -174
- nautobot/project-static/docs/models/dcim/powerfeed.html +1425 -172
- nautobot/project-static/docs/models/dcim/poweroutlet.html +1427 -174
- nautobot/project-static/docs/models/dcim/poweroutlettemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/powerpanel.html +1425 -172
- nautobot/project-static/docs/models/dcim/powerport.html +1427 -174
- nautobot/project-static/docs/models/dcim/powerporttemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/rack.html +1427 -174
- nautobot/project-static/docs/models/dcim/rackgroup.html +1427 -174
- nautobot/project-static/docs/models/dcim/rackreservation.html +1427 -174
- nautobot/project-static/docs/models/dcim/rearport.html +1427 -174
- nautobot/project-static/docs/models/dcim/rearporttemplate.html +1427 -174
- nautobot/project-static/docs/models/dcim/region.html +1401 -170
- nautobot/project-static/docs/models/dcim/site.html +1401 -170
- nautobot/project-static/docs/models/dcim/virtualchassis.html +1425 -172
- nautobot/project-static/docs/models/extras/computedfield.html +1393 -194
- nautobot/project-static/docs/models/extras/configcontext.html +1465 -174
- nautobot/project-static/docs/models/extras/configcontextschema.html +1421 -168
- nautobot/project-static/docs/models/extras/customfield.html +1389 -190
- nautobot/project-static/docs/models/extras/customlink.html +1389 -190
- nautobot/project-static/docs/models/extras/dynamicgroup.html +1398 -199
- nautobot/project-static/docs/models/extras/exporttemplate.html +1389 -190
- nautobot/project-static/docs/models/extras/gitrepository.html +1393 -190
- nautobot/project-static/docs/models/extras/graphqlquery.html +1469 -171
- nautobot/project-static/docs/models/extras/imageattachment.html +1434 -181
- nautobot/project-static/docs/models/extras/job.html +1411 -157
- nautobot/project-static/docs/models/extras/jobbutton.html +1410 -207
- nautobot/project-static/docs/models/extras/jobhook.html +1397 -194
- nautobot/project-static/docs/models/extras/joblogentry.html +1408 -155
- nautobot/project-static/docs/models/extras/jobresult.html +1417 -159
- nautobot/project-static/docs/models/extras/note.html +1389 -190
- nautobot/project-static/docs/models/extras/relationship.html +1391 -192
- nautobot/project-static/docs/models/extras/role.html +1495 -198
- nautobot/project-static/docs/models/extras/secret.html +1492 -201
- nautobot/project-static/docs/models/extras/secretsgroup.html +1410 -157
- nautobot/project-static/docs/models/extras/status.html +1381 -221
- nautobot/project-static/docs/models/extras/tag.html +1389 -190
- nautobot/project-static/docs/models/extras/webhook.html +1389 -190
- nautobot/project-static/docs/models/ipam/ipaddress.html +1488 -200
- nautobot/project-static/docs/models/ipam/prefix.html +1410 -157
- nautobot/project-static/docs/models/ipam/rir.html +1410 -157
- nautobot/project-static/docs/models/ipam/routetarget.html +1410 -157
- nautobot/project-static/docs/models/ipam/service.html +1410 -157
- nautobot/project-static/docs/models/ipam/vlan.html +1410 -157
- nautobot/project-static/docs/models/ipam/vlangroup.html +1410 -157
- nautobot/project-static/docs/models/ipam/vrf.html +1410 -161
- nautobot/project-static/docs/models/tenancy/tenant.html +1412 -159
- nautobot/project-static/docs/models/tenancy/tenantgroup.html +1412 -159
- nautobot/project-static/docs/models/users/objectpermission.html +1462 -171
- nautobot/project-static/docs/models/users/token.html +1410 -157
- nautobot/project-static/docs/models/virtualization/cluster.html +1410 -157
- nautobot/project-static/docs/models/virtualization/clustergroup.html +1410 -157
- nautobot/project-static/docs/models/virtualization/clustertype.html +1410 -157
- nautobot/project-static/docs/models/virtualization/virtualmachine.html +1414 -157
- nautobot/project-static/docs/models/virtualization/vminterface.html +1410 -157
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/plugins/development.html +1916 -646
- nautobot/project-static/docs/plugins/index.html +1389 -190
- nautobot/project-static/docs/plugins/porting-from-netbox.html +1389 -190
- nautobot/project-static/docs/release-notes/index.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.0.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.1.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.2.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.3.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.4.html +1389 -190
- nautobot/project-static/docs/release-notes/version-1.5.html +2016 -397
- nautobot/project-static/docs/release-notes/version-2.0.html +1935 -287
- nautobot/project-static/docs/requirements.txt +5 -4
- nautobot/project-static/docs/rest-api/authentication.html +1389 -190
- nautobot/project-static/docs/rest-api/filtering.html +1389 -190
- nautobot/project-static/docs/rest-api/overview.html +2002 -576
- nautobot/project-static/docs/rest-api/ui-related-endpoints.html +4057 -0
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +197 -187
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guides/custom-fields.html +1390 -191
- nautobot/project-static/docs/user-guides/getting-started/creating-devices.html +1392 -193
- nautobot/project-static/docs/user-guides/getting-started/index.html +1388 -189
- nautobot/project-static/docs/user-guides/getting-started/interfaces.html +1388 -189
- nautobot/project-static/docs/user-guides/getting-started/ipam.html +1386 -187
- nautobot/project-static/docs/user-guides/getting-started/platforms.html +1448 -249
- nautobot/project-static/docs/user-guides/getting-started/regions.html +1411 -212
- nautobot/project-static/docs/user-guides/getting-started/search-bar.html +1395 -196
- nautobot/project-static/docs/user-guides/getting-started/tenants.html +1448 -249
- nautobot/project-static/docs/user-guides/getting-started/vlans-and-vlan-groups.html +1448 -249
- nautobot/project-static/docs/user-guides/git-data-source.html +1405 -206
- nautobot/project-static/docs/user-guides/graphql.html +1402 -203
- nautobot/project-static/docs/user-guides/relationships.html +1448 -249
- nautobot/project-static/docs/user-guides/s3-django-storage.html +1448 -249
- nautobot/project-static/js/forms.js +16 -9
- nautobot/project-static/js/theme.js +5 -0
- nautobot/tenancy/api/serializers.py +4 -34
- nautobot/tenancy/api/urls.py +1 -1
- nautobot/tenancy/filters/__init__.py +9 -7
- nautobot/tenancy/filters/mixins.py +3 -2
- nautobot/tenancy/forms.py +3 -36
- nautobot/tenancy/migrations/0001_initial.py +0 -1
- nautobot/tenancy/migrations/0002_auto_slug.py +0 -1
- nautobot/tenancy/migrations/0003_mptt_to_tree_queries.py +0 -1
- nautobot/tenancy/migrations/0004_change_tree_manager_on_tree_models.py +0 -1
- nautobot/tenancy/migrations/0005_rename_foreign_keys_and_related_names.py +0 -1
- nautobot/tenancy/migrations/0006_created_datetime.py +0 -1
- nautobot/tenancy/migrations/0007_remove_tenant_tenantgroup_slug.py +20 -0
- nautobot/tenancy/migrations/0008_tagsfield.py +19 -0
- nautobot/tenancy/models.py +0 -30
- nautobot/tenancy/navigation.py +6 -39
- nautobot/tenancy/tables.py +4 -4
- nautobot/tenancy/templates/tenancy/tenant.html +12 -12
- nautobot/tenancy/templates/tenancy/tenant_edit.html +0 -1
- nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
- nautobot/tenancy/tests/test_api.py +1 -12
- nautobot/tenancy/tests/test_filters.py +20 -12
- nautobot/tenancy/tests/test_views.py +11 -29
- nautobot/tenancy/urls.py +10 -10
- nautobot/tenancy/views.py +0 -3
- nautobot/ui/.eslintignore +6 -0
- nautobot/ui/.gitignore +10 -0
- nautobot/ui/.prettierignore +9 -0
- nautobot/ui/.prettierrc +4 -0
- nautobot/ui/README.md +33 -0
- nautobot/ui/app_imports.js.j2 +7 -0
- nautobot/ui/craco.config.js +46 -0
- nautobot/ui/jsconfig-base.json +11 -0
- nautobot/ui/jsconfig.json +5 -0
- nautobot/ui/lib/nautobot-craco-alias-plugin.js +40 -0
- nautobot/ui/package-lock.json +21451 -0
- nautobot/ui/package.json +70 -0
- nautobot/ui/public/index.html +47 -0
- nautobot/ui/public/logo192.png +0 -0
- nautobot/ui/public/logo512.png +0 -0
- nautobot/ui/public/manifest.json +25 -0
- nautobot/ui/public/nautobot_logo.svg +131 -0
- nautobot/ui/public/robots.txt +3 -0
- nautobot/ui/src/App.js +71 -0
- nautobot/ui/src/components/AppFullWidthComponents.js +8 -0
- nautobot/ui/src/components/AppTab.js +40 -0
- nautobot/ui/src/components/Apps.js +60 -0
- nautobot/ui/src/components/HomeChangelogPanel.js +98 -0
- nautobot/ui/src/components/HomePanel.js +58 -0
- nautobot/ui/src/components/JobHistoryTable.js +78 -0
- nautobot/ui/src/components/Layout.js +53 -0
- nautobot/ui/src/components/LoadingWidget.js +25 -0
- nautobot/ui/src/components/Navbar.js +116 -0
- nautobot/ui/src/components/NotificationPopover.js +27 -0
- nautobot/ui/src/components/ObjectListTable.js +209 -0
- nautobot/ui/src/components/ReferenceDataTag.js +35 -0
- nautobot/ui/src/components/RouterButton.js +10 -0
- nautobot/ui/src/components/RouterLink.js +10 -0
- nautobot/ui/src/components/SidebarNav.js +147 -0
- nautobot/ui/src/components/Table.js +48 -0
- nautobot/ui/src/components/TableItem.js +71 -0
- nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +16 -0
- nautobot/ui/src/components/__tests__/AppTab.test.js +21 -0
- nautobot/ui/src/components/__tests__/Apps.test.js +14 -0
- nautobot/ui/src/components/__tests__/Layout.test.js +33 -0
- nautobot/ui/src/components/__tests__/Table.test.js +36 -0
- nautobot/ui/src/components/__tests__/TableItem.test.js +37 -0
- nautobot/ui/src/components/__tests__/paginator.test.js +43 -0
- nautobot/ui/src/components/__tests__/paginator_form.test.js +13 -0
- nautobot/ui/src/components/pagination.js +93 -0
- nautobot/ui/src/components/paginator.js +79 -0
- nautobot/ui/src/components/paginator_form.js +43 -0
- nautobot/ui/src/components/usePagination.js +57 -0
- nautobot/ui/src/constants/apiPath.js +10 -0
- nautobot/ui/src/constants/icons.js +15 -0
- nautobot/ui/src/constants/size.js +15 -0
- nautobot/ui/src/index.js +65 -0
- nautobot/ui/src/reportWebVitals.js +15 -0
- nautobot/ui/src/router.js +77 -0
- nautobot/ui/src/utils/api.js +131 -0
- nautobot/ui/src/utils/app-import.js +15 -0
- nautobot/ui/src/utils/color.js +15 -0
- nautobot/ui/src/utils/date.js +14 -0
- nautobot/ui/src/utils/index.js +15 -0
- nautobot/ui/src/utils/navigation.js +32 -0
- nautobot/ui/src/utils/session.js +64 -0
- nautobot/ui/src/utils/store.js +242 -0
- nautobot/ui/src/utils/string.js +6 -0
- nautobot/ui/src/utils/url.js +4 -0
- nautobot/ui/src/views/Home.js +138 -0
- nautobot/ui/src/views/InstalledApps.js +80 -0
- nautobot/ui/src/views/Login.js +48 -0
- nautobot/ui/src/views/Logout.js +20 -0
- nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +11 -0
- nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +107 -0
- nautobot/ui/src/views/__tests__/Login.test.js +15 -0
- nautobot/ui/src/views/generic/GenericView.js +142 -0
- nautobot/ui/src/views/generic/ObjectCreate.js +96 -0
- nautobot/ui/src/views/generic/ObjectList.js +127 -0
- nautobot/ui/src/views/generic/ObjectRetrieve.js +551 -0
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +51 -61
- nautobot/users/api/urls.py +1 -1
- nautobot/users/api/views.py +53 -2
- nautobot/users/migrations/0001_initial.py +0 -1
- nautobot/users/migrations/0002_token_ordering_by_created.py +0 -1
- nautobot/users/migrations/0003_alter_user_options.py +0 -1
- nautobot/users/migrations/0004_alter_user_managers.py +0 -1
- nautobot/users/tests/test_api.py +109 -28
- nautobot/users/tests/test_filters.py +0 -4
- nautobot/users/tests/test_models.py +0 -1
- nautobot/users/views.py +0 -7
- nautobot/virtualization/api/serializers.py +18 -132
- nautobot/virtualization/api/urls.py +1 -1
- nautobot/virtualization/api/views.py +1 -22
- nautobot/virtualization/choices.py +0 -2
- nautobot/virtualization/filters.py +12 -7
- nautobot/virtualization/forms.py +21 -117
- nautobot/virtualization/migrations/0001_initial.py +0 -1
- nautobot/virtualization/migrations/0002_virtualmachine_local_context_schema.py +0 -1
- nautobot/virtualization/migrations/0003_vminterface_verbose_name.py +0 -1
- nautobot/virtualization/migrations/0004_auto_slug.py +0 -1
- nautobot/virtualization/migrations/0005_add_natural_indexing.py +0 -1
- nautobot/virtualization/migrations/0006_vminterface_status.py +0 -1
- nautobot/virtualization/migrations/0007_vminterface_status_data_migration.py +0 -1
- nautobot/virtualization/migrations/0008_vminterface_parent.py +0 -1
- nautobot/virtualization/migrations/0009_cluster_location.py +0 -1
- nautobot/virtualization/migrations/0010_vminterface_mac_address_data_migration.py +0 -1
- nautobot/virtualization/migrations/0011_alter_vminterface_mac_address.py +0 -1
- nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -2
- nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +18 -12
- nautobot/virtualization/migrations/0014_rename_virtualmachine_roles.py +0 -1
- nautobot/virtualization/migrations/0015_rename_foreignkey_fields.py +1 -2
- nautobot/virtualization/migrations/0016_remove_site_foreign_key_from_cluster_class.py +0 -1
- nautobot/virtualization/migrations/0017_created_datetime.py +0 -1
- nautobot/virtualization/migrations/0018_related_name_changes.py +1 -2
- nautobot/virtualization/migrations/0019_vminterface_ip_addresses_m2m.py +0 -1
- nautobot/virtualization/migrations/0020_remove_clustergroup_clustertype_slug.py +20 -0
- nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +39 -0
- nautobot/virtualization/migrations/0022_vminterface_timestamps_data_migration.py +17 -0
- nautobot/virtualization/migrations/0023_ipam__namespaces.py +25 -0
- nautobot/virtualization/migrations/0024_fixup_null_statuses.py +25 -0
- nautobot/virtualization/migrations/0025_status_nonnullable.py +29 -0
- nautobot/virtualization/models.py +39 -131
- nautobot/virtualization/navigation.py +18 -99
- nautobot/virtualization/tables.py +4 -4
- nautobot/virtualization/templates/virtualization/virtualmachine.html +13 -2
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +6 -0
- nautobot/virtualization/tests/test_api.py +42 -52
- nautobot/virtualization/tests/test_filters.py +98 -75
- nautobot/virtualization/tests/test_models.py +36 -13
- nautobot/virtualization/tests/test_views.py +68 -73
- nautobot/virtualization/urls.py +10 -10
- nautobot/virtualization/views.py +8 -14
- {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/METADATA +15 -22
- {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/RECORD +987 -834
- {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/WHEEL +1 -1
- nautobot/circuits/api/nested_serializers.py +0 -69
- nautobot/core/templates/plugin_template/navigation.py-tpl +0 -22
- nautobot/dcim/api/nested_serializers.py +0 -356
- nautobot/dcim/templates/dcim/device_import.html +0 -5
- nautobot/dcim/templates/dcim/device_import_child.html +0 -5
- nautobot/dcim/templates/dcim/inc/device_import_header.html +0 -4
- nautobot/extras/api/nested_serializers.py +0 -353
- nautobot/extras/migrations/0064_configcontext_data_migrations.py +0 -42
- nautobot/extras/migrations/0071_job__unique_name_data_migration.py +0 -47
- nautobot/extras/reports.py +0 -60
- nautobot/extras/scripts.py +0 -72
- nautobot/extras/tests/example_jobs/script_variables.py +0 -67
- nautobot/extras/tests/example_jobs/test_duplicate_name2.py +0 -5
- nautobot/extras/tests/example_jobs/test_fail.py +0 -16
- nautobot/extras/tests/example_jobs/test_file_upload_pass.py +0 -20
- nautobot/extras/tests/example_jobs/test_ipaddress_vars.py +0 -52
- nautobot/extras/tests/example_jobs/test_job_button_receiver.py +0 -21
- nautobot/extras/tests/example_jobs/test_job_hook_receiver.py +0 -20
- nautobot/extras/tests/example_jobs/test_location_with_custom_field.py +0 -35
- nautobot/extras/tests/example_jobs/test_log_redaction.py +0 -14
- nautobot/extras/tests/example_jobs/test_modify_db.py +0 -19
- nautobot/extras/tests/example_jobs/test_object_var_optional.py +0 -14
- nautobot/extras/tests/example_jobs/test_object_var_required.py +0 -14
- nautobot/extras/tests/example_jobs/test_object_vars.py +0 -29
- nautobot/extras/tests/example_jobs/test_pass.py +0 -19
- nautobot/extras/tests/example_jobs/test_read_only_fail.py +0 -24
- nautobot/extras/tests/example_jobs/test_read_only_no_commit_field.py +0 -10
- nautobot/extras/tests/example_jobs/test_read_only_pass.py +0 -22
- nautobot/ipam/api/nested_serializers.py +0 -143
- nautobot/project-static/docs/assets/javascripts/bundle.5a2dcb6a.min.js +0 -29
- nautobot/project-static/docs/assets/javascripts/bundle.5a2dcb6a.min.js.map +0 -8
- nautobot/project-static/docs/assets/javascripts/extra/bundle.5f09fbc3.min.js +0 -18
- nautobot/project-static/docs/assets/javascripts/extra/bundle.5f09fbc3.min.js.map +0 -8
- nautobot/project-static/docs/assets/stylesheets/extra.0d2c79a8.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/extra.0d2c79a8.min.css.map +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.975780f9.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.975780f9.min.css.map +0 -1
- nautobot/project-static/docs/assets/stylesheets/palette.2505c338.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/palette.2505c338.min.css.map +0 -1
- nautobot/tenancy/api/nested_serializers.py +0 -31
- nautobot/users/api/nested_serializers.py +0 -67
- nautobot/virtualization/api/nested_serializers.py +0 -65
- /nautobot/extras/{tests/example_jobs → test_jobs}/__init__.py +0 -0
- /nautobot/{dcim/models/sites.py → ipam/management/__init__.py} +0 -0
- {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.0.0a2.dist-info → nautobot-2.0.0b1.dist-info}/entry_points.txt +0 -0
nautobot/core/constants.py
CHANGED
|
@@ -6,49 +6,31 @@ SEARCH_MAX_RESULTS = 15
|
|
|
6
6
|
|
|
7
7
|
SEARCH_MAX_RESULTS = 15
|
|
8
8
|
|
|
9
|
-
FILTER_CHAR_BASED_LOOKUP_MAP =
|
|
10
|
-
n
|
|
11
|
-
ic
|
|
12
|
-
nic
|
|
13
|
-
iew
|
|
14
|
-
niew
|
|
15
|
-
isw
|
|
16
|
-
nisw
|
|
17
|
-
ie
|
|
18
|
-
nie
|
|
19
|
-
re
|
|
20
|
-
nre
|
|
21
|
-
ire
|
|
22
|
-
nire
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
FILTER_NUMERIC_BASED_LOOKUP_MAP =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
HTTP_REQUEST_META_SAFE_COPY = [
|
|
35
|
-
"CONTENT_LENGTH",
|
|
36
|
-
"CONTENT_TYPE",
|
|
37
|
-
"HTTP_ACCEPT",
|
|
38
|
-
"HTTP_ACCEPT_ENCODING",
|
|
39
|
-
"HTTP_ACCEPT_LANGUAGE",
|
|
40
|
-
"HTTP_HOST",
|
|
41
|
-
"HTTP_REFERER",
|
|
42
|
-
"HTTP_USER_AGENT",
|
|
43
|
-
"QUERY_STRING",
|
|
44
|
-
"REMOTE_ADDR",
|
|
45
|
-
"REMOTE_HOST",
|
|
46
|
-
"REMOTE_USER",
|
|
47
|
-
"REQUEST_METHOD",
|
|
48
|
-
"SERVER_NAME",
|
|
49
|
-
"SERVER_PORT",
|
|
50
|
-
]
|
|
51
|
-
|
|
9
|
+
FILTER_CHAR_BASED_LOOKUP_MAP = {
|
|
10
|
+
"n": "exact",
|
|
11
|
+
"ic": "icontains",
|
|
12
|
+
"nic": "icontains",
|
|
13
|
+
"iew": "iendswith",
|
|
14
|
+
"niew": "iendswith",
|
|
15
|
+
"isw": "istartswith",
|
|
16
|
+
"nisw": "istartswith",
|
|
17
|
+
"ie": "iexact",
|
|
18
|
+
"nie": "iexact",
|
|
19
|
+
"re": "regex",
|
|
20
|
+
"nre": "regex",
|
|
21
|
+
"ire": "iregex",
|
|
22
|
+
"nire": "iregex",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
FILTER_NUMERIC_BASED_LOOKUP_MAP = {
|
|
26
|
+
"n": "exact",
|
|
27
|
+
"lte": "lte",
|
|
28
|
+
"lt": "lt",
|
|
29
|
+
"gte": "gte",
|
|
30
|
+
"gt": "gt",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
FILTER_NEGATION_LOOKUP_MAP = {"n": "exact"}
|
|
52
34
|
|
|
53
35
|
#
|
|
54
36
|
# Factory defaults
|
|
@@ -34,8 +34,20 @@ def settings(request):
|
|
|
34
34
|
Expose Django settings in the template context. Example: {{ settings.DEBUG }}
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
|
+
use_new_ui = request.COOKIES.get("newui", False)
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
view_class = request.resolver_match.func.view_class
|
|
41
|
+
use_new_ui = use_new_ui and getattr(view_class, "use_new_ui", False)
|
|
42
|
+
except AttributeError:
|
|
43
|
+
# Use this method to import the view class views that inherits from
|
|
44
|
+
# NautobotUIViewSet, as this views do not have the 'view_class' attribute.
|
|
45
|
+
if hasattr(request, "accepted_renderer"):
|
|
46
|
+
use_new_ui = use_new_ui and getattr(request.accepted_renderer, "use_new_ui", False)
|
|
47
|
+
|
|
37
48
|
return {
|
|
38
49
|
"settings": django_settings,
|
|
50
|
+
"root_template": "base_react.html" if use_new_ui else "base_django.html",
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
|
nautobot/core/filters.py
CHANGED
|
@@ -12,7 +12,6 @@ from django_filters.constants import EMPTY_VALUES
|
|
|
12
12
|
from django_filters.utils import get_model_field, resolve_field
|
|
13
13
|
from drf_spectacular.types import OpenApiTypes
|
|
14
14
|
from drf_spectacular.utils import extend_schema_field
|
|
15
|
-
from taggit.managers import TaggableManager
|
|
16
15
|
|
|
17
16
|
from nautobot.core import constants, forms
|
|
18
17
|
from nautobot.core.forms import widgets
|
|
@@ -557,7 +556,7 @@ class BaseFilterSet(django_filters.FilterSet):
|
|
|
557
556
|
models.URLField: {"filter_class": MultiValueCharFilter},
|
|
558
557
|
models.UUIDField: {"filter_class": MultiValueUUIDFilter},
|
|
559
558
|
core_fields.MACAddressCharField: {"filter_class": MultiValueMACAddressFilter},
|
|
560
|
-
|
|
559
|
+
core_fields.TagsField: {"filter_class": TagFilter},
|
|
561
560
|
}
|
|
562
561
|
)
|
|
563
562
|
|
|
@@ -763,4 +762,5 @@ class NameSlugSearchFilterSet(django_filters.FilterSet):
|
|
|
763
762
|
A base class for adding the search method to models which only expose the `name` and `slug` fields
|
|
764
763
|
"""
|
|
765
764
|
|
|
765
|
+
# TODO Modify and rename this class after slugs are removed from all models.
|
|
766
766
|
q = SearchFilter(filter_predicates={"name": "icontains", "slug": "icontains"})
|
nautobot/core/forms/__init__.py
CHANGED
|
@@ -52,10 +52,8 @@ from nautobot.core.forms.utils import (
|
|
|
52
52
|
expand_ipaddress_pattern,
|
|
53
53
|
form_from_model,
|
|
54
54
|
parse_alphanumeric_range,
|
|
55
|
-
parse_csv,
|
|
56
55
|
parse_numeric_range,
|
|
57
56
|
restrict_form_fields,
|
|
58
|
-
validate_csv,
|
|
59
57
|
)
|
|
60
58
|
from nautobot.core.forms.widgets import (
|
|
61
59
|
APISelect,
|
|
@@ -125,7 +123,6 @@ __all__ = (
|
|
|
125
123
|
"NUMERIC_EXPANSION_PATTERN",
|
|
126
124
|
"NumericArrayField",
|
|
127
125
|
"parse_alphanumeric_range",
|
|
128
|
-
"parse_csv",
|
|
129
126
|
"parse_numeric_range",
|
|
130
127
|
"PrefixFieldMixin",
|
|
131
128
|
"restrict_form_fields",
|
|
@@ -141,5 +138,4 @@ __all__ = (
|
|
|
141
138
|
"TableConfigForm",
|
|
142
139
|
"TagFilterField",
|
|
143
140
|
"TimePicker",
|
|
144
|
-
"validate_csv",
|
|
145
141
|
)
|
nautobot/core/forms/fields.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
from io import StringIO
|
|
3
1
|
import json
|
|
4
2
|
import re
|
|
5
3
|
|
|
@@ -50,21 +48,22 @@ __all__ = (
|
|
|
50
48
|
|
|
51
49
|
class CSVDataField(django_forms.CharField):
|
|
52
50
|
"""
|
|
53
|
-
A CharField (rendered as a Textarea) which
|
|
54
|
-
item is a dictionary of column headers, mapping field names to the attribute by which they match a related object
|
|
55
|
-
(where applicable). The second item is a list of dictionaries, each representing a discrete row of CSV data.
|
|
51
|
+
A CharField (rendered as a Textarea) which expects CSV-formatted data.
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
Initial value is a list of headers corresponding to the required fields for the given serializer class.
|
|
54
|
+
|
|
55
|
+
This no longer actually does any CSV parsing or validation on its own,
|
|
56
|
+
as that is now handled by the NautobotCSVParser class and the REST API serializers.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
required_field_names: List of field names representing required fields for this import.
|
|
58
60
|
"""
|
|
59
61
|
|
|
60
62
|
widget = django_forms.Textarea
|
|
61
63
|
|
|
62
|
-
def __init__(self,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
self.model = form.Meta.model
|
|
66
|
-
self.fields = form.fields
|
|
67
|
-
self.required_fields = [name for name, field in form.fields.items() if field.required]
|
|
64
|
+
def __init__(self, *args, required_field_names="", **kwargs):
|
|
65
|
+
self.required_field_names = required_field_names
|
|
66
|
+
kwargs.setdefault("required", False)
|
|
68
67
|
|
|
69
68
|
super().__init__(*args, **kwargs)
|
|
70
69
|
|
|
@@ -72,7 +71,7 @@ class CSVDataField(django_forms.CharField):
|
|
|
72
71
|
if not self.label:
|
|
73
72
|
self.label = ""
|
|
74
73
|
if not self.initial:
|
|
75
|
-
self.initial = ",".join(self.
|
|
74
|
+
self.initial = ",".join(self.required_field_names) + "\n"
|
|
76
75
|
if not self.help_text:
|
|
77
76
|
self.help_text = (
|
|
78
77
|
"Enter the list of column headers followed by one line per record to be imported, using "
|
|
@@ -80,37 +79,17 @@ class CSVDataField(django_forms.CharField):
|
|
|
80
79
|
"in double quotes."
|
|
81
80
|
)
|
|
82
81
|
|
|
83
|
-
def to_python(self, value):
|
|
84
|
-
if value is None:
|
|
85
|
-
return None
|
|
86
|
-
reader = csv.reader(StringIO(value.strip()))
|
|
87
|
-
return forms.parse_csv(reader)
|
|
88
|
-
|
|
89
|
-
def validate(self, value):
|
|
90
|
-
if value is None:
|
|
91
|
-
return None
|
|
92
|
-
headers, _records = value
|
|
93
|
-
forms.validate_csv(headers, self.fields, self.required_fields)
|
|
94
|
-
|
|
95
|
-
return value
|
|
96
|
-
|
|
97
82
|
|
|
98
83
|
class CSVFileField(django_forms.FileField):
|
|
99
84
|
"""
|
|
100
|
-
A FileField (rendered as a ClearableFileInput) which
|
|
101
|
-
data as a two-tuple: The first item is a dictionary of column headers, mapping field names to the attribute
|
|
102
|
-
by which they match a related object (where applicable). The second item is a list of dictionaries, each
|
|
103
|
-
representing a discrete row of CSV data.
|
|
85
|
+
A FileField (rendered as a ClearableFileInput) which expects a file containing CSV-formatted data.
|
|
104
86
|
|
|
105
|
-
|
|
87
|
+
This no longer actually does any CSV parsing or validation on its own,
|
|
88
|
+
as that is now handled by the NautobotCSVParser class and the REST API serializers.
|
|
106
89
|
"""
|
|
107
90
|
|
|
108
|
-
def __init__(self,
|
|
109
|
-
|
|
110
|
-
form = from_form()
|
|
111
|
-
self.model = form.Meta.model
|
|
112
|
-
self.fields = form.fields
|
|
113
|
-
self.required_fields = [name for name, field in form.fields.items() if field.required]
|
|
91
|
+
def __init__(self, *args, **kwargs):
|
|
92
|
+
kwargs.setdefault("required", False)
|
|
114
93
|
|
|
115
94
|
super().__init__(*args, **kwargs)
|
|
116
95
|
|
|
@@ -124,37 +103,19 @@ class CSVFileField(django_forms.FileField):
|
|
|
124
103
|
)
|
|
125
104
|
|
|
126
105
|
def to_python(self, file):
|
|
106
|
+
"""For parity with CSVDataField, this returns the CSV text rather than an UploadedFile object."""
|
|
127
107
|
if file is None:
|
|
128
108
|
return None
|
|
129
109
|
|
|
130
110
|
file = super().to_python(file)
|
|
131
|
-
|
|
132
|
-
# Check if there is only one column of input
|
|
133
|
-
# If so a delimiter cannot be determined and it will raise an exception.
|
|
134
|
-
# In that case we will use csv.excel class
|
|
135
|
-
# Which defines the usual properties of an Excel-generated CSV file.
|
|
136
|
-
try:
|
|
137
|
-
dialect = csv.Sniffer().sniff(csv_str, delimiters=",")
|
|
138
|
-
except csv.Error:
|
|
139
|
-
dialect = csv.excel
|
|
140
|
-
reader = csv.reader(csv_str.splitlines(), dialect)
|
|
141
|
-
headers, records = forms.parse_csv(reader)
|
|
142
|
-
|
|
143
|
-
return headers, records
|
|
144
|
-
|
|
145
|
-
def validate(self, value):
|
|
146
|
-
if value is None:
|
|
147
|
-
return None
|
|
148
|
-
|
|
149
|
-
headers, _records = value
|
|
150
|
-
forms.validate_csv(headers, self.fields, self.required_fields)
|
|
151
|
-
|
|
152
|
-
return value
|
|
111
|
+
return file.read().decode("utf-8-sig").strip()
|
|
153
112
|
|
|
154
113
|
|
|
155
114
|
class CSVChoiceField(django_forms.ChoiceField):
|
|
156
115
|
"""
|
|
157
116
|
Invert the provided set of choices to take the human-friendly label as input, and return the database value.
|
|
117
|
+
|
|
118
|
+
Despite the name, this is no longer used in CSV imports since 2.0, but *is* used in JSON/YAML import of DeviceTypes.
|
|
158
119
|
"""
|
|
159
120
|
|
|
160
121
|
STATIC_CHOICES = True
|
|
@@ -166,7 +127,10 @@ class CSVChoiceField(django_forms.ChoiceField):
|
|
|
166
127
|
|
|
167
128
|
class CSVMultipleChoiceField(CSVChoiceField):
|
|
168
129
|
"""
|
|
169
|
-
A version of CSVChoiceField that supports and emits a list of choice values
|
|
130
|
+
A version of CSVChoiceField that supports and emits a list of choice values.
|
|
131
|
+
|
|
132
|
+
As with CSVChoiceField, the name is misleading, as this is no longer used for CSV imports, but is used for
|
|
133
|
+
JSON/YAML import of DeviceTypes still.
|
|
170
134
|
"""
|
|
171
135
|
|
|
172
136
|
def to_python(self, value):
|
|
@@ -184,6 +148,9 @@ class CSVMultipleChoiceField(CSVChoiceField):
|
|
|
184
148
|
class CSVModelChoiceField(django_forms.ModelChoiceField):
|
|
185
149
|
"""
|
|
186
150
|
Provides additional validation for model choices entered as CSV data.
|
|
151
|
+
|
|
152
|
+
Note: class name is misleading; the subclass CSVContentTypeField (below) is also used in FilterSets, where it has
|
|
153
|
+
nothing to do with CSV data.
|
|
187
154
|
"""
|
|
188
155
|
|
|
189
156
|
default_error_messages = {
|
|
@@ -200,6 +167,8 @@ class CSVModelChoiceField(django_forms.ModelChoiceField):
|
|
|
200
167
|
class CSVContentTypeField(CSVModelChoiceField):
|
|
201
168
|
"""
|
|
202
169
|
Reference a ContentType in the form `{app_label}.{model}`.
|
|
170
|
+
|
|
171
|
+
Note: class name is misleading; this field is also used in numerous FilterSets where it has nothing to do with CSV.
|
|
203
172
|
"""
|
|
204
173
|
|
|
205
174
|
STATIC_CHOICES = True
|
|
@@ -315,6 +284,9 @@ class MultiValueCharField(django_forms.CharField):
|
|
|
315
284
|
class CSVMultipleContentTypeField(MultipleContentTypeField):
|
|
316
285
|
"""
|
|
317
286
|
Reference a list of `ContentType` objects in the form `{app_label}.{model}'.
|
|
287
|
+
|
|
288
|
+
Note: This is unused in Nautobot core at this time, but some apps (data-validation-engine) use this for non-CSV
|
|
289
|
+
purposes, similar to CSVContentTypeField above.
|
|
318
290
|
"""
|
|
319
291
|
|
|
320
292
|
def prepare_value(self, value):
|
|
@@ -382,7 +354,7 @@ class ExpandableIPAddressField(django_forms.CharField):
|
|
|
382
354
|
)
|
|
383
355
|
|
|
384
356
|
def to_python(self, value):
|
|
385
|
-
# Hackish address
|
|
357
|
+
# Hackish address version detection but it's all we have to work with
|
|
386
358
|
if "." in value and re.search(forms.IP4_EXPANSION_PATTERN, value):
|
|
387
359
|
return list(forms.expand_ipaddress_pattern(value, 4))
|
|
388
360
|
elif ":" in value and re.search(forms.IP6_EXPANSION_PATTERN, value):
|
|
@@ -485,7 +457,7 @@ class DynamicModelChoiceMixin:
|
|
|
485
457
|
:param null_option: The string used to represent a null selection (if any)
|
|
486
458
|
:param disabled_indicator: The name of the field which, if populated, will disable selection of the
|
|
487
459
|
choice (optional)
|
|
488
|
-
:param
|
|
460
|
+
:param depth: Nested serialization depth when making API requests (default: `0` or a flat representation)
|
|
489
461
|
"""
|
|
490
462
|
|
|
491
463
|
filter = django_filters.ModelChoiceFilter # 2.0 TODO(Glenn): can we rename this? pylint: disable=redefined-builtin
|
|
@@ -498,7 +470,7 @@ class DynamicModelChoiceMixin:
|
|
|
498
470
|
initial_params=None,
|
|
499
471
|
null_option=None,
|
|
500
472
|
disabled_indicator=None,
|
|
501
|
-
|
|
473
|
+
depth=0,
|
|
502
474
|
*args,
|
|
503
475
|
**kwargs,
|
|
504
476
|
):
|
|
@@ -507,7 +479,7 @@ class DynamicModelChoiceMixin:
|
|
|
507
479
|
self.initial_params = initial_params or {}
|
|
508
480
|
self.null_option = null_option
|
|
509
481
|
self.disabled_indicator = disabled_indicator
|
|
510
|
-
self.
|
|
482
|
+
self.depth = depth
|
|
511
483
|
|
|
512
484
|
# to_field_name is set by ModelChoiceField.__init__(), but we need to set it early for reference
|
|
513
485
|
# by widget_attrs()
|
|
@@ -532,9 +504,8 @@ class DynamicModelChoiceMixin:
|
|
|
532
504
|
if self.disabled_indicator is not None:
|
|
533
505
|
attrs["disabled-indicator"] = self.disabled_indicator
|
|
534
506
|
|
|
535
|
-
# Toggle
|
|
536
|
-
|
|
537
|
-
attrs["data-full"] = "true"
|
|
507
|
+
# Toggle depth
|
|
508
|
+
attrs["data-depth"] = self.depth
|
|
538
509
|
|
|
539
510
|
# Attach any static query parameters
|
|
540
511
|
for key, value in self.query_params.items():
|
nautobot/core/forms/forms.py
CHANGED
|
@@ -7,7 +7,7 @@ from django.forms import formset_factory
|
|
|
7
7
|
from django.urls import reverse
|
|
8
8
|
import yaml
|
|
9
9
|
|
|
10
|
-
from nautobot.core.utils.filtering import build_lookup_label, get_filterset_parameter_form_field
|
|
10
|
+
from nautobot.core.utils.filtering import build_lookup_label, get_filterset_parameter_form_field, get_filter_field_label
|
|
11
11
|
from nautobot.ipam import formfields
|
|
12
12
|
|
|
13
13
|
__all__ = (
|
|
@@ -36,7 +36,6 @@ class AddressFieldMixin(forms.ModelForm):
|
|
|
36
36
|
address = formfields.IPNetworkFormField()
|
|
37
37
|
|
|
38
38
|
def __init__(self, *args, **kwargs):
|
|
39
|
-
|
|
40
39
|
instance = kwargs.get("instance")
|
|
41
40
|
initial = kwargs.get("initial", {}).copy()
|
|
42
41
|
|
|
@@ -138,7 +137,10 @@ class BulkRenameForm(forms.Form):
|
|
|
138
137
|
|
|
139
138
|
class CSVModelForm(forms.ModelForm):
|
|
140
139
|
"""
|
|
141
|
-
ModelForm used for the import of objects
|
|
140
|
+
ModelForm used for the import of objects.
|
|
141
|
+
|
|
142
|
+
Note: the name is misleading as since 2.0 this is no longer used for CSV imports; however it *is* still used for
|
|
143
|
+
JSON/YAML imports of DeviceTypes and their component templates.
|
|
142
144
|
"""
|
|
143
145
|
|
|
144
146
|
def __init__(self, *args, headers=None, **kwargs):
|
|
@@ -159,7 +161,6 @@ class PrefixFieldMixin(forms.ModelForm):
|
|
|
159
161
|
prefix = formfields.IPNetworkFormField()
|
|
160
162
|
|
|
161
163
|
def __init__(self, *args, **kwargs):
|
|
162
|
-
|
|
163
164
|
instance = kwargs.get("instance")
|
|
164
165
|
initial = kwargs.get("initial", {}).copy()
|
|
165
166
|
|
|
@@ -262,22 +263,21 @@ class DynamicFilterForm(BootstrapMixin, forms.Form):
|
|
|
262
263
|
label="Value",
|
|
263
264
|
)
|
|
264
265
|
|
|
265
|
-
def __init__(self, *args,
|
|
266
|
+
def __init__(self, *args, filterset=None, **kwargs):
|
|
266
267
|
super().__init__(*args, **kwargs)
|
|
267
268
|
from nautobot.core.forms import add_blank_choice # Avoid circular import
|
|
268
269
|
|
|
269
270
|
# cls.model is set at `dynamic_formset_factory()`
|
|
270
|
-
self.
|
|
271
|
+
self.filterset = filterset or getattr(self, "filterset", None)
|
|
271
272
|
|
|
272
|
-
# Raise exception if `cls.
|
|
273
|
-
if self.
|
|
274
|
-
raise AttributeError("'DynamicFilterForm' object requires `
|
|
273
|
+
# Raise exception if `cls.filterset` not set and `filterset` not passed
|
|
274
|
+
if self.filterset is None:
|
|
275
|
+
raise AttributeError("'DynamicFilterForm' object requires `filterset` attribute")
|
|
275
276
|
|
|
276
|
-
model = self.
|
|
277
|
+
model = self.filterset._meta.model
|
|
277
278
|
|
|
278
|
-
if self.
|
|
279
|
-
|
|
280
|
-
self.filterset_filters = filterset_class.filters
|
|
279
|
+
if self.filterset is not None:
|
|
280
|
+
self.filterset_filters = self.filterset.filters
|
|
281
281
|
contenttype = model._meta.app_label + "." + model._meta.model_name
|
|
282
282
|
|
|
283
283
|
# Configure fields: Add css class and set choices for lookup_field
|
|
@@ -296,9 +296,11 @@ class DynamicFilterForm(BootstrapMixin, forms.Form):
|
|
|
296
296
|
verbose_name = self.filterset_filters[lookup_type].lookup_expr
|
|
297
297
|
label = build_lookup_label(lookup_type, verbose_name)
|
|
298
298
|
self.fields["lookup_type"].choices = [(lookup_type, label)]
|
|
299
|
-
self.fields["lookup_value"] = get_filterset_parameter_form_field(
|
|
299
|
+
self.fields["lookup_value"] = get_filterset_parameter_form_field(
|
|
300
|
+
model, lookup_type, filterset=self.filterset
|
|
301
|
+
)
|
|
300
302
|
elif lookup_type and lookup_type not in self.filterset_filters:
|
|
301
|
-
logger.warning(f"{lookup_type} is not a valid {
|
|
303
|
+
logger.warning(f"{lookup_type} is not a valid {self.filterset.__class__.__name__} field")
|
|
302
304
|
|
|
303
305
|
self.fields["lookup_type"].widget.attrs["data-query-param-field_name"] = json.dumps(["$lookup_field"])
|
|
304
306
|
self.fields["lookup_type"].widget.attrs["data-contenttype"] = contenttype
|
|
@@ -312,26 +314,24 @@ class DynamicFilterForm(BootstrapMixin, forms.Form):
|
|
|
312
314
|
else:
|
|
313
315
|
logger.warning(f"FilterSet for {model.__class__} not found.")
|
|
314
316
|
|
|
315
|
-
@staticmethod
|
|
316
|
-
def capitalize(field):
|
|
317
|
-
field = field.replace("_custom_field_data__", "")
|
|
318
|
-
split_field = field.split("__") if "__" in field else field.split("_")
|
|
319
|
-
words = " ".join(split_field)
|
|
320
|
-
return words[0].upper() + words[1:]
|
|
321
|
-
|
|
322
317
|
def _get_lookup_field_choices(self):
|
|
323
318
|
"""Get choices for lookup_fields i.e filterset parameters without a lookup expr"""
|
|
319
|
+
from nautobot.extras.filters.mixins import RelationshipFilter # Avoid circular import
|
|
320
|
+
|
|
324
321
|
filterset_without_lookup = (
|
|
325
|
-
(
|
|
326
|
-
|
|
327
|
-
|
|
322
|
+
(
|
|
323
|
+
name,
|
|
324
|
+
get_filter_field_label(filter_field),
|
|
325
|
+
)
|
|
326
|
+
for name, filter_field in self.filterset_filters.items()
|
|
327
|
+
if isinstance(filter_field, RelationshipFilter) or ("__" not in name and name != "q")
|
|
328
328
|
)
|
|
329
329
|
return sorted(filterset_without_lookup, key=lambda x: x[1])
|
|
330
330
|
|
|
331
331
|
|
|
332
|
-
def dynamic_formset_factory(
|
|
332
|
+
def dynamic_formset_factory(filterset, data=None, **kwargs):
|
|
333
333
|
filter_form = DynamicFilterForm
|
|
334
|
-
filter_form.
|
|
334
|
+
filter_form.filterset = filterset
|
|
335
335
|
|
|
336
336
|
params = {
|
|
337
337
|
"can_delete_extra": True,
|
nautobot/core/forms/utils.py
CHANGED
|
@@ -15,8 +15,6 @@ __all__ = (
|
|
|
15
15
|
"parse_alphanumeric_range",
|
|
16
16
|
"parse_numeric_range",
|
|
17
17
|
"restrict_form_fields",
|
|
18
|
-
"parse_csv",
|
|
19
|
-
"validate_csv",
|
|
20
18
|
)
|
|
21
19
|
|
|
22
20
|
|
|
@@ -85,15 +83,15 @@ def expand_alphanumeric_pattern(string):
|
|
|
85
83
|
yield f"{lead}{i}{remnant}"
|
|
86
84
|
|
|
87
85
|
|
|
88
|
-
def expand_ipaddress_pattern(string,
|
|
86
|
+
def expand_ipaddress_pattern(string, ip_version):
|
|
89
87
|
"""
|
|
90
88
|
Expand an IP address pattern into a list of strings. Examples:
|
|
91
89
|
'192.0.2.[1,2,100-250]/24' => ['192.0.2.1/24', '192.0.2.2/24', '192.0.2.100/24' ... '192.0.2.250/24']
|
|
92
90
|
'2001:db8:0:[0,fd-ff]::/64' => ['2001:db8:0:0::/64', '2001:db8:0:fd::/64', ... '2001:db8:0:ff::/64']
|
|
93
91
|
"""
|
|
94
|
-
if
|
|
95
|
-
raise
|
|
96
|
-
if
|
|
92
|
+
if ip_version not in [4, 6]:
|
|
93
|
+
raise ValueError(f"Invalid IP address version: {ip_version}")
|
|
94
|
+
if ip_version == 4:
|
|
97
95
|
regex = forms.IP4_EXPANSION_PATTERN
|
|
98
96
|
base = 10
|
|
99
97
|
else:
|
|
@@ -103,10 +101,10 @@ def expand_ipaddress_pattern(string, family):
|
|
|
103
101
|
parsed_range = parse_numeric_range(pattern, base)
|
|
104
102
|
for i in parsed_range:
|
|
105
103
|
if re.search(regex, remnant):
|
|
106
|
-
for string2 in expand_ipaddress_pattern(remnant,
|
|
107
|
-
yield "".join([lead, format(i, "x" if
|
|
104
|
+
for string2 in expand_ipaddress_pattern(remnant, ip_version):
|
|
105
|
+
yield "".join([lead, format(i, "x" if ip_version == 6 else "d"), string2])
|
|
108
106
|
else:
|
|
109
|
-
yield "".join([lead, format(i, "x" if
|
|
107
|
+
yield "".join([lead, format(i, "x" if ip_version == 6 else "d"), remnant])
|
|
110
108
|
|
|
111
109
|
|
|
112
110
|
def add_blank_choice(choices):
|
|
@@ -139,56 +137,6 @@ def restrict_form_fields(form, user, action="view"):
|
|
|
139
137
|
field.queryset = field.queryset.restrict(user, action)
|
|
140
138
|
|
|
141
139
|
|
|
142
|
-
def parse_csv(reader):
|
|
143
|
-
"""
|
|
144
|
-
Parse a csv_reader object into a headers dictionary and a list of records dictionaries. Raise an error
|
|
145
|
-
if the records are formatted incorrectly. Return headers and records as a tuple.
|
|
146
|
-
"""
|
|
147
|
-
records = []
|
|
148
|
-
headers = {}
|
|
149
|
-
|
|
150
|
-
# Consume the first line of CSV data as column headers. Create a dictionary mapping each header to an optional
|
|
151
|
-
# "to" field specifying how the related object is being referenced. For example, importing a Device might use a
|
|
152
|
-
# `site.slug` header, to indicate the related site is being referenced by its slug.
|
|
153
|
-
|
|
154
|
-
for header in next(reader):
|
|
155
|
-
if "." in header:
|
|
156
|
-
field, to_field = header.split(".", 1)
|
|
157
|
-
headers[field] = to_field
|
|
158
|
-
else:
|
|
159
|
-
headers[header] = None
|
|
160
|
-
|
|
161
|
-
# Parse CSV rows into a list of dictionaries mapped from the column headers.
|
|
162
|
-
for i, row in enumerate(reader, start=1):
|
|
163
|
-
if len(row) != len(headers):
|
|
164
|
-
raise django_forms.ValidationError(f"Row {i}: Expected {len(headers)} columns but found {len(row)}")
|
|
165
|
-
row = [col.strip() for col in row]
|
|
166
|
-
record = dict(zip(headers.keys(), row))
|
|
167
|
-
records.append(record)
|
|
168
|
-
|
|
169
|
-
return headers, records
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
def validate_csv(headers, fields, required_fields):
|
|
173
|
-
"""
|
|
174
|
-
Validate that parsed csv data conforms to the object's available fields. Raise validation errors
|
|
175
|
-
if parsed csv data contains invalid headers or does not contain required headers.
|
|
176
|
-
"""
|
|
177
|
-
# Validate provided column headers
|
|
178
|
-
for field, to_field in headers.items():
|
|
179
|
-
if field not in fields:
|
|
180
|
-
raise django_forms.ValidationError(f'Unexpected column header "{field}" found.')
|
|
181
|
-
if to_field and not hasattr(fields[field], "to_field_name"):
|
|
182
|
-
raise django_forms.ValidationError(f'Column "{field}" is not a related object; cannot use dots')
|
|
183
|
-
if to_field and not hasattr(fields[field].queryset.model, to_field):
|
|
184
|
-
raise django_forms.ValidationError(f'Invalid related object attribute for column "{field}": {to_field}')
|
|
185
|
-
|
|
186
|
-
# Validate required fields
|
|
187
|
-
for f in required_fields:
|
|
188
|
-
if f not in headers:
|
|
189
|
-
raise django_forms.ValidationError(f'Required column header "{f}" not found.')
|
|
190
|
-
|
|
191
|
-
|
|
192
140
|
def add_field_to_filter_form_class(form_class, field_name, field_obj):
|
|
193
141
|
"""
|
|
194
142
|
Attach a field to an existing filter form class.
|
nautobot/core/forms/widgets.py
CHANGED
|
@@ -156,7 +156,6 @@ class APISelect(SelectWithDisabled):
|
|
|
156
156
|
self.attrs[key] = json.dumps(values, ensure_ascii=False)
|
|
157
157
|
|
|
158
158
|
def get_context(self, name, value, attrs):
|
|
159
|
-
|
|
160
159
|
# This adds null options to DynamicModelMultipleChoiceField selected choices
|
|
161
160
|
# example <select ..>
|
|
162
161
|
# <option .. selected value="null">None</option>
|
|
@@ -34,7 +34,7 @@ def execute_query(query, variables=None, request=None, user=None):
|
|
|
34
34
|
return document.execute(context_value=request)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
def execute_saved_query(
|
|
37
|
+
def execute_saved_query(saved_query_name, **kwargs):
|
|
38
38
|
"""Execute saved query from the ORM.
|
|
39
39
|
|
|
40
40
|
Args:
|
|
@@ -46,7 +46,7 @@ def execute_saved_query(saved_query_slug, **kwargs):
|
|
|
46
46
|
Returns:
|
|
47
47
|
GraphQL Object: Result for query
|
|
48
48
|
"""
|
|
49
|
-
query = GraphQLQuery.objects.get(
|
|
49
|
+
query = GraphQLQuery.objects.get(name=saved_query_name)
|
|
50
50
|
return execute_query(query=query.query, **kwargs)
|
|
51
51
|
|
|
52
52
|
|
nautobot/core/graphql/schema.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Schema module for GraphQL."""
|
|
2
2
|
from collections import OrderedDict
|
|
3
3
|
import logging
|
|
4
|
-
import warnings
|
|
5
4
|
|
|
6
5
|
from django.conf import settings
|
|
7
6
|
from django.contrib.contenttypes.models import ContentType
|
|
@@ -276,18 +275,7 @@ def extend_schema_type_computed_field(schema_type, model):
|
|
|
276
275
|
prefix = f"{settings.GRAPHQL_COMPUTED_FIELD_PREFIX}_"
|
|
277
276
|
|
|
278
277
|
for field in cfs:
|
|
279
|
-
field_name = f"{prefix}{
|
|
280
|
-
if str_to_var_name(field.slug) != field.slug:
|
|
281
|
-
# 2.0 TODO: str_to_var_name is lossy, it may cause different fields to map to the same field_name
|
|
282
|
-
# In 2.0 we should simply omit fields whose slugs are invalid in GraphQL, instead of mapping them.
|
|
283
|
-
# We need to make sure that slug/key is unique in a data migration before we remove the warning
|
|
284
|
-
# See https://github.com/nautobot/nautobot/pull/3426 for detailed solution
|
|
285
|
-
warnings.warn(
|
|
286
|
-
f'Computed field "{field}" on {model._meta.verbose_name} does not have a GraphQL-safe slug '
|
|
287
|
-
f'("{field.slug}"); for now it will be mapped to the GraphQL name "{field_name}", '
|
|
288
|
-
"but in a future release this field may fail to appear in GraphQL.",
|
|
289
|
-
FutureWarning,
|
|
290
|
-
)
|
|
278
|
+
field_name = f"{prefix}{field.key}"
|
|
291
279
|
resolver_name = f"resolve_{field_name}"
|
|
292
280
|
|
|
293
281
|
if hasattr(schema_type, resolver_name):
|
|
@@ -303,7 +291,7 @@ def extend_schema_type_computed_field(schema_type, model):
|
|
|
303
291
|
setattr(
|
|
304
292
|
schema_type,
|
|
305
293
|
resolver_name,
|
|
306
|
-
generate_computed_field_resolver(field.
|
|
294
|
+
generate_computed_field_resolver(field.key, resolver_name),
|
|
307
295
|
)
|
|
308
296
|
|
|
309
297
|
schema_type._meta.fields[field_name] = graphene.Field.mounted(graphene.String())
|
|
@@ -376,24 +364,13 @@ def extend_schema_type_relationships(schema_type, model):
|
|
|
376
364
|
for relationship in relationships:
|
|
377
365
|
peer_side = RelationshipSideChoices.OPPOSITE[side]
|
|
378
366
|
|
|
379
|
-
# Generate the name of the attribute and the name of the resolver based on the
|
|
367
|
+
# Generate the name of the attribute and the name of the resolver based on the key of the relationship
|
|
380
368
|
# and based on the prefix
|
|
381
|
-
rel_name = f"{prefix}{
|
|
369
|
+
rel_name = f"{prefix}{relationship.key}"
|
|
382
370
|
# Handle non-symmetric relationships where the model can be either source or destination
|
|
383
371
|
if not relationship.symmetric and relationship.source_type == relationship.destination_type:
|
|
384
372
|
rel_name = f"{rel_name}_{peer_side}"
|
|
385
373
|
resolver_name = f"resolve_{rel_name}"
|
|
386
|
-
if str_to_var_name(relationship.slug) != relationship.slug:
|
|
387
|
-
# 2.0 TODO: str_to_var_name is lossy, it may cause different relationships to map to the same rel_name
|
|
388
|
-
# In 2.0 we should simply omit relations whose slugs are invalid in GraphQL, instead of mapping them.
|
|
389
|
-
# We need to make sure that slug/key is unique in a data migration before we remove the warning
|
|
390
|
-
# See https://github.com/nautobot/nautobot/pull/3426 for detailed solution
|
|
391
|
-
warnings.warn(
|
|
392
|
-
f'Relationship "{relationship}" on {model._meta.verbose_name} does not have a GraphQL-safe slug '
|
|
393
|
-
f'("{relationship.slug}"); for now it will be mapped to the GraphQL name "{rel_name}", '
|
|
394
|
-
"but in a future release this relationship may fail to appear in GraphQL.",
|
|
395
|
-
FutureWarning,
|
|
396
|
-
)
|
|
397
374
|
|
|
398
375
|
if hasattr(schema_type, resolver_name):
|
|
399
376
|
# If a symmetric relationship, and this is destination side, we already added source side, expected
|