nautobot 2.1.0b1__py3-none-any.whl → 2.1.1__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 -3
- nautobot/apps/__init__.py +1 -2
- nautobot/apps/admin.py +0 -1
- nautobot/apps/api.py +0 -1
- nautobot/apps/change_logging.py +0 -1
- nautobot/apps/choices.py +0 -3
- nautobot/apps/datasources.py +2 -2
- nautobot/apps/exceptions.py +0 -1
- nautobot/apps/factory.py +0 -1
- nautobot/apps/filters.py +6 -9
- nautobot/apps/forms.py +1 -2
- nautobot/apps/graphql.py +0 -1
- nautobot/apps/jobs.py +2 -1
- nautobot/apps/models.py +4 -2
- nautobot/apps/querysets.py +0 -1
- nautobot/apps/secrets.py +0 -1
- nautobot/apps/tables.py +0 -1
- nautobot/apps/testing.py +0 -1
- nautobot/apps/ui.py +1 -3
- nautobot/apps/urls.py +0 -1
- nautobot/apps/utils.py +0 -1
- nautobot/apps/views.py +0 -1
- nautobot/circuits/api/serializers.py +1 -1
- nautobot/circuits/api/urls.py +1 -1
- nautobot/circuits/api/views.py +2 -1
- nautobot/circuits/apps.py +1 -1
- nautobot/circuits/choices.py +0 -1
- nautobot/circuits/factory.py +1 -1
- nautobot/circuits/filters.py +2 -1
- nautobot/circuits/forms.py +2 -2
- nautobot/circuits/homepage.py +0 -1
- nautobot/circuits/migrations/0001_initial_part_1.py +3 -1
- nautobot/circuits/migrations/0002_initial_part_2.py +2 -1
- nautobot/circuits/migrations/0003_auto_slug.py +1 -0
- nautobot/circuits/migrations/0005_providernetwork.py +4 -2
- nautobot/circuits/migrations/0013_alter_circuittermination__path.py +1 -0
- nautobot/circuits/migrations/0014_related_name_changes.py +1 -0
- nautobot/circuits/migrations/0016_tagsfield.py +1 -0
- nautobot/circuits/migrations/0018_status_nonnullable.py +1 -0
- nautobot/circuits/models.py +2 -2
- nautobot/circuits/navigation.py +0 -1
- nautobot/circuits/signals.py +3 -2
- nautobot/circuits/tables.py +1 -0
- nautobot/circuits/tests/integration/test_relationships.py +1 -1
- nautobot/circuits/tests/test_api.py +1 -1
- nautobot/circuits/tests/test_urls.py +1 -1
- nautobot/circuits/tests/test_views.py +1 -0
- nautobot/circuits/urls.py +1 -1
- nautobot/circuits/views.py +1 -10
- nautobot/core/__init__.py +0 -1
- nautobot/core/admin.py +3 -5
- nautobot/core/api/__init__.py +0 -1
- nautobot/core/api/metadata.py +4 -6
- nautobot/core/api/pagination.py +2 -2
- nautobot/core/api/parsers.py +1 -3
- nautobot/core/api/renderers.py +0 -1
- nautobot/core/api/schema.py +2 -3
- nautobot/core/api/serializers.py +9 -7
- nautobot/core/api/urls.py +1 -5
- nautobot/core/api/utils.py +14 -15
- nautobot/core/api/versioning.py +1 -1
- nautobot/core/api/views.py +22 -91
- nautobot/core/apps/__init__.py +5 -7
- nautobot/core/authentication.py +1 -1
- nautobot/core/celery/__init__.py +1 -2
- nautobot/core/celery/control.py +0 -2
- nautobot/core/celery/encoders.py +0 -1
- nautobot/core/celery/schedulers.py +1 -2
- nautobot/core/celery/task.py +1 -1
- nautobot/core/checks.py +31 -2
- nautobot/core/choices.py +2 -2
- nautobot/core/cli/__init__.py +8 -17
- nautobot/core/context_processors.py +1 -5
- nautobot/core/factory.py +2 -2
- nautobot/core/filters.py +1 -1
- nautobot/core/forms/fields.py +2 -4
- nautobot/core/forms/forms.py +1 -1
- nautobot/core/forms/search.py +1 -1
- nautobot/core/forms/utils.py +1 -1
- nautobot/core/graphql/__init__.py +2 -3
- nautobot/core/graphql/generators.py +2 -2
- nautobot/core/graphql/schema.py +21 -8
- nautobot/core/graphql/schema_init.py +0 -1
- nautobot/core/graphql/types.py +10 -0
- nautobot/core/graphql/utils.py +1 -2
- nautobot/core/management/commands/generate_test_data.py +7 -6
- nautobot/core/management/commands/makemigrations.py +1 -1
- nautobot/core/management/commands/migrate.py +1 -1
- nautobot/core/management/commands/post_upgrade.py +1 -15
- nautobot/core/management/commands/refresh_content_type_cache.py +1 -2
- nautobot/core/management/commands/send_installation_metrics.py +2 -3
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/middleware.py +2 -2
- nautobot/core/models/__init__.py +12 -12
- nautobot/core/models/fields.py +1 -1
- nautobot/core/models/generics.py +2 -3
- nautobot/core/models/managers.py +0 -1
- nautobot/core/models/name_color_content_types.py +2 -2
- nautobot/core/models/tree_queries.py +2 -4
- nautobot/core/models/validators.py +1 -1
- nautobot/core/releases.py +1 -1
- nautobot/core/runner/importer.py +2 -25
- nautobot/core/runner/runner.py +2 -2
- nautobot/core/runner/settings.py +1 -1
- nautobot/core/settings.py +15 -21
- nautobot/core/settings_funcs.py +1 -2
- nautobot/core/signals.py +0 -1
- nautobot/core/tables.py +1 -1
- nautobot/core/templates/admin/base.html +9 -9
- nautobot/core/templates/exceptions/programming_error.html +2 -2
- nautobot/core/templates/graphene/graphiql.html +9 -3
- nautobot/core/templates/home.html +26 -6
- nautobot/core/templates/inc/footer.html +0 -7
- nautobot/core/templates/inc/javascript.html +4 -2
- nautobot/core/templates/inc/media.html +2 -2
- nautobot/core/templates/inc/nav_menu.html +27 -25
- nautobot/core/templates/inc/object_details_advanced_panel.html +12 -0
- nautobot/core/templates/nautobot_config.py.j2 +4 -4
- nautobot/core/templates/utilities/theme_preview.html +883 -0
- nautobot/core/templatetags/bootstrapped_goodies_tags.py +6 -3
- nautobot/core/templatetags/buttons.py +2 -1
- nautobot/core/templatetags/helpers.py +45 -18
- nautobot/core/testing/__init__.py +1 -2
- nautobot/core/testing/api.py +2 -4
- nautobot/core/testing/filters.py +1 -1
- nautobot/core/testing/integration.py +2 -2
- nautobot/core/testing/migrations.py +1 -0
- nautobot/core/testing/mixins.py +1 -2
- nautobot/core/testing/schema.py +1 -1
- nautobot/core/testing/utils.py +3 -3
- nautobot/core/testing/views.py +8 -8
- nautobot/core/tests/integration/test_home.py +1 -1
- nautobot/core/tests/integration/test_navbar.py +2 -2
- nautobot/core/tests/integration/test_plugin_home.py +2 -1
- nautobot/core/tests/integration/test_plugin_navbar.py +6 -6
- nautobot/core/tests/nautobot_config.py +3 -3
- nautobot/core/tests/runner.py +3 -4
- nautobot/core/tests/test_api.py +6 -51
- nautobot/core/tests/test_authentication.py +2 -3
- nautobot/core/tests/test_checks.py +1 -2
- nautobot/core/tests/test_config.py +1 -1
- nautobot/core/tests/test_csv.py +4 -4
- nautobot/core/tests/test_factory.py +1 -3
- nautobot/core/tests/test_filters.py +4 -7
- nautobot/core/tests/test_forms.py +3 -6
- nautobot/core/tests/test_graphql.py +33 -17
- nautobot/core/tests/test_jinja_filters.py +5 -4
- nautobot/core/tests/test_jobs.py +1 -1
- nautobot/core/tests/test_models.py +28 -3
- nautobot/core/tests/test_navigations.py +2 -1
- nautobot/core/tests/test_openapi.py +0 -1
- nautobot/core/tests/test_paginator.py +2 -2
- nautobot/core/tests/test_releases.py +2 -2
- nautobot/core/tests/test_tables.py +1 -1
- nautobot/core/tests/test_templatetags_helpers.py +17 -2
- nautobot/core/tests/test_templatetags_netutils.py +1 -2
- nautobot/core/tests/test_utils.py +4 -8
- nautobot/core/tests/test_views.py +95 -1
- nautobot/core/tests/test_views_utils.py +0 -1
- nautobot/core/urls.py +24 -4
- nautobot/core/utils/color.py +1 -1
- nautobot/core/utils/data.py +1 -2
- nautobot/core/utils/filtering.py +4 -5
- nautobot/core/utils/git.py +6 -2
- nautobot/core/utils/logging.py +2 -1
- nautobot/core/utils/lookup.py +4 -6
- nautobot/core/utils/migrations.py +1 -0
- nautobot/core/utils/permissions.py +2 -4
- nautobot/core/utils/requests.py +10 -0
- nautobot/core/views/__init__.py +32 -8
- nautobot/core/views/generic.py +14 -13
- nautobot/core/views/mixins.py +24 -22
- nautobot/core/views/renderers.py +1 -1
- nautobot/core/views/routers.py +6 -0
- nautobot/core/views/utils.py +2 -1
- nautobot/dcim/api/urls.py +1 -1
- nautobot/dcim/api/views.py +6 -5
- nautobot/dcim/apps.py +1 -1
- nautobot/dcim/choices.py +4 -1
- nautobot/dcim/constants.py +0 -1
- nautobot/dcim/elevations.py +1 -2
- nautobot/dcim/factory.py +125 -13
- nautobot/dcim/fields.py +1 -0
- nautobot/dcim/filters/__init__.py +2 -3
- nautobot/dcim/filters/mixins.py +1 -1
- nautobot/dcim/forms.py +37 -44
- nautobot/dcim/graphql/types.py +16 -17
- nautobot/dcim/migrations/0001_initial_part_1.py +4 -2
- nautobot/dcim/migrations/0002_initial_part_2.py +2 -1
- nautobot/dcim/migrations/0003_initial_part_3.py +2 -1
- nautobot/dcim/migrations/0004_initial_part_4.py +2 -1
- nautobot/dcim/migrations/0006_auto_slug.py +1 -0
- nautobot/dcim/migrations/0009_add_natural_indexing.py +1 -0
- nautobot/dcim/migrations/0010_interface_status.py +1 -0
- nautobot/dcim/migrations/0011_interface_status_data_migration.py +1 -0
- nautobot/dcim/migrations/0013_location_location_type.py +4 -2
- nautobot/dcim/migrations/0014_location_status_data_migration.py +1 -0
- nautobot/dcim/migrations/0016_device_components__timestamp_data_migration.py +0 -1
- nautobot/dcim/migrations/0018_device_redundancy_group.py +4 -2
- nautobot/dcim/migrations/0019_device_redundancy_group_data_migration.py +1 -0
- nautobot/dcim/migrations/0022_interface_redundancy_group.py +3 -1
- nautobot/dcim/migrations/0023_interface_redundancy_group_data_migration.py +1 -0
- nautobot/dcim/migrations/0024_move_site_fields_to_location_model.py +2 -1
- nautobot/dcim/migrations/0027_alter_interface_mac_address.py +1 -0
- nautobot/dcim/migrations/0028_alter_device_and_rack_role_add_new_role.py +1 -0
- nautobot/dcim/migrations/0029_device_and_rack_roles_data_migrations.py +1 -0
- nautobot/dcim/migrations/0033_add_tree_managers_and_foreign_keys_pre_data_migration.py +1 -0
- nautobot/dcim/migrations/0034_migrate_region_and_site_data_to_locations.py +1 -2
- nautobot/dcim/migrations/0038_fixup_fks_and_related_names.py +1 -0
- nautobot/dcim/migrations/0039_related_name_changes.py +1 -0
- nautobot/dcim/migrations/0042_alter_location_managers.py +1 -0
- nautobot/dcim/migrations/0044_tagsfield.py +1 -0
- nautobot/dcim/migrations/0047_status_nonnullable.py +1 -0
- nautobot/dcim/migrations/0051_interface_redundancy_group_nullable_status.py +1 -0
- nautobot/dcim/models/cables.py +3 -3
- nautobot/dcim/models/device_component_templates.py +6 -6
- nautobot/dcim/models/devices.py +9 -4
- nautobot/dcim/models/locations.py +6 -1
- nautobot/dcim/models/power.py +1 -1
- nautobot/dcim/models/racks.py +5 -4
- nautobot/dcim/navigation.py +0 -1
- nautobot/dcim/signals.py +3 -2
- nautobot/dcim/tables/__init__.py +5 -4
- nautobot/dcim/tables/cables.py +1 -0
- nautobot/dcim/tables/devices.py +1 -0
- nautobot/dcim/tables/locations.py +1 -1
- nautobot/dcim/tables/power.py +1 -0
- nautobot/dcim/tables/racks.py +2 -1
- nautobot/dcim/templates/dcim/device/consoleports.html +2 -2
- nautobot/dcim/templates/dcim/device/consoleserverports.html +2 -2
- nautobot/dcim/templates/dcim/device/devicebays.html +1 -1
- nautobot/dcim/templates/dcim/device/frontports.html +2 -2
- nautobot/dcim/templates/dcim/device/interfaces.html +4 -4
- nautobot/dcim/templates/dcim/device/inventory.html +1 -1
- nautobot/dcim/templates/dcim/device/poweroutlets.html +2 -2
- nautobot/dcim/templates/dcim/device/powerports.html +2 -2
- nautobot/dcim/templates/dcim/device/rearports.html +2 -2
- nautobot/dcim/templates/dcim/inc/location_hierarchy.html +4 -2
- nautobot/dcim/templates/dcim/rack.html +1 -1
- nautobot/dcim/templates/dcim/rack_elevation_list.html +1 -1
- nautobot/dcim/templates/dcim/rackreservation.html +1 -1
- nautobot/dcim/tests/test_api.py +7 -7
- nautobot/dcim/tests/test_cablepaths.py +0 -1
- nautobot/dcim/tests/test_filters.py +16 -13
- nautobot/dcim/tests/test_forms.py +2 -3
- nautobot/dcim/tests/test_graphql.py +1 -0
- nautobot/dcim/tests/test_migrations.py +2 -2
- nautobot/dcim/tests/test_models.py +2 -2
- nautobot/dcim/tests/test_views.py +77 -14
- nautobot/dcim/urls.py +3 -2
- nautobot/dcim/utils.py +1 -1
- nautobot/dcim/views.py +4 -3
- nautobot/extras/admin.py +2 -1
- nautobot/extras/api/customfields.py +0 -2
- nautobot/extras/api/mixins.py +0 -1
- nautobot/extras/api/serializers.py +4 -4
- nautobot/extras/api/urls.py +1 -1
- nautobot/extras/api/views.py +1 -1
- nautobot/extras/apps.py +3 -4
- nautobot/extras/choices.py +3 -18
- nautobot/extras/context_managers.py +1 -1
- nautobot/extras/datasources/__init__.py +3 -1
- nautobot/extras/datasources/git.py +33 -12
- nautobot/extras/datasources/utils.py +0 -1
- nautobot/extras/factory.py +20 -0
- nautobot/extras/filters/__init__.py +2 -3
- nautobot/extras/filters/customfields.py +0 -1
- nautobot/extras/filters/mixins.py +1 -1
- nautobot/extras/forms/__init__.py +3 -4
- nautobot/extras/forms/base.py +1 -1
- nautobot/extras/forms/forms.py +29 -11
- nautobot/extras/forms/mixins.py +1 -1
- nautobot/extras/graphql/types.py +2 -2
- nautobot/extras/health_checks.py +1 -1
- nautobot/extras/jobs.py +43 -25
- nautobot/extras/management/__init__.py +0 -1
- nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +1 -1
- nautobot/extras/management/commands/runjob.py +3 -3
- nautobot/extras/management/commands/webhook_receiver.py +1 -2
- nautobot/extras/migrations/0001_initial_part_1.py +2 -1
- nautobot/extras/migrations/0002_initial_part_2.py +2 -1
- nautobot/extras/migrations/0003_initial_part_3.py +1 -0
- nautobot/extras/migrations/0006_graphqlquery.py +2 -1
- nautobot/extras/migrations/0007_configcontextschema.py +3 -1
- nautobot/extras/migrations/0009_computedfield.py +3 -1
- nautobot/extras/migrations/0011_fileattachment_fileproxy.py +3 -1
- nautobot/extras/migrations/0012_healthchecktestmodel.py +2 -1
- nautobot/extras/migrations/0014_auto_slug.py +1 -0
- nautobot/extras/migrations/0015_scheduled_job.py +3 -1
- nautobot/extras/migrations/0016_secret.py +4 -2
- nautobot/extras/migrations/0017_joblogentry.py +2 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +2 -1
- nautobot/extras/migrations/0021_customfield_changelog_data.py +3 -2
- nautobot/extras/migrations/0022_objectchange_object_datav2.py +1 -0
- nautobot/extras/migrations/0023_job_model.py +4 -2
- nautobot/extras/migrations/0026_job_add_gitrepository_fk.py +1 -0
- nautobot/extras/migrations/0029_dynamicgroup.py +3 -1
- nautobot/extras/migrations/0031_tag_content_types.py +1 -0
- nautobot/extras/migrations/0032_tag_content_types_data_migration.py +1 -0
- nautobot/extras/migrations/0040_dynamicgroup__dynamicgroupmembership.py +2 -1
- nautobot/extras/migrations/0041_jobresult_job_kwargs.py +1 -0
- nautobot/extras/migrations/0043_note.py +3 -1
- nautobot/extras/migrations/0044_add_job_hook.py +3 -1
- nautobot/extras/migrations/0046_populate_custom_field_slug_label.py +1 -0
- nautobot/extras/migrations/0047_enforce_custom_field_slug.py +1 -0
- nautobot/extras/migrations/0051_add_job_task_queues.py +1 -0
- nautobot/extras/migrations/0055_configcontext_dynamic_groups.py +1 -0
- nautobot/extras/migrations/0057_jobbutton.py +3 -1
- nautobot/extras/migrations/0065_configcontext_data_migrations.py +1 -0
- nautobot/extras/migrations/0067_migrate_job_result_status.py +0 -1
- nautobot/extras/migrations/0068_jobresult__add_celery_fields.py +1 -0
- nautobot/extras/migrations/0071_replace_related_names.py +1 -0
- nautobot/extras/migrations/0077_migrate_custom_field_data.py +1 -0
- nautobot/extras/migrations/0078_remove_name_field_and_make_label_field_non_nullable.py +1 -0
- nautobot/extras/migrations/0080_tagsfield.py +1 -0
- nautobot/extras/migrations/0082_rename_relationship_name_to_label.py +1 -0
- nautobot/extras/migrations/0083_ensure_relationship_keys_are_unique.py +1 -0
- nautobot/extras/migrations/0090_joblogentry__log_level_data_migration.py +0 -1
- nautobot/extras/migrations/0095_ensure_note_timestamps_are_unique.py +4 -5
- nautobot/extras/migrations/0097_alter_job_result_remove_result.py +1 -0
- nautobot/extras/migrations/0100_fileproxy_job_result.py +1 -0
- nautobot/extras/migrations/0101_externalintegration.py +9 -1
- nautobot/extras/models/__init__.py +2 -3
- nautobot/extras/models/change_logging.py +0 -1
- nautobot/extras/models/customfields.py +13 -4
- nautobot/extras/models/datasources.py +2 -2
- nautobot/extras/models/groups.py +3 -4
- nautobot/extras/models/jobs.py +13 -7
- nautobot/extras/models/models.py +61 -24
- nautobot/extras/models/relationships.py +8 -4
- nautobot/extras/models/roles.py +1 -1
- nautobot/extras/models/secrets.py +1 -3
- nautobot/extras/models/tags.py +0 -1
- nautobot/extras/navigation.py +0 -1
- nautobot/extras/plugins/__init__.py +6 -7
- nautobot/extras/plugins/tables.py +1 -2
- nautobot/extras/plugins/utils.py +1 -1
- nautobot/extras/plugins/views.py +21 -21
- nautobot/extras/querysets.py +30 -13
- nautobot/extras/signals.py +6 -7
- nautobot/extras/tables.py +13 -5
- nautobot/extras/tasks.py +1 -2
- nautobot/extras/templates/extras/configcontext_edit.html +1 -1
- nautobot/extras/templates/extras/customfield_edit.html +7 -12
- nautobot/extras/templates/extras/dynamicgroup_edit.html +42 -47
- nautobot/extras/templates/extras/externalintegration_retrieve.html +12 -0
- nautobot/extras/templates/extras/externalintegration_update.html +28 -0
- nautobot/extras/templates/extras/gitrepository_result.html +2 -2
- nautobot/extras/templates/extras/graphqlquery.html +4 -2
- nautobot/extras/templates/extras/inc/jobresult_js.html +1 -1
- nautobot/extras/templates/extras/job_list.html +1 -1
- nautobot/extras/templates/extras/jobresult.html +2 -2
- nautobot/extras/templates/extras/secretsgroup_edit.html +40 -45
- nautobot/extras/templatetags/custom_links.py +2 -3
- nautobot/extras/templatetags/job_buttons.py +76 -83
- nautobot/extras/templatetags/log_levels.py +0 -1
- nautobot/extras/templatetags/plugins.py +1 -1
- nautobot/extras/test_jobs/api_test_job.py +1 -2
- nautobot/extras/test_jobs/atomic_transaction.py +1 -2
- nautobot/extras/test_jobs/dry_run.py +1 -2
- nautobot/extras/test_jobs/fail.py +1 -2
- nautobot/extras/test_jobs/field_order.py +1 -1
- nautobot/extras/test_jobs/file_upload_fail.py +1 -2
- nautobot/extras/test_jobs/file_upload_pass.py +1 -2
- nautobot/extras/test_jobs/has_sensitive_variables.py +1 -2
- nautobot/extras/test_jobs/ipaddress_vars.py +1 -4
- nautobot/extras/test_jobs/job_button_receiver.py +1 -2
- nautobot/extras/test_jobs/job_hook_receiver.py +1 -2
- nautobot/extras/test_jobs/job_variables.py +7 -2
- nautobot/extras/test_jobs/location_with_custom_field.py +1 -2
- nautobot/extras/test_jobs/log_redaction.py +1 -2
- nautobot/extras/test_jobs/log_skip_db_logging.py +1 -2
- nautobot/extras/test_jobs/modify_db.py +1 -2
- nautobot/extras/test_jobs/object_var_optional.py +1 -2
- nautobot/extras/test_jobs/object_var_required.py +1 -2
- nautobot/extras/test_jobs/object_vars.py +1 -2
- nautobot/extras/test_jobs/pass.py +1 -2
- nautobot/extras/test_jobs/profiling.py +1 -2
- nautobot/extras/tests/integration/__init__.py +1 -1
- nautobot/extras/tests/integration/test_computedfields.py +2 -2
- nautobot/extras/tests/integration/test_configcontextschema.py +5 -5
- nautobot/extras/tests/integration/test_plugins.py +5 -4
- nautobot/extras/tests/integration/test_tagfilter.py +1 -1
- nautobot/extras/tests/test_api.py +15 -9
- nautobot/extras/tests/test_changelog.py +3 -2
- nautobot/extras/tests/test_context_managers.py +6 -3
- nautobot/extras/tests/test_customfields.py +4 -4
- nautobot/extras/tests/test_datasources.py +1 -1
- nautobot/extras/tests/test_dynamicgroups.py +3 -3
- nautobot/extras/tests/test_filters.py +3 -2
- nautobot/extras/tests/test_forms.py +5 -6
- nautobot/extras/tests/test_git.py +1 -1
- nautobot/extras/tests/test_job_variables.py +20 -1
- nautobot/extras/tests/test_jobs.py +34 -5
- nautobot/extras/tests/test_models.py +156 -6
- nautobot/extras/tests/test_notes.py +0 -1
- nautobot/extras/tests/test_plugins.py +71 -9
- nautobot/extras/tests/test_relationships.py +3 -3
- nautobot/extras/tests/test_tags.py +1 -1
- nautobot/extras/tests/test_views.py +105 -25
- nautobot/extras/tests/test_webhooks.py +4 -5
- nautobot/extras/urls.py +0 -2
- nautobot/extras/utils.py +11 -9
- nautobot/extras/views.py +42 -44
- nautobot/generate_secret_key.py +10 -5
- nautobot/ipam/api/serializers.py +1 -2
- nautobot/ipam/api/urls.py +1 -1
- nautobot/ipam/api/views.py +1 -0
- nautobot/ipam/apps.py +2 -1
- nautobot/ipam/factory.py +6 -9
- nautobot/ipam/fields.py +1 -1
- nautobot/ipam/filters.py +42 -58
- nautobot/ipam/formfields.py +1 -2
- nautobot/ipam/forms.py +5 -4
- nautobot/ipam/graphql/types.py +1 -1
- nautobot/ipam/homepage.py +0 -1
- nautobot/ipam/lookups.py +2 -3
- nautobot/ipam/migrations/0002_initial_part_2.py +2 -1
- nautobot/ipam/migrations/0003_remove_max_length.py +1 -0
- nautobot/ipam/migrations/0004_fixup_p2p_broadcast.py +0 -1
- nautobot/ipam/migrations/0005_auto_slug.py +1 -0
- nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -0
- nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +1 -0
- nautobot/ipam/migrations/0020_related_name_changes.py +1 -0
- nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +1 -2
- nautobot/ipam/migrations/0024_interface_to_ipaddress_m2m.py +2 -1
- nautobot/ipam/migrations/0025_interface_ipaddress_m2m_data_migration.py +15 -13
- nautobot/ipam/migrations/0028_tagsfield.py +1 -0
- nautobot/ipam/migrations/0030_ipam__namespaces.py +3 -1
- nautobot/ipam/migrations/0034_status_nonnullable.py +1 -0
- nautobot/ipam/migrations/0037_data_migration_vlan_group_name_uniqueness.py +0 -1
- nautobot/ipam/migrations/0039_alter_ipaddresstointerface_ip_address.py +20 -0
- nautobot/ipam/models.py +11 -8
- nautobot/ipam/navigation.py +0 -1
- nautobot/ipam/querysets.py +48 -49
- nautobot/ipam/tables.py +11 -2
- nautobot/ipam/templates/ipam/ipaddress.html +30 -6
- nautobot/ipam/templates/ipam/ipaddress_interfaces.html +3 -3
- nautobot/ipam/templates/ipam/ipaddress_vm_interfaces.html +32 -0
- nautobot/ipam/tests/test_api.py +2 -2
- nautobot/ipam/tests/test_filters.py +13 -17
- nautobot/ipam/tests/test_migrations.py +1 -2
- nautobot/ipam/tests/test_models.py +17 -2
- nautobot/ipam/tests/test_ordering.py +1 -1
- nautobot/ipam/tests/test_querysets.py +2 -2
- nautobot/ipam/tests/test_views.py +6 -6
- nautobot/ipam/urls.py +6 -0
- nautobot/ipam/utils/migrations.py +0 -1
- nautobot/ipam/views.py +26 -6
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +142 -142
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +307 -307
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
- nautobot/project-static/css/base.css +59 -30
- nautobot/project-static/css/dark.css +38 -31
- nautobot/project-static/docs/404.html +17 -87
- nautobot/project-static/docs/apps/index.html +17 -87
- nautobot/project-static/docs/apps/nautobot-apps.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +405 -475
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +28 -98
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +2334 -2396
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +132 -202
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +155 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +42 -112
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1028 -1098
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +186 -256
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +1454 -1156
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1443 -1507
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +157 -203
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +17 -87
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +32 -102
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +3822 -3888
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +990 -1060
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +65 -123
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +1431 -1495
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +3618 -3640
- nautobot/project-static/docs/development/apps/api/configuration-view.html +17 -87
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +19 -89
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +17 -87
- nautobot/project-static/docs/development/apps/api/models/global-search.html +17 -87
- nautobot/project-static/docs/development/apps/api/models/graphql.html +17 -87
- nautobot/project-static/docs/development/apps/api/models/index.html +17 -87
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +17 -87
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +17 -87
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +19 -89
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +19 -89
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +19 -89
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +17 -87
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +17 -87
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +21 -87
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +17 -87
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +17 -87
- nautobot/project-static/docs/development/apps/api/prometheus.html +17 -87
- nautobot/project-static/docs/development/apps/api/setup.html +17 -87
- nautobot/project-static/docs/development/apps/api/testing.html +20 -90
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +17 -87
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +17 -87
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +17 -87
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +19 -89
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-detail-views.html +209 -140
- nautobot/project-static/docs/development/apps/api/ui-extensions/tabs.html +13 -5390
- nautobot/project-static/docs/development/apps/api/views/base-template.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +22 -92
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/index.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/notes.html +19 -89
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/urls.html +17 -87
- nautobot/project-static/docs/development/apps/api/views/view-overrides.html +13 -5385
- nautobot/project-static/docs/development/apps/index.html +17 -87
- nautobot/project-static/docs/development/apps/migration/code-updates.html +17 -87
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +17 -87
- nautobot/project-static/docs/development/apps/migration/from-v1.html +17 -88
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +17 -87
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +17 -87
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +17 -87
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +17 -87
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +17 -87
- nautobot/project-static/docs/development/core/application-registry.html +20 -90
- nautobot/project-static/docs/development/core/best-practices.html +20 -90
- nautobot/project-static/docs/development/core/bootstrap-ui.html +5360 -0
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +17 -87
- nautobot/project-static/docs/development/core/extending-models.html +21 -87
- nautobot/project-static/docs/development/core/generic-views.html +17 -87
- nautobot/project-static/docs/development/core/getting-started.html +124 -301
- nautobot/project-static/docs/development/core/homepage.html +17 -87
- nautobot/project-static/docs/development/core/index.html +17 -87
- nautobot/project-static/docs/development/core/model-features.html +17 -87
- nautobot/project-static/docs/development/core/natural-keys.html +17 -87
- nautobot/project-static/docs/development/core/navigation-menu.html +17 -87
- nautobot/project-static/docs/development/core/react-ui.html +13 -5668
- nautobot/project-static/docs/development/core/release-checklist.html +20 -96
- nautobot/project-static/docs/development/core/role-internals.html +20 -90
- nautobot/project-static/docs/development/core/style-guide.html +77 -146
- nautobot/project-static/docs/development/core/templates.html +20 -90
- nautobot/project-static/docs/development/core/testing.html +17 -87
- nautobot/project-static/docs/development/core/user-preferences.html +17 -87
- nautobot/project-static/docs/development/index.html +17 -87
- nautobot/project-static/docs/development/jobs/index.html +424 -425
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +75 -98
- nautobot/project-static/docs/development/react-ui.html +3 -3
- nautobot/project-static/docs/img/relationship_w_json_filter.png +0 -0
- nautobot/project-static/docs/index.html +90 -93
- nautobot/project-static/docs/media/admin_ui_run_permission.png +0 -0
- nautobot/project-static/docs/media/development/homepage_changelog_panel.png +0 -0
- nautobot/project-static/docs/media/development/homepage_dcim_panel.png +0 -0
- nautobot/project-static/docs/media/installation/nautobot_ui_admin.png +0 -0
- nautobot/project-static/docs/media/installation/nautobot_ui_login.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_filtering_01.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_01.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_02.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_03.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_04.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_1_05.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_01.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_02.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_03.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_04.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_05.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_06.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_advanced_2_07.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_01.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_02.png +0 -0
- nautobot/project-static/docs/media/models/dynamicgroup_workflow_basic_03.png +0 -0
- nautobot/project-static/docs/media/models/jobbutton_form.png +0 -0
- nautobot/project-static/docs/media/models/site_jobbuttons.png +0 -0
- nautobot/project-static/docs/media/plugins/plugin_admin_config.png +0 -0
- nautobot/project-static/docs/media/plugins/plugin_admin_ui.png +0 -0
- nautobot/project-static/docs/media/ss_config_contexts.png +0 -0
- nautobot/project-static/docs/media/ss_graphiql.png +0 -0
- nautobot/project-static/docs/media/ss_main_page.png +0 -0
- nautobot/project-static/docs/media/ss_plugin_chatops.png +0 -0
- nautobot/project-static/docs/media/ss_plugin_golden_config.png +0 -0
- nautobot/project-static/docs/media/ss_prefix_hierarchy.png +0 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.0.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.1.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.2.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.3.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.4.html +18 -88
- nautobot/project-static/docs/release-notes/version-1.5.html +17 -87
- nautobot/project-static/docs/release-notes/version-1.6.html +17 -87
- nautobot/project-static/docs/release-notes/version-2.0.html +467 -336
- nautobot/project-static/docs/release-notes/version-2.1.html +470 -108
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +240 -255
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +17 -87
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +20 -90
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +17 -87
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +17 -87
- nautobot/project-static/docs/user-guide/administration/configuration/node-configuration.html +13 -5417
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +47 -113
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +17 -87
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/index.html +22 -109
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +18 -101
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +23 -140
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +17 -87
- nautobot/project-static/docs/user-guide/administration/installation/services.html +17 -87
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +17 -87
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +17 -87
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +92 -181
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +18 -88
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +17 -87
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +23 -89
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +18 -88
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio +259 -1
- nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.png +0 -0
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +18 -88
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +17 -87
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +17 -87
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +17 -87
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +23 -93
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +17 -87
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +17 -87
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +26 -96
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +35 -103
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +19 -89
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +19 -91
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +19 -89
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +24 -94
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +39 -258
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +45 -243
- nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_choices.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_grouped.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_detail_label.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_edit.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/custom-fields/custom_field_select.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/1-create-location-type.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/10-add-platform.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/11-platforms-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/12-add-tenant.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/13-assign-tenant-to-device.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/14-assign-tenant-to-device-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/15-create-device-type.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/16-interface-templates.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/17-templated-interfaces.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/18-assign-device-type.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/19-edit-ints-for-lag.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/2-create-manufacturer.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/20-ints-int-lag.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/21-device-type.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/22-create-vlans.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/23-create-vlans-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/24-vlan-main-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/25-add-vlan-to-interface.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/26-add-vlan-to-interface-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/27-add-rir.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/3-create-role.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/30-add-prefix.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/32-add-ip-addr.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/33-assign-address.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/34-assign-address-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/35-assign-address-3.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/36-verify-address.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/37-verify-prefix.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/38-verify-prefix2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/4-create-device-type.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/41-device-search-results.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/42-address-search-v2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/43-get-to-device-main-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/44-add-platform.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/5-create-device.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/6-create-location.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/7-location-type-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/8-location-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/01-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/02-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/03-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/04-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/05-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/06-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/07-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/08-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/09-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/10-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/11-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/12-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/13-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/14-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/15-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/16-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/17-git-data-source.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/00-graphiql.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/01-graphiql-explorer.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/02-graphiql-explorer-device-query.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/03-graphiql-explorer-device-attributes.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/04-graphql-query-01.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/05-graphiql-autocomplete.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/06-graphql-query-02.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/07-graphql-query-03.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/08-graphql-query-04.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/09-graphql-query-05.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/10-graphql-swagger.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/graphql/11-graphql-query-06.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/ip_merge_button.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_button.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/merge_view.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/no_more_dup_ips.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/skip_button.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/ip-address-merge-tool/unselect_ips.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/01-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/02-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/03-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/04-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/05-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/06-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/07-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/08-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/09-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/10-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/relationships/11-relationships.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +20 -90
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +22 -92
- nautobot/project-static/docs/user-guide/index.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +22 -88
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +68 -87
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +18 -88
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +22 -88
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +18 -88
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +43 -91
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +21 -87
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +17 -87
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +17 -87
- nautobot/project-static/js/homepage_layout.js +170 -0
- nautobot/project-static/js/theme.js +0 -5
- nautobot/tenancy/api/urls.py +1 -1
- nautobot/tenancy/api/views.py +1 -0
- nautobot/tenancy/factory.py +2 -2
- nautobot/tenancy/filters/__init__.py +1 -2
- nautobot/tenancy/forms.py +2 -2
- nautobot/tenancy/homepage.py +0 -1
- nautobot/tenancy/migrations/0001_initial.py +2 -1
- nautobot/tenancy/migrations/0002_auto_slug.py +1 -0
- nautobot/tenancy/migrations/0004_change_tree_manager_on_tree_models.py +1 -0
- nautobot/tenancy/migrations/0008_tagsfield.py +1 -0
- nautobot/tenancy/models.py +0 -1
- nautobot/tenancy/navigation.py +0 -1
- nautobot/tenancy/tables.py +1 -0
- nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
- nautobot/tenancy/tests/test_filters.py +5 -5
- nautobot/tenancy/urls.py +1 -0
- nautobot/tenancy/views.py +2 -2
- nautobot/users/admin.py +1 -2
- nautobot/users/api/urls.py +1 -1
- nautobot/users/api/views.py +6 -4
- nautobot/users/factory.py +8 -24
- nautobot/users/filters.py +4 -4
- nautobot/users/forms.py +1 -0
- nautobot/users/migrations/0004_alter_user_managers.py +1 -0
- nautobot/users/migrations/0008_make_object_permission_a_changelogged_model.py +22 -0
- nautobot/users/models.py +2 -2
- nautobot/users/tests/test_api.py +7 -6
- nautobot/users/tests/test_filters.py +0 -1
- nautobot/users/tests/test_models.py +0 -1
- nautobot/users/tests/test_password_ui.py +1 -1
- nautobot/users/views.py +5 -4
- nautobot/virtualization/api/urls.py +1 -1
- nautobot/virtualization/api/views.py +2 -1
- nautobot/virtualization/apps.py +1 -1
- nautobot/virtualization/choices.py +0 -1
- nautobot/virtualization/factory.py +1 -1
- nautobot/virtualization/filters.py +1 -1
- nautobot/virtualization/forms.py +6 -6
- nautobot/virtualization/homepage.py +0 -1
- nautobot/virtualization/migrations/0003_vminterface_verbose_name.py +1 -0
- nautobot/virtualization/migrations/0004_auto_slug.py +1 -0
- nautobot/virtualization/migrations/0005_add_natural_indexing.py +1 -0
- nautobot/virtualization/migrations/0006_vminterface_status.py +1 -0
- nautobot/virtualization/migrations/0007_vminterface_status_data_migration.py +1 -0
- nautobot/virtualization/migrations/0011_alter_vminterface_mac_address.py +1 -0
- nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -0
- nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +1 -0
- nautobot/virtualization/migrations/0018_related_name_changes.py +1 -0
- nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +1 -0
- nautobot/virtualization/migrations/0025_status_nonnullable.py +1 -0
- nautobot/virtualization/models.py +1 -2
- nautobot/virtualization/navigation.py +0 -1
- nautobot/virtualization/signals.py +0 -1
- nautobot/virtualization/tables.py +1 -0
- nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -2
- nautobot/virtualization/tests/test_filters.py +3 -3
- nautobot/virtualization/tests/test_models.py +1 -1
- nautobot/virtualization/tests/test_views.py +2 -2
- nautobot/virtualization/urls.py +1 -0
- nautobot/virtualization/views.py +1 -1
- {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/METADATA +10 -2
- {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/RECORD +895 -993
- nautobot/core/management/commands/build_ui.py +0 -281
- nautobot/core/templates/base_react.html +0 -55
- nautobot/core/tests/test_cli.py +0 -25
- nautobot/project-static/docs/media/installation/nautobot_ui_guest.png +0 -0
- nautobot/project-static/docs/user-guide/core-data-model/ipam/media/ipam_namespace_documentation.drawio.svg +0 -4
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/39-address-search.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/getting-started-nautobot-ui/40-addr-main-page.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/git-as-data-source/18-git-data-source.png +0 -0
- nautobot/ui/.eslintignore +0 -3
- nautobot/ui/.gitignore +0 -7
- nautobot/ui/.prettierignore +0 -6
- nautobot/ui/.prettierrc +0 -4
- nautobot/ui/README.md +0 -27
- nautobot/ui/config/env.js +0 -102
- nautobot/ui/config/getHttpsConfig.js +0 -68
- nautobot/ui/config/jest/babelTransform.js +0 -14
- nautobot/ui/config/jest/cssTransform.js +0 -12
- nautobot/ui/config/jest/fileTransform.js +0 -38
- nautobot/ui/config/modules.js +0 -151
- nautobot/ui/config/paths.js +0 -67
- nautobot/ui/config/webpack/persistentCache/createEnvironmentHash.js +0 -8
- nautobot/ui/config/webpack.config.js +0 -674
- nautobot/ui/config/webpackDevServer.config.js +0 -127
- nautobot/ui/jest.config.js +0 -35
- nautobot/ui/jsconfig.json +0 -4
- nautobot/ui/package-lock.json +0 -22947
- nautobot/ui/package.json +0 -119
- nautobot/ui/public/index.html +0 -47
- nautobot/ui/public/logo192.png +0 -0
- nautobot/ui/public/logo512.png +0 -0
- nautobot/ui/public/manifest.json +0 -25
- nautobot/ui/public/nautobot_logo.svg +0 -131
- nautobot/ui/public/robots.txt +0 -3
- nautobot/ui/scripts/build.js +0 -224
- nautobot/ui/scripts/start.js +0 -140
- nautobot/ui/scripts/test.js +0 -40
- nautobot/ui/src/App.js +0 -79
- nautobot/ui/src/components/AppFullWidthComponents.js +0 -8
- nautobot/ui/src/components/AppTab.js +0 -40
- nautobot/ui/src/components/Apps.js +0 -60
- nautobot/ui/src/components/FeedbackModal.js +0 -123
- nautobot/ui/src/components/FiltersPanel.js +0 -693
- nautobot/ui/src/components/HomeChangelogPanel.js +0 -98
- nautobot/ui/src/components/HomePanel.js +0 -58
- nautobot/ui/src/components/JobHistoryTable.js +0 -78
- nautobot/ui/src/components/Layout.js +0 -76
- nautobot/ui/src/components/LoadingWidget.js +0 -14
- nautobot/ui/src/components/Navbar.js +0 -204
- nautobot/ui/src/components/NotificationPopover.js +0 -27
- nautobot/ui/src/components/ObjectTable/ObjectListTable.js +0 -300
- nautobot/ui/src/components/ObjectTable/ObjectTable.js +0 -96
- nautobot/ui/src/components/ObjectTable/ObjectTableItem.js +0 -70
- nautobot/ui/src/components/ObjectTable/index.js +0 -3
- nautobot/ui/src/components/Pagination/PageNumberForm.js +0 -228
- nautobot/ui/src/components/Pagination/PageSizeForm.js +0 -65
- nautobot/ui/src/components/Pagination/Pagination.js +0 -67
- nautobot/ui/src/components/Pagination/index.js +0 -3
- nautobot/ui/src/components/ReferenceDataTag.js +0 -35
- nautobot/ui/src/components/Retrieve/RenderChangeLogsTab.js +0 -58
- nautobot/ui/src/components/Retrieve/RenderColumn.js +0 -30
- nautobot/ui/src/components/Retrieve/RenderGroup.js +0 -24
- nautobot/ui/src/components/Retrieve/RenderHeader.js +0 -125
- nautobot/ui/src/components/Retrieve/RenderNotesTab.js +0 -60
- nautobot/ui/src/components/Retrieve/RenderTable.js +0 -33
- nautobot/ui/src/components/Retrieve/RenderTabs.js +0 -56
- nautobot/ui/src/components/Retrieve/index.js +0 -7
- nautobot/ui/src/components/RouterButton.js +0 -10
- nautobot/ui/src/components/RouterLink.js +0 -10
- nautobot/ui/src/components/SidebarNav.js +0 -156
- nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +0 -16
- nautobot/ui/src/components/__tests__/AppTab.test.js +0 -21
- nautobot/ui/src/components/__tests__/Apps.test.js +0 -14
- nautobot/ui/src/components/__tests__/Layout.test.js +0 -33
- nautobot/ui/src/components/__tests__/PageSizeForm.test.js +0 -13
- nautobot/ui/src/components/__tests__/Pagination.test.js +0 -43
- nautobot/ui/src/components/__tests__/Table.test.js +0 -39
- nautobot/ui/src/components/__tests__/TableItem.test.js +0 -39
- nautobot/ui/src/components/index.js +0 -4
- nautobot/ui/src/constants/apiPath.js +0 -13
- nautobot/ui/src/constants/icons.js +0 -15
- nautobot/ui/src/constants/size.js +0 -15
- nautobot/ui/src/file_templates/app_imports.js.j2 +0 -7
- nautobot/ui/src/file_templates/jsconfig-base.json +0 -12
- nautobot/ui/src/index.js +0 -65
- nautobot/ui/src/reportWebVitals.js +0 -15
- nautobot/ui/src/router.js +0 -77
- nautobot/ui/src/utils/api.js +0 -160
- nautobot/ui/src/utils/app-import.js +0 -15
- nautobot/ui/src/utils/color.js +0 -15
- nautobot/ui/src/utils/date.js +0 -14
- nautobot/ui/src/utils/index.js +0 -15
- nautobot/ui/src/utils/navigation.js +0 -48
- nautobot/ui/src/utils/session.js +0 -64
- nautobot/ui/src/utils/store.js +0 -242
- nautobot/ui/src/utils/string.js +0 -6
- nautobot/ui/src/utils/url.js +0 -4
- nautobot/ui/src/views/Home.js +0 -142
- nautobot/ui/src/views/InstalledApps.js +0 -80
- nautobot/ui/src/views/Login.js +0 -48
- nautobot/ui/src/views/Logout.js +0 -20
- nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +0 -11
- nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +0 -107
- nautobot/ui/src/views/__tests__/Login.test.js +0 -15
- nautobot/ui/src/views/generic/GenericView.js +0 -191
- nautobot/ui/src/views/generic/ObjectCreate.js +0 -96
- nautobot/ui/src/views/generic/ObjectList.js +0 -137
- nautobot/ui/src/views/generic/ObjectRetrieve.js +0 -87
- {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/WHEEL +0 -0
- {nautobot-2.1.0b1.dist-info → nautobot-2.1.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from datetime import timedelta
|
|
2
|
+
from unittest import mock
|
|
2
3
|
import urllib.parse
|
|
3
4
|
import uuid
|
|
4
5
|
|
|
@@ -9,13 +10,12 @@ from django.test import override_settings
|
|
|
9
10
|
from django.urls import reverse
|
|
10
11
|
from django.utils import timezone
|
|
11
12
|
from django.utils.html import format_html
|
|
12
|
-
from unittest import mock
|
|
13
13
|
|
|
14
14
|
from nautobot.core.choices import ColorChoices
|
|
15
15
|
from nautobot.core.models.fields import slugify_dashes_to_underscores
|
|
16
|
-
from nautobot.core.testing import
|
|
16
|
+
from nautobot.core.testing import extract_form_failures, extract_page_body, TestCase, ViewTestCases
|
|
17
17
|
from nautobot.core.testing.utils import disable_warnings, post_data
|
|
18
|
-
from nautobot.dcim.models import ConsolePort, Device, DeviceType, Interface,
|
|
18
|
+
from nautobot.dcim.models import ConsolePort, Device, DeviceType, Interface, Location, LocationType, Manufacturer
|
|
19
19
|
from nautobot.dcim.tests import test_views
|
|
20
20
|
from nautobot.extras.choices import (
|
|
21
21
|
CustomFieldTypeChoices,
|
|
@@ -23,6 +23,7 @@ from nautobot.extras.choices import (
|
|
|
23
23
|
ObjectChangeActionChoices,
|
|
24
24
|
SecretsGroupAccessTypeChoices,
|
|
25
25
|
SecretsGroupSecretTypeChoices,
|
|
26
|
+
WebhookHttpMethodChoices,
|
|
26
27
|
)
|
|
27
28
|
from nautobot.extras.constants import HTTP_CONTENT_TYPE_JSON
|
|
28
29
|
from nautobot.extras.models import (
|
|
@@ -52,13 +53,13 @@ from nautobot.extras.models import (
|
|
|
52
53
|
Tag,
|
|
53
54
|
Webhook,
|
|
54
55
|
)
|
|
56
|
+
from nautobot.extras.templatetags.job_buttons import NO_CONFIRM_BUTTON
|
|
55
57
|
from nautobot.extras.tests.constants import BIG_GRAPHQL_DEVICE_QUERY
|
|
56
58
|
from nautobot.extras.tests.test_relationships import RequiredRelationshipTestMixin
|
|
57
59
|
from nautobot.extras.utils import RoleModelsQuery, TaggableClassesQuery
|
|
58
60
|
from nautobot.ipam.models import IPAddress, Prefix, VLAN, VLANGroup
|
|
59
61
|
from nautobot.users.models import ObjectPermission
|
|
60
62
|
|
|
61
|
-
|
|
62
63
|
# Use the proper swappable User model
|
|
63
64
|
User = get_user_model()
|
|
64
65
|
|
|
@@ -696,12 +697,12 @@ class ExportTemplateTestCase(
|
|
|
696
697
|
|
|
697
698
|
class ExternalIntegrationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
698
699
|
model = ExternalIntegration
|
|
699
|
-
bulk_edit_data = {"timeout": 10, "verify_ssl": True, "extra_config": r"{}"}
|
|
700
|
+
bulk_edit_data = {"timeout": 10, "verify_ssl": True, "extra_config": r"{}", "headers": r"{}"}
|
|
700
701
|
csv_data = (
|
|
701
|
-
"name,remote_url,verify_ssl,timeout",
|
|
702
|
-
"Test External Integration 1,https://example.com/test1/,False,10",
|
|
703
|
-
"Test External Integration 2,https://example.com/test2/,True,20",
|
|
704
|
-
"Test External Integration 3,https://example.com/test3/,False,30",
|
|
702
|
+
"name,remote_url,verify_ssl,timeout,http_method",
|
|
703
|
+
"Test External Integration 1,https://example.com/test1/,False,10,POST",
|
|
704
|
+
"Test External Integration 2,https://example.com/test2/,True,20,DELETE",
|
|
705
|
+
"Test External Integration 3,https://example.com/test3/,False,30,PATCH",
|
|
705
706
|
)
|
|
706
707
|
form_data = {
|
|
707
708
|
"name": "Test External Integration",
|
|
@@ -710,6 +711,9 @@ class ExternalIntegrationTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
|
710
711
|
"secrets_group": None,
|
|
711
712
|
"timeout": 10,
|
|
712
713
|
"extra_config": '{"foo": "bar"}',
|
|
714
|
+
"http_method": WebhookHttpMethodChoices.METHOD_GET,
|
|
715
|
+
"headers": '{"header": "fake header"}',
|
|
716
|
+
"ca_file_path": "this/is/a/file/path",
|
|
713
717
|
}
|
|
714
718
|
|
|
715
719
|
|
|
@@ -916,9 +920,9 @@ class SecretsGroupTestCase(
|
|
|
916
920
|
)
|
|
917
921
|
|
|
918
922
|
secrets = (
|
|
919
|
-
Secret.objects.create(name="secret 1", provider="text-file", parameters={"path": "/tmp"}),
|
|
920
|
-
Secret.objects.create(name="secret 2", provider="text-file", parameters={"path": "/tmp"}),
|
|
921
|
-
Secret.objects.create(name="secret 3", provider="text-file", parameters={"path": "/tmp"}),
|
|
923
|
+
Secret.objects.create(name="secret 1", provider="text-file", parameters={"path": "/tmp"}), # noqa: S108 # hardcoded-temp-file -- false positive
|
|
924
|
+
Secret.objects.create(name="secret 2", provider="text-file", parameters={"path": "/tmp"}), # noqa: S108 # hardcoded-temp-file -- false positive
|
|
925
|
+
Secret.objects.create(name="secret 3", provider="text-file", parameters={"path": "/tmp"}), # noqa: S108 # hardcoded-temp-file -- false positive
|
|
922
926
|
)
|
|
923
927
|
|
|
924
928
|
SecretsGroupAssociation.objects.create(
|
|
@@ -1033,7 +1037,7 @@ class ScheduledJobTestCase(
|
|
|
1033
1037
|
def test_only_enabled_is_listed(self):
|
|
1034
1038
|
self.add_permissions("extras.view_scheduledjob")
|
|
1035
1039
|
|
|
1036
|
-
# this should not appear, since it
|
|
1040
|
+
# this should not appear, since it's not enabled
|
|
1037
1041
|
ScheduledJob.objects.create(
|
|
1038
1042
|
enabled=False,
|
|
1039
1043
|
name="test4",
|
|
@@ -2015,14 +2019,24 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
2015
2019
|
|
|
2016
2020
|
def setUp(self):
|
|
2017
2021
|
super().setUp()
|
|
2018
|
-
self.
|
|
2019
|
-
name="JobButton",
|
|
2022
|
+
self.job_button_1 = JobButton(
|
|
2023
|
+
name="JobButton 1",
|
|
2020
2024
|
text="JobButton {{ obj.name }}",
|
|
2021
2025
|
job=Job.objects.get(job_class_name="TestJobButtonReceiverSimple"),
|
|
2022
2026
|
confirmation=False,
|
|
2023
2027
|
)
|
|
2024
|
-
self.
|
|
2025
|
-
self.
|
|
2028
|
+
self.job_button_1.validated_save()
|
|
2029
|
+
self.job_button_1.content_types.add(ContentType.objects.get_for_model(LocationType))
|
|
2030
|
+
|
|
2031
|
+
self.job_button_2 = JobButton(
|
|
2032
|
+
name="JobButton 2",
|
|
2033
|
+
text="Click me!",
|
|
2034
|
+
job=Job.objects.get(job_class_name="TestJobButtonReceiverComplex"),
|
|
2035
|
+
confirmation=False,
|
|
2036
|
+
)
|
|
2037
|
+
self.job_button_2.validated_save()
|
|
2038
|
+
self.job_button_2.content_types.add(ContentType.objects.get_for_model(LocationType))
|
|
2039
|
+
|
|
2026
2040
|
self.location_type = LocationType.objects.get(name="Campus")
|
|
2027
2041
|
|
|
2028
2042
|
def test_view_object_with_job_button(self):
|
|
@@ -2031,11 +2045,12 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
2031
2045
|
self.assertEqual(response.status_code, 200)
|
|
2032
2046
|
content = extract_page_body(response.content.decode(response.charset))
|
|
2033
2047
|
self.assertIn(f"JobButton {self.location_type.name}", content, content)
|
|
2048
|
+
self.assertIn("Click me!", content, content)
|
|
2034
2049
|
|
|
2035
2050
|
def test_view_object_with_unsafe_text(self):
|
|
2036
2051
|
"""Ensure that JobButton text can't be used as a vector for XSS."""
|
|
2037
|
-
self.
|
|
2038
|
-
self.
|
|
2052
|
+
self.job_button_1.text = '<script>alert("Hello world!")</script>'
|
|
2053
|
+
self.job_button_1.validated_save()
|
|
2039
2054
|
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
2040
2055
|
self.assertEqual(response.status_code, 200)
|
|
2041
2056
|
content = extract_page_body(response.content.decode(response.charset))
|
|
@@ -2043,8 +2058,8 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
2043
2058
|
self.assertIn("<script>alert", content, content)
|
|
2044
2059
|
|
|
2045
2060
|
# Make sure grouped rendering is safe too
|
|
2046
|
-
self.
|
|
2047
|
-
self.
|
|
2061
|
+
self.job_button_1.group_name = '<script>alert("Goodbye")</script>'
|
|
2062
|
+
self.job_button_1.validated_save()
|
|
2048
2063
|
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
2049
2064
|
self.assertEqual(response.status_code, 200)
|
|
2050
2065
|
content = extract_page_body(response.content.decode(response.charset))
|
|
@@ -2053,15 +2068,80 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
2053
2068
|
|
|
2054
2069
|
def test_view_object_with_unsafe_name(self):
|
|
2055
2070
|
"""Ensure that JobButton names can't be used as a vector for XSS."""
|
|
2056
|
-
self.
|
|
2057
|
-
self.
|
|
2058
|
-
self.
|
|
2071
|
+
self.job_button_1.text = "JobButton {{ obj"
|
|
2072
|
+
self.job_button_1.name = '<script>alert("Yo")</script>'
|
|
2073
|
+
self.job_button_1.validated_save()
|
|
2059
2074
|
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
2060
2075
|
self.assertEqual(response.status_code, 200)
|
|
2061
2076
|
content = extract_page_body(response.content.decode(response.charset))
|
|
2062
2077
|
self.assertNotIn("<script>alert", content, content)
|
|
2063
2078
|
self.assertIn("<script>alert", content, content)
|
|
2064
2079
|
|
|
2080
|
+
def test_render_constrained_run_permissions(self):
|
|
2081
|
+
obj_perm = ObjectPermission(
|
|
2082
|
+
name="Test permission",
|
|
2083
|
+
constraints={"pk": self.job_button_1.job.pk},
|
|
2084
|
+
actions=["run"],
|
|
2085
|
+
)
|
|
2086
|
+
obj_perm.save()
|
|
2087
|
+
obj_perm.users.add(self.user)
|
|
2088
|
+
obj_perm.object_types.add(ContentType.objects.get_for_model(Job))
|
|
2089
|
+
|
|
2090
|
+
with self.subTest("Ungrouped buttons"):
|
|
2091
|
+
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
2092
|
+
self.assertEqual(response.status_code, 200)
|
|
2093
|
+
content = extract_page_body(response.content.decode(response.charset))
|
|
2094
|
+
self.assertInHTML(
|
|
2095
|
+
NO_CONFIRM_BUTTON.format(
|
|
2096
|
+
button_id=self.job_button_1.pk,
|
|
2097
|
+
button_text=f"JobButton {self.location_type.name}",
|
|
2098
|
+
button_class=self.job_button_1.button_class,
|
|
2099
|
+
disabled="",
|
|
2100
|
+
),
|
|
2101
|
+
content,
|
|
2102
|
+
)
|
|
2103
|
+
self.assertInHTML(
|
|
2104
|
+
NO_CONFIRM_BUTTON.format(
|
|
2105
|
+
button_id=self.job_button_2.pk,
|
|
2106
|
+
button_text="Click me!",
|
|
2107
|
+
button_class=self.job_button_2.button_class,
|
|
2108
|
+
disabled="disabled",
|
|
2109
|
+
),
|
|
2110
|
+
content,
|
|
2111
|
+
)
|
|
2112
|
+
|
|
2113
|
+
with self.subTest("Grouped buttons"):
|
|
2114
|
+
self.job_button_1.group_name = "Grouping"
|
|
2115
|
+
self.job_button_1.validated_save()
|
|
2116
|
+
self.job_button_2.group_name = "Grouping"
|
|
2117
|
+
self.job_button_2.validated_save()
|
|
2118
|
+
|
|
2119
|
+
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
2120
|
+
self.assertEqual(response.status_code, 200)
|
|
2121
|
+
content = extract_page_body(response.content.decode(response.charset))
|
|
2122
|
+
self.assertInHTML(
|
|
2123
|
+
"<li>"
|
|
2124
|
+
+ NO_CONFIRM_BUTTON.format(
|
|
2125
|
+
button_id=self.job_button_1.pk,
|
|
2126
|
+
button_text=f"JobButton {self.location_type.name}",
|
|
2127
|
+
button_class="link",
|
|
2128
|
+
disabled="",
|
|
2129
|
+
)
|
|
2130
|
+
+ "</li>",
|
|
2131
|
+
content,
|
|
2132
|
+
)
|
|
2133
|
+
self.assertInHTML(
|
|
2134
|
+
"<li>"
|
|
2135
|
+
+ NO_CONFIRM_BUTTON.format(
|
|
2136
|
+
button_id=self.job_button_2.pk,
|
|
2137
|
+
button_text="Click me!",
|
|
2138
|
+
button_class="link",
|
|
2139
|
+
disabled="disabled",
|
|
2140
|
+
)
|
|
2141
|
+
+ "</li>",
|
|
2142
|
+
content,
|
|
2143
|
+
)
|
|
2144
|
+
|
|
2065
2145
|
|
|
2066
2146
|
# TODO: Convert to StandardTestCases.Views
|
|
2067
2147
|
class ObjectChangeTestCase(TestCase):
|
|
@@ -2213,7 +2293,7 @@ class RelationshipTestCase(
|
|
|
2213
2293
|
"relationship "VLANs require at least one Device"",
|
|
2214
2294
|
)
|
|
2215
2295
|
for vlan in vlans[:3]:
|
|
2216
|
-
self.assertContains(response,
|
|
2296
|
+
self.assertContains(response, str(vlan))
|
|
2217
2297
|
|
|
2218
2298
|
# Try editing 6 VLANs and adding the required device (succeeds):
|
|
2219
2299
|
response = self.client.post(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import uuid
|
|
3
1
|
from copy import deepcopy
|
|
2
|
+
import json
|
|
4
3
|
from unittest.mock import patch
|
|
4
|
+
import uuid
|
|
5
5
|
|
|
6
6
|
from django.apps import apps
|
|
7
7
|
from django.contrib.auth import get_user_model
|
|
@@ -17,13 +17,12 @@ from nautobot.dcim.api.serializers import LocationSerializer
|
|
|
17
17
|
from nautobot.dcim.models import Location, LocationType
|
|
18
18
|
from nautobot.extras.choices import ObjectChangeActionChoices
|
|
19
19
|
from nautobot.extras.context_managers import web_request_context
|
|
20
|
-
from nautobot.extras.models import
|
|
20
|
+
from nautobot.extras.models import Tag, Webhook
|
|
21
21
|
from nautobot.extras.models.statuses import Status
|
|
22
22
|
from nautobot.extras.registry import registry
|
|
23
23
|
from nautobot.extras.tasks import process_webhook
|
|
24
24
|
from nautobot.extras.utils import generate_signature
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
User = get_user_model()
|
|
28
27
|
|
|
29
28
|
|
|
@@ -32,7 +31,7 @@ class WebhookTest(APITestCase):
|
|
|
32
31
|
def setUpTestData(cls):
|
|
33
32
|
location_ct = ContentType.objects.get_for_model(Location)
|
|
34
33
|
MOCK_URL = "http://localhost/"
|
|
35
|
-
MOCK_SECRET = "LOOKATMEIMASECRETSTRING"
|
|
34
|
+
MOCK_SECRET = "LOOKATMEIMASECRETSTRING" # noqa: S105 # hardcoded-password-string -- OK as this is test code
|
|
36
35
|
|
|
37
36
|
webhooks = (
|
|
38
37
|
Webhook.objects.create(
|
nautobot/extras/urls.py
CHANGED
|
@@ -480,8 +480,6 @@ urlpatterns = [
|
|
|
480
480
|
views.JobResultDeleteView.as_view(),
|
|
481
481
|
name="jobresult_delete",
|
|
482
482
|
),
|
|
483
|
-
# Job Button Run
|
|
484
|
-
path("job-button/<uuid:pk>/run/", views.JobButtonRunView.as_view(), name="jobbutton_run"),
|
|
485
483
|
# Notes
|
|
486
484
|
path("notes/", views.NoteListView.as_view(), name="note_list"),
|
|
487
485
|
path("notes/add/", views.NoteEditView.as_view(), name="note_add"),
|
nautobot/extras/utils.py
CHANGED
|
@@ -25,7 +25,6 @@ from nautobot.extras.constants import (
|
|
|
25
25
|
)
|
|
26
26
|
from nautobot.extras.registry import registry
|
|
27
27
|
|
|
28
|
-
|
|
29
28
|
logger = logging.getLogger(__name__)
|
|
30
29
|
|
|
31
30
|
|
|
@@ -338,9 +337,9 @@ def refresh_job_model_from_job_class(job_model_class, job_class):
|
|
|
338
337
|
and in that case we need to not import models ourselves.
|
|
339
338
|
"""
|
|
340
339
|
from nautobot.extras.jobs import (
|
|
341
|
-
JobHookReceiver,
|
|
342
340
|
JobButtonReceiver,
|
|
343
|
-
|
|
341
|
+
JobHookReceiver,
|
|
342
|
+
)
|
|
344
343
|
|
|
345
344
|
# Unrecoverable errors
|
|
346
345
|
if len(job_class.__module__) > JOB_MAX_NAME_LENGTH:
|
|
@@ -526,10 +525,17 @@ def migrate_role_data(
|
|
|
526
525
|
to_role_choiceset (ChoiceSet): If `to_role_field` is a choices field, the corresponding ChoiceSet for it
|
|
527
526
|
is_m2m_field (bool): True if the role fields are both ManyToManyFields, else False
|
|
528
527
|
"""
|
|
528
|
+
if from_role_model is not None and from_role_choiceset is not None:
|
|
529
|
+
raise RuntimeError("from_role_model and from_role_choiceset are mutually exclusive")
|
|
530
|
+
if from_role_model is None and from_role_choiceset is None:
|
|
531
|
+
raise RuntimeError("One of from_role_model or from_role_choiceset must be specified and not None")
|
|
532
|
+
if to_role_model is not None and to_role_choiceset is not None:
|
|
533
|
+
raise RuntimeError("to_role_model and to_role_choiceset are mutually exclusive")
|
|
534
|
+
if to_role_model is None and to_role_choiceset is None:
|
|
535
|
+
raise RuntimeError("One of to_role_model or to_role_choiceset must be specified and not None")
|
|
536
|
+
|
|
529
537
|
if from_role_model is not None:
|
|
530
|
-
assert from_role_choiceset is None
|
|
531
538
|
if to_role_model is not None:
|
|
532
|
-
assert to_role_choiceset is None
|
|
533
539
|
# Mapping "from" model instances to corresponding "to" model instances
|
|
534
540
|
roles_translation_mapping = {
|
|
535
541
|
# Use .filter().first(), not .get() because "to" role might not exist, especially on reverse migrations
|
|
@@ -537,7 +543,6 @@ def migrate_role_data(
|
|
|
537
543
|
for from_role in from_role_model.objects.all()
|
|
538
544
|
}
|
|
539
545
|
else:
|
|
540
|
-
assert to_role_choiceset is not None
|
|
541
546
|
# Mapping "from" model instances to corresponding "to" choices
|
|
542
547
|
# We need to use `label` to look up the from_role instance, but `value` is what we set for the to_role_field
|
|
543
548
|
inverted_to_role_choiceset = {label: value for value, label in to_role_choiceset.CHOICES}
|
|
@@ -546,9 +551,7 @@ def migrate_role_data(
|
|
|
546
551
|
for from_role in from_role_model.objects.all()
|
|
547
552
|
}
|
|
548
553
|
else:
|
|
549
|
-
assert from_role_choiceset is not None
|
|
550
554
|
if to_role_model is not None:
|
|
551
|
-
assert to_role_choiceset is None
|
|
552
555
|
# Mapping "from" choices to corresponding "to" model instances
|
|
553
556
|
roles_translation_mapping = {
|
|
554
557
|
# Use .filter().first(), not .get() because "to" role might not exist, especially on reverse migrations
|
|
@@ -556,7 +559,6 @@ def migrate_role_data(
|
|
|
556
559
|
for from_role_value, from_role_label in from_role_choiceset.CHOICES
|
|
557
560
|
}
|
|
558
561
|
else:
|
|
559
|
-
assert to_role_choiceset is not None
|
|
560
562
|
# Mapping "from" choices to corresponding "to" choices; we don't currently use this case, but it should work
|
|
561
563
|
# We need to use `label` to look up the from_role instance, but `value` is what we set for the to_role_field
|
|
562
564
|
inverted_to_role_choiceset = {label: value for value, label in to_role_choiceset.CHOICES}
|
nautobot/extras/views.py
CHANGED
|
@@ -10,11 +10,12 @@ from django.db.models import Count, ProtectedError, Q
|
|
|
10
10
|
from django.forms.utils import pretty_name
|
|
11
11
|
from django.http import Http404, HttpResponse, HttpResponseForbidden
|
|
12
12
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
13
|
-
from django.template.loader import
|
|
13
|
+
from django.template.loader import get_template, TemplateDoesNotExist
|
|
14
14
|
from django.urls import reverse
|
|
15
15
|
from django.utils import timezone
|
|
16
|
+
from django.utils.encoding import iri_to_uri
|
|
16
17
|
from django.utils.html import format_html
|
|
17
|
-
from django.utils.http import
|
|
18
|
+
from django.utils.http import url_has_allowed_host_and_scheme
|
|
18
19
|
from django.views.generic import View
|
|
19
20
|
from django_tables2 import RequestConfig
|
|
20
21
|
from jsonschema.validators import Draft7Validator
|
|
@@ -26,10 +27,10 @@ from nautobot.core.tables import ButtonsColumn
|
|
|
26
27
|
from nautobot.core.utils.lookup import get_table_for_model
|
|
27
28
|
from nautobot.core.utils.requests import normalize_querydict
|
|
28
29
|
from nautobot.core.views import generic, viewsets
|
|
29
|
-
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
30
30
|
from nautobot.core.views.mixins import ObjectPermissionRequiredMixin
|
|
31
31
|
from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
|
|
32
32
|
from nautobot.core.views.utils import prepare_cloned_fields
|
|
33
|
+
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
33
34
|
from nautobot.dcim.models import Device, Rack
|
|
34
35
|
from nautobot.dcim.tables import DeviceTable, RackTable
|
|
35
36
|
from nautobot.extras.tasks import delete_custom_field_data
|
|
@@ -62,6 +63,7 @@ from .models import (
|
|
|
62
63
|
GitRepository,
|
|
63
64
|
GraphQLQuery,
|
|
64
65
|
ImageAttachment,
|
|
66
|
+
Job as JobModel,
|
|
65
67
|
JobButton,
|
|
66
68
|
JobHook,
|
|
67
69
|
JobResult,
|
|
@@ -79,7 +81,6 @@ from .models import (
|
|
|
79
81
|
TaggedItem,
|
|
80
82
|
Webhook,
|
|
81
83
|
)
|
|
82
|
-
from .models import Job as JobModel
|
|
83
84
|
from .registry import registry
|
|
84
85
|
from .tables import RoleTable
|
|
85
86
|
|
|
@@ -413,9 +414,9 @@ class CustomFieldEditView(generic.ObjectEditView):
|
|
|
413
414
|
verb = "Created" if object_created else "Modified"
|
|
414
415
|
msg = f"{verb} {self.queryset.model._meta.verbose_name}"
|
|
415
416
|
logger.info(f"{msg} {obj} (PK: {obj.pk})")
|
|
416
|
-
|
|
417
|
+
try:
|
|
417
418
|
msg = format_html('{} <a href="{}">{}</a>', msg, obj.get_absolute_url(), obj)
|
|
418
|
-
|
|
419
|
+
except AttributeError:
|
|
419
420
|
msg = format_html("{} {}", msg, obj)
|
|
420
421
|
messages.success(request, msg)
|
|
421
422
|
|
|
@@ -428,8 +429,8 @@ class CustomFieldEditView(generic.ObjectEditView):
|
|
|
428
429
|
return redirect(request.get_full_path())
|
|
429
430
|
|
|
430
431
|
return_url = form.cleaned_data.get("return_url")
|
|
431
|
-
if
|
|
432
|
-
return redirect(return_url)
|
|
432
|
+
if url_has_allowed_host_and_scheme(url=return_url, allowed_hosts=request.get_host()):
|
|
433
|
+
return redirect(iri_to_uri(return_url))
|
|
433
434
|
else:
|
|
434
435
|
return redirect(self.get_return_url(request, obj))
|
|
435
436
|
|
|
@@ -651,9 +652,9 @@ class DynamicGroupEditView(generic.ObjectEditView):
|
|
|
651
652
|
verb = "Created" if object_created else "Modified"
|
|
652
653
|
msg = f"{verb} {self.queryset.model._meta.verbose_name}"
|
|
653
654
|
logger.info(f"{msg} {obj} (PK: {obj.pk})")
|
|
654
|
-
|
|
655
|
+
try:
|
|
655
656
|
msg = format_html('{} <a href="{}">{}</a>', msg, obj.get_absolute_url(), obj)
|
|
656
|
-
|
|
657
|
+
except AttributeError:
|
|
657
658
|
msg = format_html("{} {}", msg, obj)
|
|
658
659
|
messages.success(request, msg)
|
|
659
660
|
|
|
@@ -666,8 +667,8 @@ class DynamicGroupEditView(generic.ObjectEditView):
|
|
|
666
667
|
return redirect(request.get_full_path())
|
|
667
668
|
|
|
668
669
|
return_url = form.cleaned_data.get("return_url")
|
|
669
|
-
if
|
|
670
|
-
return redirect(return_url)
|
|
670
|
+
if url_has_allowed_host_and_scheme(url=return_url, allowed_hosts=request.get_host()):
|
|
671
|
+
return redirect(iri_to_uri(return_url))
|
|
671
672
|
else:
|
|
672
673
|
return redirect(self.get_return_url(request, obj))
|
|
673
674
|
|
|
@@ -1152,6 +1153,12 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1152
1153
|
schedule_form = forms.JobScheduleForm(request.POST)
|
|
1153
1154
|
task_queue = request.POST.get("_task_queue")
|
|
1154
1155
|
|
|
1156
|
+
return_url = request.POST.get("_return_url")
|
|
1157
|
+
if return_url is not None and url_has_allowed_host_and_scheme(url=return_url, allowed_hosts=request.get_host()):
|
|
1158
|
+
return_url = iri_to_uri(return_url)
|
|
1159
|
+
else:
|
|
1160
|
+
return_url = None
|
|
1161
|
+
|
|
1155
1162
|
# Allow execution only if a worker process is running and the job is runnable.
|
|
1156
1163
|
if not get_worker_count(queue=task_queue):
|
|
1157
1164
|
messages.error(request, "Unable to run or schedule job: Celery worker process not running.")
|
|
@@ -1159,7 +1166,10 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1159
1166
|
messages.error(request, "Unable to run or schedule job: Job is not presently installed.")
|
|
1160
1167
|
elif not job_model.enabled:
|
|
1161
1168
|
messages.error(request, "Unable to run or schedule job: Job is not enabled to be run.")
|
|
1162
|
-
elif
|
|
1169
|
+
elif (
|
|
1170
|
+
job_model.has_sensitive_variables
|
|
1171
|
+
and request.POST.get("_schedule_type") != JobExecutionType.TYPE_IMMEDIATELY
|
|
1172
|
+
):
|
|
1163
1173
|
messages.error(request, "Unable to schedule job: Job may have sensitive input variables.")
|
|
1164
1174
|
elif job_model.has_sensitive_variables and job_model.approval_required:
|
|
1165
1175
|
messages.error(
|
|
@@ -1221,10 +1231,10 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1221
1231
|
|
|
1222
1232
|
if job_model.approval_required:
|
|
1223
1233
|
messages.success(request, f"Job {schedule_name} successfully submitted for approval")
|
|
1224
|
-
return redirect("extras:scheduledjob_approval_queue_list")
|
|
1234
|
+
return redirect(return_url if return_url else "extras:scheduledjob_approval_queue_list")
|
|
1225
1235
|
else:
|
|
1226
1236
|
messages.success(request, f"Job {schedule_name} successfully scheduled")
|
|
1227
|
-
return redirect("extras:scheduledjob_list")
|
|
1237
|
+
return redirect(return_url if return_url else "extras:scheduledjob_list")
|
|
1228
1238
|
|
|
1229
1239
|
else:
|
|
1230
1240
|
# Enqueue job for immediate execution
|
|
@@ -1237,8 +1247,21 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1237
1247
|
**job_model.job_class.serialize_data(job_kwargs),
|
|
1238
1248
|
)
|
|
1239
1249
|
|
|
1250
|
+
if return_url:
|
|
1251
|
+
messages.info(
|
|
1252
|
+
request,
|
|
1253
|
+
format_html(
|
|
1254
|
+
'Job enqueued. <a href="{}">Click here for the results.</a>',
|
|
1255
|
+
job_result.get_absolute_url(),
|
|
1256
|
+
),
|
|
1257
|
+
)
|
|
1258
|
+
return redirect(return_url)
|
|
1259
|
+
|
|
1240
1260
|
return redirect("extras:jobresult", pk=job_result.pk)
|
|
1241
1261
|
|
|
1262
|
+
if return_url:
|
|
1263
|
+
return redirect(return_url)
|
|
1264
|
+
|
|
1242
1265
|
template_name = "extras/job.html"
|
|
1243
1266
|
if job_model.job_class is not None and hasattr(job_model.job_class, "template_name"):
|
|
1244
1267
|
try:
|
|
@@ -1556,31 +1579,6 @@ class JobButtonUIViewSet(NautobotUIViewSet):
|
|
|
1556
1579
|
table_class = tables.JobButtonTable
|
|
1557
1580
|
|
|
1558
1581
|
|
|
1559
|
-
class JobButtonRunView(ObjectPermissionRequiredMixin, View):
|
|
1560
|
-
"""
|
|
1561
|
-
View to run the Job linked to the Job Button.
|
|
1562
|
-
"""
|
|
1563
|
-
|
|
1564
|
-
queryset = JobButton.objects.all()
|
|
1565
|
-
|
|
1566
|
-
def get_required_permission(self):
|
|
1567
|
-
return "extras.run_job"
|
|
1568
|
-
|
|
1569
|
-
def post(self, request, pk):
|
|
1570
|
-
post_data = request.POST
|
|
1571
|
-
job_button = JobButton.objects.get(pk=pk)
|
|
1572
|
-
job_model = job_button.job
|
|
1573
|
-
result = JobResult.enqueue_job(
|
|
1574
|
-
job_model=job_model,
|
|
1575
|
-
user=request.user,
|
|
1576
|
-
object_pk=post_data["object_pk"],
|
|
1577
|
-
object_model_name=post_data["object_model_name"],
|
|
1578
|
-
)
|
|
1579
|
-
msg = format_html('Job enqueued. <a href="{}">Click here for the results.</a>', result.get_absolute_url())
|
|
1580
|
-
messages.info(request=request, message=msg)
|
|
1581
|
-
return redirect(post_data["redirect_path"])
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
1582
|
#
|
|
1585
1583
|
# Change logging
|
|
1586
1584
|
#
|
|
@@ -2050,9 +2048,9 @@ class SecretsGroupEditView(generic.ObjectEditView):
|
|
|
2050
2048
|
verb = "Created" if object_created else "Modified"
|
|
2051
2049
|
msg = f"{verb} {self.queryset.model._meta.verbose_name}"
|
|
2052
2050
|
logger.info(f"{msg} {obj} (PK: {obj.pk})")
|
|
2053
|
-
|
|
2051
|
+
try:
|
|
2054
2052
|
msg = format_html('{} <a href="{}">{}</a>', msg, obj.get_absolute_url(), obj)
|
|
2055
|
-
|
|
2053
|
+
except AttributeError:
|
|
2056
2054
|
msg = format_html("{} {}", msg, obj)
|
|
2057
2055
|
messages.success(request, msg)
|
|
2058
2056
|
|
|
@@ -2065,8 +2063,8 @@ class SecretsGroupEditView(generic.ObjectEditView):
|
|
|
2065
2063
|
return redirect(request.get_full_path())
|
|
2066
2064
|
|
|
2067
2065
|
return_url = form.cleaned_data.get("return_url")
|
|
2068
|
-
if
|
|
2069
|
-
return redirect(return_url)
|
|
2066
|
+
if url_has_allowed_host_and_scheme(url=return_url, allowed_hosts=request.get_host()):
|
|
2067
|
+
return redirect(iri_to_uri(return_url))
|
|
2070
2068
|
else:
|
|
2071
2069
|
return redirect(self.get_return_url(request, obj))
|
|
2072
2070
|
|
nautobot/generate_secret_key.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# This script will generate a random 50-character string suitable for use as a SECRET_KEY.
|
|
3
|
-
|
|
3
|
+
# shamelessly pulled from https://docs.python.org/3/library/secrets.html#recipes-and-best-practices
|
|
4
|
+
import secrets
|
|
5
|
+
import string
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
length = 50
|
|
8
|
+
alphabet = string.ascii_letters + string.digits + "!@#$%^&*(-_=+)" # string.punctuation would be an option
|
|
9
|
+
while True:
|
|
10
|
+
password = "".join(secrets.choice(alphabet) for i in range(length))
|
|
11
|
+
if len(set(password)) >= 5:
|
|
12
|
+
break
|
|
13
|
+
print(password)
|
nautobot/ipam/api/serializers.py
CHANGED
|
@@ -11,9 +11,9 @@ from nautobot.core.api import (
|
|
|
11
11
|
ValidatedModelSerializer,
|
|
12
12
|
)
|
|
13
13
|
from nautobot.extras.api.mixins import TaggedModelSerializerMixin
|
|
14
|
+
from nautobot.ipam import constants
|
|
14
15
|
from nautobot.ipam.api.fields import IPFieldSerializer
|
|
15
16
|
from nautobot.ipam.choices import PrefixTypeChoices, ServiceProtocolChoices
|
|
16
|
-
from nautobot.ipam import constants
|
|
17
17
|
from nautobot.ipam.models import (
|
|
18
18
|
get_default_namespace,
|
|
19
19
|
IPAddress,
|
|
@@ -28,7 +28,6 @@ from nautobot.ipam.models import (
|
|
|
28
28
|
VRF,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
#
|
|
33
32
|
# Namespaces
|
|
34
33
|
#
|
nautobot/ipam/api/urls.py
CHANGED
nautobot/ipam/api/views.py
CHANGED
nautobot/ipam/apps.py
CHANGED
|
@@ -15,8 +15,9 @@ class IPAMConfig(NautobotConfig):
|
|
|
15
15
|
super().ready()
|
|
16
16
|
|
|
17
17
|
from graphene_django.converter import convert_django_field, convert_field_to_string
|
|
18
|
+
|
|
18
19
|
from nautobot.ipam.fields import VarbinaryIPField
|
|
19
|
-
import nautobot.ipam.signals # noqa: F401
|
|
20
|
+
import nautobot.ipam.signals # noqa: F401 # unused-import -- but this import installs the signals
|
|
20
21
|
|
|
21
22
|
# Register VarbinaryIPField to be converted to a string type
|
|
22
23
|
convert_django_field.register(VarbinaryIPField)(convert_field_to_string)
|
nautobot/ipam/factory.py
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import logging
|
|
3
|
+
import math
|
|
3
4
|
|
|
4
5
|
import factory
|
|
5
6
|
import faker
|
|
6
|
-
import math
|
|
7
7
|
|
|
8
8
|
from nautobot.core.factory import (
|
|
9
|
+
get_random_instances,
|
|
9
10
|
NautobotBoolIterator,
|
|
10
11
|
OrganizationalModelFactory,
|
|
11
12
|
PrimaryModelFactory,
|
|
12
|
-
UniqueFaker,
|
|
13
|
-
get_random_instances,
|
|
14
13
|
random_instance,
|
|
14
|
+
UniqueFaker,
|
|
15
15
|
)
|
|
16
16
|
from nautobot.dcim.models import Location
|
|
17
17
|
from nautobot.extras.models import Role, Status
|
|
18
18
|
from nautobot.ipam.choices import PrefixTypeChoices
|
|
19
|
-
from nautobot.ipam.models import IPAddress, Prefix, RIR, RouteTarget, VLAN, VLANGroup, VRF
|
|
19
|
+
from nautobot.ipam.models import IPAddress, Namespace, Prefix, RIR, RouteTarget, VLAN, VLANGroup, VRF
|
|
20
20
|
from nautobot.tenancy.models import Tenant
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
logger = logging.getLogger(__name__)
|
|
24
23
|
|
|
25
24
|
|
|
@@ -51,7 +50,7 @@ def random_route_distinguisher():
|
|
|
51
50
|
fake = faker.Faker()
|
|
52
51
|
branch = fake.pyint(0, 2)
|
|
53
52
|
if branch == 0:
|
|
54
|
-
# 16-bit ASNs 64496
|
|
53
|
+
# 16-bit ASNs 64496-64511 are reserved for documentation and sample code
|
|
55
54
|
return f"{fake.pyint(64496, 64511)}:{fake.pyint(0, 2**32 - 1)}"
|
|
56
55
|
if branch == 1:
|
|
57
56
|
return f"{fake.ipv4_private()}:{fake.pyint(0, 2**16 - 1)}"
|
|
@@ -201,9 +200,7 @@ class VLANFactory(PrimaryModelFactory):
|
|
|
201
200
|
),
|
|
202
201
|
)
|
|
203
202
|
]
|
|
204
|
-
)[
|
|
205
|
-
:255
|
|
206
|
-
] # truncate to max VLAN.name length just to be safe
|
|
203
|
+
)[:255] # truncate to max VLAN.name length just to be safe
|
|
207
204
|
)
|
|
208
205
|
|
|
209
206
|
status = random_instance(lambda: Status.objects.get_for_model(VLAN), allow_null=False)
|