octopize.deploy_tool 3.3.0__tar.gz → 3.5.0__tar.gz
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.
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/PKG-INFO +45 -5
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/README.md +44 -4
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/pyproject.toml +1 -1
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/__init__.py +1 -1
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/app_root.py +123 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/checks.py +15 -3
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/install_command.py +2 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/migrate_command.py +2 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_users.py +62 -5
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/update_command.py +3 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/configure_command.py +4 -3
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/application/host_paths.py +143 -0
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/application/image_registry_auth.py +201 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/ports.py +59 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/start_command.py +49 -1
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/authentik_migration.py +12 -3
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/authentik_user_types.py +23 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/__init__.py +12 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/start.py +4 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/config_resolver.py +29 -7
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/defaults.yaml +1 -1
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/exceptions.py +19 -0
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/container_identity.py +64 -0
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/container_mounts.py +56 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/docker_client.py +122 -23
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/docker_config_reader.py +60 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/document_step_runner.py +20 -25
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/noop_docker_client.py +13 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/input_gatherer.py +139 -20
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/line_editing.py +56 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/resources/config.example.yaml +11 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/base.py +13 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/email.py +9 -4
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/required.py +2 -0
- octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/templates/.env.template +3 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_api.template +0 -1
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_infra.template +1 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_lifecycle.py +32 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/.env +2 -1
- {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_apply_output → octopize_deploy_tool-3.5.0/tests/fixtures/install_render_output}/.env +2 -1
- {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_render_output → octopize_deploy_tool-3.5.0/tests/fixtures/update_interactive_diff/expected_apply_output}/.env +2 -1
- {octopize_deploy_tool-3.3.0/tests/fixtures/install_render_output → octopize_deploy_tool-3.5.0/tests/fixtures/update_interactive_diff/expected_render_output}/.env +2 -1
- octopize_deploy_tool-3.5.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +102 -0
- octopize_deploy_tool-3.5.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +102 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/fakes.py +44 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_cli_integration.py +44 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_configure_command.py +23 -28
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_install_command.py +141 -1
- octopize_deploy_tool-3.5.0/tests/unit/infra/test_container_identity.py +97 -0
- octopize_deploy_tool-3.5.0/tests/unit/infra/test_docker_config_reader.py +61 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_document_step_runner.py +40 -22
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_email.py +86 -2
- octopize_deploy_tool-3.5.0/tests/unit/steps/test_prompt_text.py +107 -0
- octopize_deploy_tool-3.5.0/tests/unit/test_app_root.py +104 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_client.py +68 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migration.py +12 -4
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_config_resolver.py +123 -1
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_create_users.py +139 -6
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_diff_command.py +9 -24
- octopize_deploy_tool-3.5.0/tests/unit/test_host_paths.py +129 -0
- octopize_deploy_tool-3.5.0/tests/unit/test_image_registry_auth.py +159 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_input_gatherer.py +97 -0
- octopize_deploy_tool-3.5.0/tests/unit/test_line_editing.py +84 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_preflight_checks.py +30 -2
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_rich_implementations.py +42 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_start_command.py +116 -1
- octopize_deploy_tool-3.3.0/src/octopize_avatar_deploy/templates/.env.template +0 -3
- octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +0 -101
- octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +0 -101
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/.gitignore +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/src/octopize_avatar_deploy/steps/user.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/generate_env_output_dir_error/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/missing_subcommand/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/_guards.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/apply_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_env.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_login.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_readiness.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/client_compatibility_report.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/subcommand_ports.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/authentik_migrate.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_task.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/provision_admin.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/reconcile_blueprint.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/registry.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/verify_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/configure_resume_policy.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/deployment_markers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/deployment_paths.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/diff_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/legacy_layout.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/operator_owned_files.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/polling.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/render_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/secret_files.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/stop_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/uninstall_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/user_config.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cert_generator.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/certificate_verifier.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/_shared.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/apply.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/configure.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/diff.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/install.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/migrate.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/render.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/stop.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/tasks.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/uninstall.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/update.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/verify.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli_dependencies.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli_test_harness.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/control_flags.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/deployment_mode.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/client_compatibility.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/configure_preset.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_item.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_item_registry.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_state.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/generation.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/placement.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/service_versions.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/validation.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/version_id.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/download_templates.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/environment.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/cert_infra.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/current_version_resolver.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/env_file_reader.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem_legacy_source.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem_user_config_scaffolder.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/httpx2_http_client.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/in_memory_state_repository.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/offline_http_client.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_defaults_source.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_template_provider.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_version_provider.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/preset_loader.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/system_clock.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/yaml_config_source.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/yaml_state_repository.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/normalizers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/output_spec.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/printer.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/public_url.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/renderer.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/resources/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/secret_factory.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/self_signed_ssl.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/authentik.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/authentik_blueprint.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/database.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/logging.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/nginx.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/service_urls.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/storage.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/telemetry.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/user.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/template_provisioning.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/.template-version +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_web.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/api.env.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/compose.override.yaml.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/docker-compose.yml.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/nginx.conf.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/python_client.env.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/web.env.template +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/tls_types.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/topology_urls.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/url_contract.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/verbosity.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/version_compat.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/TESTING.md +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/conftest.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/conftest.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_migrate_start_provision_verify.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_update_reapplies_blueprint.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/user_disable_revokes_api_key.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/apply_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/licenses.csv +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/organizations.csv +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/users.csv +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/expected/.deployment_states/v1/deployment_state.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/input.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/from/.env +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/from/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/.env +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.env +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/admin_emails +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/authjwt_secret_key +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/clevercloud_sso_salt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_password +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_user +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_name +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_password +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_user +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/file_jwt_secret_key +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/organization_name +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/pepper +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/smtp_password +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_access_key_id +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_secret_access_key +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/migrate_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/missing_subcommand/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/non_interactive_complete/config.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/non_interactive_no_telemetry/config.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/render_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/start_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/stop_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_authentik_migrate_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_create_self_signed_cert_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_create_users_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_provision_admin_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_reconcile_blueprint_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/uninstall_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/base_v1/generated_files/.env +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.needs_blueprint_reconcile +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/base_v1/generated_files/.env +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.needs_blueprint_reconcile +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/.permissions.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/favicon.ico +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/logo.png +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/translations.json +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/docker-compose.yml +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/nginx/nginx.conf +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/verify_help/output.txt +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/fixture_dir_comparison.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/normalization.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/printers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/steps.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/tls_fixtures.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_authentik_migrate_task.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_client_compatibility_output.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_create_self_signed_cert_task.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_diff_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_legacy_app_root.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_first_run.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_relative_tls_paths.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_without_tls_keys.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_update_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/test_cli_harness.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/__init__.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/conftest.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_docker_client.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_filesystem.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_filesystem_legacy_source.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_httpx2_http_client.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_preset_loader.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_yaml_config_source.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_yaml_deployment_state_repository.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_authentik.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_authentik_blueprint.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_database.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_logging.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_nginx.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_required.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_service_urls.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_storage.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_telemetry.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_user.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_apply_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_env.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_login.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_for_docker.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_parsers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_readiness.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_cert_generator.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_certificate_verifier.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_cli_verify_ssl.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_client_compatibility.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_compare_helpers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_config_resolver_consistency.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_configure_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_create_self_signed_cert_task.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_deployment_item.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_docs_command_references.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_environment.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_generation.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_generic_prompt.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_install_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_migrate_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_normalizers.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_output_spec.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_placement.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_polling.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_printer.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_provision_admin.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_public_url.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_reconcile_blueprint.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_render_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_renderer.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_secret_factory.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_secret_files.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_select_authentik_migrate_parser.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_service_versions.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_stop_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_task_registry.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_uninstall_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_update_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_user_config.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_validation.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_verify_command.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_version_id.py +0 -0
- {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_version_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: octopize.deploy_tool
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: Deployment configuration tool for Octopize Avatar platform
|
|
5
5
|
Project-URL: Homepage, https://octopize.io
|
|
6
6
|
Project-URL: Documentation, https://docs.octopize.io/docs/deploying/self-hosted/self_installation
|
|
@@ -96,9 +96,12 @@ to be up, and `provision-admin` must run before `verify`. Both hold once `start`
|
|
|
96
96
|
|
|
97
97
|
## Command reference
|
|
98
98
|
|
|
99
|
-
`--app-root` defaults to the current directory everywhere it is accepted
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
`--app-root` defaults to the current directory everywhere it is accepted, and must be a directory
|
|
100
|
+
the invoking user can read, write and enter — every command refuses a root-owned or otherwise
|
|
101
|
+
inaccessible root up front rather than failing part-way through. It does not have to exist yet, as
|
|
102
|
+
long as its parent is writable. Every command and `tasks` sub-command takes `--verbosity {1,2}`,
|
|
103
|
+
where `1` is essential (the default) and `2` is verbose. Every command's `--help` lists its full
|
|
104
|
+
option set.
|
|
102
105
|
|
|
103
106
|
### Everyday commands
|
|
104
107
|
|
|
@@ -279,7 +282,8 @@ answering "keep" for a file is still honoured and still blocks the apply.
|
|
|
279
282
|
`migrate` also creates `user_config/` under the new app root, so a migrated deployment is shaped
|
|
280
283
|
exactly like an installed one and `update --from-config` works the same way on both.
|
|
281
284
|
|
|
282
|
-
> **Before migrating non-interactively**, make sure the legacy `.env` sets
|
|
285
|
+
> **Before migrating non-interactively**, make sure the legacy `.env` sets `SMTP_HOST` (or pass
|
|
286
|
+
> `USE_AWS_SMTP_PRESET: true`), and sets
|
|
283
287
|
> `NGINX_SSL_CERTIFICATE_PATH` and `NGINX_SSL_CERTIFICATE_KEY_PATH` to paths that exist.
|
|
284
288
|
> Otherwise the run falls back to a relative built-in default and keeps it with a warning that
|
|
285
289
|
> the path is "not usable yet" — the migration completes, but nginx will not start until a
|
|
@@ -425,6 +429,9 @@ Two things the example does not tell you:
|
|
|
425
429
|
- **`ORGANIZATION_NAME` is missing from it** and is required. A `--non-interactive` run without it
|
|
426
430
|
stops at `ORGANIZATION_NAME is required but not provided in configuration file`. Add it
|
|
427
431
|
yourself, as below.
|
|
432
|
+
- **`SMTP_HOST` is required too**, unless you set `USE_AWS_SMTP_PRESET: true` to take the AWS SES
|
|
433
|
+
settings Octopize provides. The example sets it; a `--non-interactive` run with neither stops at
|
|
434
|
+
`'SMTP_HOST' is required and no value was provided`.
|
|
428
435
|
- **The TLS keys the tool reads are `NGINX_SSL_CERTIFICATE_PATH` and
|
|
429
436
|
`NGINX_SSL_CERTIFICATE_KEY_PATH`.** Use those spellings.
|
|
430
437
|
|
|
@@ -515,14 +522,31 @@ docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/
|
|
|
515
522
|
|
|
516
523
|
### Start
|
|
517
524
|
|
|
525
|
+
`start` pulls the images the deployment needs, and two of them are private. The
|
|
526
|
+
credentials `docker login` writes belong to the Docker _client_, so the login you did on
|
|
527
|
+
the host is invisible to the client in this container: the extra `DOCKER_CONFIG` mount
|
|
528
|
+
below is what gives them to it.
|
|
529
|
+
|
|
518
530
|
```bash
|
|
519
531
|
export CP=$(docker info -f '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
|
|
520
532
|
docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/docker.sock)" \
|
|
521
533
|
-v "$(pwd)/avatar:/app-root" -v /var/run/docker.sock:/var/run/docker.sock \
|
|
522
534
|
-v "$(which docker):/usr/local/bin/docker:ro" -v "$CP:$CP:ro" \
|
|
535
|
+
-e DOCKER_CONFIG=/docker-config -v "$HOME/.docker:/docker-config:ro" \
|
|
523
536
|
quay.io/octopize/deploy-tool:latest start --app-root /app-root
|
|
524
537
|
```
|
|
525
538
|
|
|
539
|
+
If the host keeps its registry credentials in a credential helper — a `credsStore` entry
|
|
540
|
+
in `~/.docker/config.json` — that mount carries no usable credential, because the helper
|
|
541
|
+
is a program the container does not have. Write a configuration that holds the token
|
|
542
|
+
itself, and mount that one instead:
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
mkdir -p ~/avatar-registry-login
|
|
546
|
+
DOCKER_CONFIG=~/avatar-registry-login docker login quay.io
|
|
547
|
+
# ... -e DOCKER_CONFIG=/docker-config -v "$HOME/avatar-registry-login:/docker-config:ro"
|
|
548
|
+
```
|
|
549
|
+
|
|
526
550
|
### Stop
|
|
527
551
|
|
|
528
552
|
```bash
|
|
@@ -583,6 +607,11 @@ Notes:
|
|
|
583
607
|
by Docker Compose on the _host_, so give the host path even though you are typing it inside a
|
|
584
608
|
container. The tool detects that it is running in a container, skips the existence check for
|
|
585
609
|
those paths and prints a notice saying so.
|
|
610
|
+
- **The app root has to come from a mount.** The deployment files are read by the Docker daemon
|
|
611
|
+
on the host, and the tool works out their host path from the container's own mounts, so
|
|
612
|
+
`-v "$(pwd)/avatar:/app-root"` needs no path to match. A directory that belongs to the
|
|
613
|
+
container itself (`/tmp/avatar`, say) is reachable by nothing but the tool, and `start`
|
|
614
|
+
refuses it rather than bring up a stack that cannot read its own secrets.
|
|
586
615
|
- **Anything outside the app root needs its own mount**: `-v "$(pwd)/config:/input:ro"` with
|
|
587
616
|
`--from-config /input/config.yaml`, or `-v "$(pwd)/avatar-old:/legacy:ro"` with
|
|
588
617
|
`--from-legacy /legacy` for `migrate`. Always pass the container-side path.
|
|
@@ -647,6 +676,17 @@ under `generated_files/`. Merge them into `.deployment_states/<vX>/generated/` a
|
|
|
647
676
|
|
|
648
677
|
**`verify` reports "API key not found".** Run `tasks provision-admin` first.
|
|
649
678
|
|
|
679
|
+
**An `install` was interrupted with Ctrl+C.** Run `install` again: it reports the incomplete
|
|
680
|
+
configuration and asks `Resume the in-progress configuration (vN)?` Answering `y` continues
|
|
681
|
+
where it stopped, keeping the answers already given; answering `n` starts the questionnaire
|
|
682
|
+
again in a new version slot and leaves the interrupted one on disk. A `--non-interactive` run
|
|
683
|
+
cannot answer, so it stops instead.
|
|
684
|
+
|
|
685
|
+
**`start` reports that an image registry refused the credentials.** The credentials
|
|
686
|
+
`docker login` writes belong to the Docker client, so a `start` run from the deploy-tool
|
|
687
|
+
container does not have the ones you created on the host. The message names the mount to add —
|
|
688
|
+
see [Running via Docker](#running-via-docker).
|
|
689
|
+
|
|
650
690
|
**Something needs a closer look.** Add `--verbosity 2` for detailed progress and template output.
|
|
651
691
|
|
|
652
692
|
**Starting over.** `uninstall` is the supported teardown: it is confirmation-gated and removes
|
|
@@ -63,9 +63,12 @@ to be up, and `provision-admin` must run before `verify`. Both hold once `start`
|
|
|
63
63
|
|
|
64
64
|
## Command reference
|
|
65
65
|
|
|
66
|
-
`--app-root` defaults to the current directory everywhere it is accepted
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
`--app-root` defaults to the current directory everywhere it is accepted, and must be a directory
|
|
67
|
+
the invoking user can read, write and enter — every command refuses a root-owned or otherwise
|
|
68
|
+
inaccessible root up front rather than failing part-way through. It does not have to exist yet, as
|
|
69
|
+
long as its parent is writable. Every command and `tasks` sub-command takes `--verbosity {1,2}`,
|
|
70
|
+
where `1` is essential (the default) and `2` is verbose. Every command's `--help` lists its full
|
|
71
|
+
option set.
|
|
69
72
|
|
|
70
73
|
### Everyday commands
|
|
71
74
|
|
|
@@ -246,7 +249,8 @@ answering "keep" for a file is still honoured and still blocks the apply.
|
|
|
246
249
|
`migrate` also creates `user_config/` under the new app root, so a migrated deployment is shaped
|
|
247
250
|
exactly like an installed one and `update --from-config` works the same way on both.
|
|
248
251
|
|
|
249
|
-
> **Before migrating non-interactively**, make sure the legacy `.env` sets
|
|
252
|
+
> **Before migrating non-interactively**, make sure the legacy `.env` sets `SMTP_HOST` (or pass
|
|
253
|
+
> `USE_AWS_SMTP_PRESET: true`), and sets
|
|
250
254
|
> `NGINX_SSL_CERTIFICATE_PATH` and `NGINX_SSL_CERTIFICATE_KEY_PATH` to paths that exist.
|
|
251
255
|
> Otherwise the run falls back to a relative built-in default and keeps it with a warning that
|
|
252
256
|
> the path is "not usable yet" — the migration completes, but nginx will not start until a
|
|
@@ -392,6 +396,9 @@ Two things the example does not tell you:
|
|
|
392
396
|
- **`ORGANIZATION_NAME` is missing from it** and is required. A `--non-interactive` run without it
|
|
393
397
|
stops at `ORGANIZATION_NAME is required but not provided in configuration file`. Add it
|
|
394
398
|
yourself, as below.
|
|
399
|
+
- **`SMTP_HOST` is required too**, unless you set `USE_AWS_SMTP_PRESET: true` to take the AWS SES
|
|
400
|
+
settings Octopize provides. The example sets it; a `--non-interactive` run with neither stops at
|
|
401
|
+
`'SMTP_HOST' is required and no value was provided`.
|
|
395
402
|
- **The TLS keys the tool reads are `NGINX_SSL_CERTIFICATE_PATH` and
|
|
396
403
|
`NGINX_SSL_CERTIFICATE_KEY_PATH`.** Use those spellings.
|
|
397
404
|
|
|
@@ -482,14 +489,31 @@ docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/
|
|
|
482
489
|
|
|
483
490
|
### Start
|
|
484
491
|
|
|
492
|
+
`start` pulls the images the deployment needs, and two of them are private. The
|
|
493
|
+
credentials `docker login` writes belong to the Docker _client_, so the login you did on
|
|
494
|
+
the host is invisible to the client in this container: the extra `DOCKER_CONFIG` mount
|
|
495
|
+
below is what gives them to it.
|
|
496
|
+
|
|
485
497
|
```bash
|
|
486
498
|
export CP=$(docker info -f '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
|
|
487
499
|
docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/docker.sock)" \
|
|
488
500
|
-v "$(pwd)/avatar:/app-root" -v /var/run/docker.sock:/var/run/docker.sock \
|
|
489
501
|
-v "$(which docker):/usr/local/bin/docker:ro" -v "$CP:$CP:ro" \
|
|
502
|
+
-e DOCKER_CONFIG=/docker-config -v "$HOME/.docker:/docker-config:ro" \
|
|
490
503
|
quay.io/octopize/deploy-tool:latest start --app-root /app-root
|
|
491
504
|
```
|
|
492
505
|
|
|
506
|
+
If the host keeps its registry credentials in a credential helper — a `credsStore` entry
|
|
507
|
+
in `~/.docker/config.json` — that mount carries no usable credential, because the helper
|
|
508
|
+
is a program the container does not have. Write a configuration that holds the token
|
|
509
|
+
itself, and mount that one instead:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
mkdir -p ~/avatar-registry-login
|
|
513
|
+
DOCKER_CONFIG=~/avatar-registry-login docker login quay.io
|
|
514
|
+
# ... -e DOCKER_CONFIG=/docker-config -v "$HOME/avatar-registry-login:/docker-config:ro"
|
|
515
|
+
```
|
|
516
|
+
|
|
493
517
|
### Stop
|
|
494
518
|
|
|
495
519
|
```bash
|
|
@@ -550,6 +574,11 @@ Notes:
|
|
|
550
574
|
by Docker Compose on the _host_, so give the host path even though you are typing it inside a
|
|
551
575
|
container. The tool detects that it is running in a container, skips the existence check for
|
|
552
576
|
those paths and prints a notice saying so.
|
|
577
|
+
- **The app root has to come from a mount.** The deployment files are read by the Docker daemon
|
|
578
|
+
on the host, and the tool works out their host path from the container's own mounts, so
|
|
579
|
+
`-v "$(pwd)/avatar:/app-root"` needs no path to match. A directory that belongs to the
|
|
580
|
+
container itself (`/tmp/avatar`, say) is reachable by nothing but the tool, and `start`
|
|
581
|
+
refuses it rather than bring up a stack that cannot read its own secrets.
|
|
553
582
|
- **Anything outside the app root needs its own mount**: `-v "$(pwd)/config:/input:ro"` with
|
|
554
583
|
`--from-config /input/config.yaml`, or `-v "$(pwd)/avatar-old:/legacy:ro"` with
|
|
555
584
|
`--from-legacy /legacy` for `migrate`. Always pass the container-side path.
|
|
@@ -614,6 +643,17 @@ under `generated_files/`. Merge them into `.deployment_states/<vX>/generated/` a
|
|
|
614
643
|
|
|
615
644
|
**`verify` reports "API key not found".** Run `tasks provision-admin` first.
|
|
616
645
|
|
|
646
|
+
**An `install` was interrupted with Ctrl+C.** Run `install` again: it reports the incomplete
|
|
647
|
+
configuration and asks `Resume the in-progress configuration (vN)?` Answering `y` continues
|
|
648
|
+
where it stopped, keeping the answers already given; answering `n` starts the questionnaire
|
|
649
|
+
again in a new version slot and leaves the interrupted one on disk. A `--non-interactive` run
|
|
650
|
+
cannot answer, so it stops instead.
|
|
651
|
+
|
|
652
|
+
**`start` reports that an image registry refused the credentials.** The credentials
|
|
653
|
+
`docker login` writes belong to the Docker client, so a `start` run from the deploy-tool
|
|
654
|
+
container does not have the ones you created on the host. The message names the mount to add —
|
|
655
|
+
see [Running via Docker](#running-via-docker).
|
|
656
|
+
|
|
617
657
|
**Something needs a closer look.** Add `--verbosity 2` for detailed progress and template output.
|
|
618
658
|
|
|
619
659
|
**Starting over.** `uninstall` is the supported teardown: it is confirmation-gated and removes
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""Validation of the deployment root supplied on the command line.
|
|
2
|
+
|
|
3
|
+
Every command reads and writes under ``--app-root``: the versioned state
|
|
4
|
+
documents, the rendered versions, ``generated_files/``, the secrets. A path the
|
|
5
|
+
invoking user cannot enter, read or write is a dead end, and the failure
|
|
6
|
+
otherwise surfaces deep inside a command as a bare ``PermissionError`` on some
|
|
7
|
+
individual file — after secrets have already been generated. Checking it at the
|
|
8
|
+
CLI boundary turns that into one actionable message before any work starts.
|
|
9
|
+
|
|
10
|
+
Write access is only demanded of the commands that write: a deployment root left
|
|
11
|
+
read-only can still be stopped, diffed and verified.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import getpass
|
|
17
|
+
import os
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from octopize_avatar_deploy.application._guards import CommandError
|
|
21
|
+
|
|
22
|
+
_EXAMPLE_ROOT = "./app/avatar"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AppRootError(CommandError):
|
|
26
|
+
"""Raised when the deployment root cannot be used by the current user."""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_app_root(app_root: Path, *, require_write: bool = True) -> Path:
|
|
30
|
+
"""Return *app_root* with ``~`` expanded, once it is usable by this user.
|
|
31
|
+
|
|
32
|
+
A root that does not exist yet is fine — commands create it — provided the
|
|
33
|
+
nearest existing ancestor is a directory this user can write into.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
app_root: The path the operator passed to ``--app-root``.
|
|
37
|
+
require_write: Whether this command writes under the root.
|
|
38
|
+
|
|
39
|
+
Raises:
|
|
40
|
+
AppRootError: If the path (or the directory it would be created in) is
|
|
41
|
+
not a directory, or lacks the access this command needs.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
expanded = app_root.expanduser()
|
|
45
|
+
|
|
46
|
+
if expanded.is_symlink() and not expanded.exists():
|
|
47
|
+
raise AppRootError(
|
|
48
|
+
f"{expanded} is a broken symlink. Point --app-root at a real directory, "
|
|
49
|
+
f"e.g. {_EXAMPLE_ROOT}."
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
target = expanded
|
|
53
|
+
while not target.exists():
|
|
54
|
+
parent = target.parent
|
|
55
|
+
if parent == target:
|
|
56
|
+
break
|
|
57
|
+
target = parent
|
|
58
|
+
|
|
59
|
+
if not target.is_dir():
|
|
60
|
+
raise AppRootError(
|
|
61
|
+
f"{target} is not a directory. Point --app-root at a directory you own, "
|
|
62
|
+
f"e.g. {_EXAMPLE_ROOT}."
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
missing = [
|
|
66
|
+
label for mode, label in _required_access(require_write) if not os.access(target, mode)
|
|
67
|
+
]
|
|
68
|
+
if not missing:
|
|
69
|
+
return expanded
|
|
70
|
+
|
|
71
|
+
user = _current_user()
|
|
72
|
+
owner = _owner(target)
|
|
73
|
+
subject = (
|
|
74
|
+
f"Deployment root {expanded}"
|
|
75
|
+
if target == expanded
|
|
76
|
+
else f"{expanded} cannot be created: {target}"
|
|
77
|
+
)
|
|
78
|
+
raise AppRootError(
|
|
79
|
+
f"{subject} is not {_join(missing)} by user {user!r} (owner: {owner!r}).\n"
|
|
80
|
+
f"Point --app-root at a directory your user owns, e.g. {_EXAMPLE_ROOT}, or fix "
|
|
81
|
+
f"this one:\n {_remedy(target, expanded, user, owner)}"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _required_access(require_write: bool) -> list[tuple[int, str]]:
|
|
86
|
+
"""The access modes the command needs, each paired with how to name it."""
|
|
87
|
+
if require_write:
|
|
88
|
+
return [(os.R_OK, "readable"), (os.W_OK, "writable"), (os.X_OK, "traversable")]
|
|
89
|
+
return [(os.R_OK, "readable"), (os.X_OK, "traversable")]
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _remedy(target: Path, expanded: Path, user: str, owner: str) -> str:
|
|
93
|
+
"""The one command that gets this user the access they are missing."""
|
|
94
|
+
if owner == user:
|
|
95
|
+
# Already theirs, so the mode bits are what stand in the way.
|
|
96
|
+
return f"chmod u+rwx {target}"
|
|
97
|
+
if target == expanded:
|
|
98
|
+
return f"sudo chown -R {user} {target}"
|
|
99
|
+
return f"sudo install -d -o {user} {expanded}"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _join(labels: list[str]) -> str:
|
|
103
|
+
if len(labels) == 1:
|
|
104
|
+
return labels[0]
|
|
105
|
+
return f"{', '.join(labels[:-1])} or {labels[-1]}"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _current_user() -> str:
|
|
109
|
+
try:
|
|
110
|
+
return getpass.getuser()
|
|
111
|
+
except OSError:
|
|
112
|
+
return f"uid {os.getuid()}"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _owner(path: Path) -> str:
|
|
116
|
+
try:
|
|
117
|
+
return path.owner()
|
|
118
|
+
except (KeyError, NotImplementedError, OSError):
|
|
119
|
+
pass
|
|
120
|
+
try:
|
|
121
|
+
return f"uid {path.stat().st_uid}"
|
|
122
|
+
except OSError:
|
|
123
|
+
return "unknown"
|
|
@@ -306,7 +306,9 @@ class DeploymentStateCheck:
|
|
|
306
306
|
Handles three cases:
|
|
307
307
|
|
|
308
308
|
- **No state** — nothing to do, continue silently.
|
|
309
|
-
- **In-progress** — in interactive mode, offer to resume;
|
|
309
|
+
- **In-progress** — in interactive mode, offer to resume; a declined resume
|
|
310
|
+
continues into a new version slot, because ``install`` is the fresh-install
|
|
311
|
+
command and has no flag that could ask for one. In non-interactive mode,
|
|
310
312
|
fail by default.
|
|
311
313
|
- **Completed** — in interactive mode, warn and ask for confirmation;
|
|
312
314
|
in non-interactive mode, fail by default (destructive fresh install requires
|
|
@@ -371,11 +373,21 @@ class DeploymentStateCheck:
|
|
|
371
373
|
f"Resume the in-progress configuration ({version_label})?",
|
|
372
374
|
default=True,
|
|
373
375
|
key="preflight.deployment_state_check.resume",
|
|
376
|
+
help_text=(
|
|
377
|
+
"Yes continues the interrupted questionnaire: the steps it already "
|
|
378
|
+
f"completed are kept and only the remaining ones are asked.\n"
|
|
379
|
+
"No starts the questionnaire again from the first question, in a new "
|
|
380
|
+
f"version slot. {version_label} stays on disk and is not deployed."
|
|
381
|
+
),
|
|
374
382
|
)
|
|
375
383
|
if resume:
|
|
376
384
|
return DeploymentStateCheckResult(state="in_progress", aborted=False, resume=True)
|
|
377
|
-
|
|
378
|
-
|
|
385
|
+
|
|
386
|
+
self._printer.print(
|
|
387
|
+
f"Starting a fresh configuration in a new version slot. "
|
|
388
|
+
f"The interrupted {version_label} is kept and is not deployed."
|
|
389
|
+
)
|
|
390
|
+
return DeploymentStateCheckResult(state="in_progress", aborted=False, resume=False)
|
|
379
391
|
|
|
380
392
|
def _handle_completed(self) -> DeploymentStateCheckResult:
|
|
381
393
|
self._printer.print_warning(
|
|
@@ -247,8 +247,8 @@ class InstallCommand:
|
|
|
247
247
|
|
|
248
248
|
self._printer.print_success(
|
|
249
249
|
f"Install complete. Version {version_label!r} is now deployed to "
|
|
250
|
-
f"{apply_result.output_dir}
|
|
251
|
-
"
|
|
250
|
+
f"{apply_result.output_dir}.\n"
|
|
251
|
+
f"Bring up the stack by running 'start' with --app-root {args.app_root}"
|
|
252
252
|
)
|
|
253
253
|
|
|
254
254
|
# 7. Name the python clients that work with this API version, so the
|
|
@@ -378,8 +378,8 @@ class MigrateCommand:
|
|
|
378
378
|
|
|
379
379
|
self._printer.print_success(
|
|
380
380
|
f"Migration complete. Version {version_label!r} is now deployed to "
|
|
381
|
-
f"{apply_result.output_dir}
|
|
382
|
-
"
|
|
381
|
+
f"{apply_result.output_dir}.\n"
|
|
382
|
+
f"Bring up the stack by running 'start' with --app-root {args.app_root}"
|
|
383
383
|
)
|
|
384
384
|
|
|
385
385
|
# 6. Name the python clients that work with this API version. A legacy
|
|
@@ -21,6 +21,11 @@ from octopize_avatar_deploy.application.authentik_env import (
|
|
|
21
21
|
)
|
|
22
22
|
from octopize_avatar_deploy.application.deployment_paths import DeploymentPaths
|
|
23
23
|
from octopize_avatar_deploy.application.ports import EnvReader, HttpClient
|
|
24
|
+
from octopize_avatar_deploy.authentik_user_types import (
|
|
25
|
+
EXTERNAL_USER_TYPE,
|
|
26
|
+
INTERNAL_USER_TYPE,
|
|
27
|
+
AuthentikUserType,
|
|
28
|
+
)
|
|
24
29
|
from octopize_avatar_deploy.cli_dependencies import CliDependencies
|
|
25
30
|
from octopize_avatar_deploy.domain.validation import ValidationError as _ValidationError
|
|
26
31
|
from octopize_avatar_deploy.domain.validation import validate_email
|
|
@@ -71,6 +76,7 @@ class AuthentikUser:
|
|
|
71
76
|
email: str
|
|
72
77
|
name: str
|
|
73
78
|
is_active: bool
|
|
79
|
+
user_type: str
|
|
74
80
|
|
|
75
81
|
|
|
76
82
|
@dataclass(frozen=True)
|
|
@@ -101,6 +107,13 @@ class UserSpec:
|
|
|
101
107
|
email: str
|
|
102
108
|
group: str # Authentik group name
|
|
103
109
|
|
|
110
|
+
@property
|
|
111
|
+
def user_type(self) -> AuthentikUserType:
|
|
112
|
+
"""The Authentik user type this user needs to exercise its group's rights."""
|
|
113
|
+
if self.group == ADMIN_GROUP_NAME:
|
|
114
|
+
return INTERNAL_USER_TYPE
|
|
115
|
+
return EXTERNAL_USER_TYPE
|
|
116
|
+
|
|
104
117
|
|
|
105
118
|
@dataclass
|
|
106
119
|
class ProvisionResult:
|
|
@@ -170,7 +183,8 @@ class CreateUsersClient(Protocol):
|
|
|
170
183
|
"""Authentik operations needed by :class:`UserProvisioner`."""
|
|
171
184
|
|
|
172
185
|
def get_user_by_email(self, email: str) -> AuthentikUser | None: ...
|
|
173
|
-
def create_user(self, *, email: str) -> AuthentikUser: ...
|
|
186
|
+
def create_user(self, *, email: str, user_type: AuthentikUserType) -> AuthentikUser: ...
|
|
187
|
+
def set_user_type(self, *, user_pk: int, user_type: AuthentikUserType) -> None: ...
|
|
174
188
|
def get_group_by_name(self, name: str) -> AuthentikGroup | None: ...
|
|
175
189
|
def add_user_to_group(self, *, user_pk: int, group_pk: str) -> None: ...
|
|
176
190
|
def get_email_stage_by_name(self, name: str) -> AuthentikEmailStage | None: ...
|
|
@@ -218,6 +232,15 @@ class AuthentikHttpClient:
|
|
|
218
232
|
return None
|
|
219
233
|
return resp.body if isinstance(resp.body, dict) else {}
|
|
220
234
|
|
|
235
|
+
def _patch(self, path: str, body: dict[str, Any]) -> None:
|
|
236
|
+
url = self._api_url(path)
|
|
237
|
+
try:
|
|
238
|
+
resp = self._http.patch_json(url, body, headers=self._headers)
|
|
239
|
+
except HttpConnectionError as exc:
|
|
240
|
+
raise AuthentikConnectionError(url, exc) from exc
|
|
241
|
+
if resp.status_code >= 400:
|
|
242
|
+
raise AuthentikAPIError(resp.status_code, str(resp.body), url)
|
|
243
|
+
|
|
221
244
|
def get_user_by_email(self, email: str) -> AuthentikUser | None:
|
|
222
245
|
resp = self._get("/core/users/", params={"search": email})
|
|
223
246
|
for user_data in resp.get("results", []):
|
|
@@ -225,7 +248,7 @@ class AuthentikHttpClient:
|
|
|
225
248
|
return self._parse_user(user_data)
|
|
226
249
|
return None
|
|
227
250
|
|
|
228
|
-
def create_user(self, *, email: str) -> AuthentikUser:
|
|
251
|
+
def create_user(self, *, email: str, user_type: AuthentikUserType) -> AuthentikUser:
|
|
229
252
|
display_name = email.split("@", maxsplit=1)[0]
|
|
230
253
|
body: dict[str, Any] = {
|
|
231
254
|
"username": email,
|
|
@@ -233,6 +256,7 @@ class AuthentikHttpClient:
|
|
|
233
256
|
"name": display_name,
|
|
234
257
|
"path": "users",
|
|
235
258
|
"is_active": True,
|
|
259
|
+
"type": user_type,
|
|
236
260
|
}
|
|
237
261
|
resp = self._post("/core/users/", body)
|
|
238
262
|
if resp is None:
|
|
@@ -241,6 +265,9 @@ class AuthentikHttpClient:
|
|
|
241
265
|
)
|
|
242
266
|
return self._parse_user(resp)
|
|
243
267
|
|
|
268
|
+
def set_user_type(self, *, user_pk: int, user_type: AuthentikUserType) -> None:
|
|
269
|
+
self._patch(f"/core/users/{user_pk}/", {"type": user_type})
|
|
270
|
+
|
|
244
271
|
def get_group_by_name(self, name: str) -> AuthentikGroup | None:
|
|
245
272
|
resp = self._get("/core/groups/", params={"name": name})
|
|
246
273
|
for group_data in resp.get("results", []):
|
|
@@ -272,6 +299,7 @@ class AuthentikHttpClient:
|
|
|
272
299
|
email=data.get("email", ""),
|
|
273
300
|
name=data.get("name", ""),
|
|
274
301
|
is_active=data.get("is_active", True),
|
|
302
|
+
user_type=str(data.get("type", "")),
|
|
275
303
|
)
|
|
276
304
|
|
|
277
305
|
|
|
@@ -340,11 +368,10 @@ class UserProvisioner:
|
|
|
340
368
|
def _provision_one(self, spec: UserSpec, *, send_email: bool) -> ProvisionResult:
|
|
341
369
|
existing = self._client.get_user_by_email(spec.email)
|
|
342
370
|
if existing is not None:
|
|
343
|
-
self.
|
|
344
|
-
return ProvisionResult(email=spec.email, status="exists")
|
|
371
|
+
return self._reconcile_existing(existing, spec)
|
|
345
372
|
|
|
346
373
|
try:
|
|
347
|
-
user = self._client.create_user(email=spec.email)
|
|
374
|
+
user = self._client.create_user(email=spec.email, user_type=spec.user_type)
|
|
348
375
|
except AuthentikAPIError as exc:
|
|
349
376
|
self._printer.print_error(f" {spec.email} — failed to create: {exc.detail}")
|
|
350
377
|
return ProvisionResult(email=spec.email, status="error", detail=exc.detail)
|
|
@@ -386,6 +413,36 @@ class UserProvisioner:
|
|
|
386
413
|
|
|
387
414
|
return ProvisionResult(email=spec.email, status="created")
|
|
388
415
|
|
|
416
|
+
def _reconcile_existing(self, user: AuthentikUser, spec: UserSpec) -> ProvisionResult:
|
|
417
|
+
"""Leave an existing user alone, except to widen an admin to an internal account.
|
|
418
|
+
|
|
419
|
+
A user is never narrowed back to ``external``: the extra rights an internal
|
|
420
|
+
account carries may have been granted deliberately outside this tool.
|
|
421
|
+
"""
|
|
422
|
+
if not (spec.user_type == INTERNAL_USER_TYPE and user.user_type == EXTERNAL_USER_TYPE):
|
|
423
|
+
self._printer.print(f" {spec.email} — already exists, skipping")
|
|
424
|
+
return ProvisionResult(email=spec.email, status="exists")
|
|
425
|
+
|
|
426
|
+
try:
|
|
427
|
+
self._client.set_user_type(user_pk=user.pk, user_type=INTERNAL_USER_TYPE)
|
|
428
|
+
except AuthentikAPIError as exc:
|
|
429
|
+
self._printer.print_error(
|
|
430
|
+
f" {spec.email} — already exists, but failed to convert to an "
|
|
431
|
+
f"internal user: {exc.detail}"
|
|
432
|
+
)
|
|
433
|
+
return ProvisionResult(
|
|
434
|
+
email=spec.email,
|
|
435
|
+
status="error",
|
|
436
|
+
detail=f"Conversion to internal user failed: {exc.detail}",
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
self._printer.print_success(
|
|
440
|
+
f" {spec.email} — already exists, converted to an internal user"
|
|
441
|
+
)
|
|
442
|
+
return ProvisionResult(
|
|
443
|
+
email=spec.email, status="exists", detail="Converted to an internal user"
|
|
444
|
+
)
|
|
445
|
+
|
|
389
446
|
|
|
390
447
|
# ---------------------------------------------------------------------------
|
|
391
448
|
# Command
|
|
@@ -369,8 +369,9 @@ class UpdateCommand:
|
|
|
369
369
|
|
|
370
370
|
self._printer.print_success(
|
|
371
371
|
f"Update complete. Version {version_label!r} is now deployed to "
|
|
372
|
-
f"{apply_result.output_dir}
|
|
373
|
-
"
|
|
372
|
+
f"{apply_result.output_dir}.\n"
|
|
373
|
+
"Bring up the stack and re-apply the Authentik blueprint by running "
|
|
374
|
+
f"'start' with --app-root {args.app_root}"
|
|
374
375
|
)
|
|
375
376
|
|
|
376
377
|
# 7. Last thing on screen: which python clients still work. The API
|
|
@@ -195,8 +195,9 @@ class ConfigureCommand:
|
|
|
195
195
|
base_state = DeploymentStateDocument.new(metadata).with_items(preset.items)
|
|
196
196
|
|
|
197
197
|
# 4. Run the configuration pipeline.
|
|
198
|
-
#
|
|
199
|
-
#
|
|
198
|
+
# Only an interactive run is checkpointed: a non-interactive one is
|
|
199
|
+
# re-runnable from its own inputs, and a partial document it left behind
|
|
200
|
+
# would make the next install ask about a session nobody can answer for.
|
|
200
201
|
def _checkpoint(partial: DeploymentStateDocument) -> None:
|
|
201
202
|
self._repository.save(args.app_root, target.version, partial)
|
|
202
203
|
|
|
@@ -204,7 +205,7 @@ class ConfigureCommand:
|
|
|
204
205
|
app_root=args.app_root,
|
|
205
206
|
base_state=base_state,
|
|
206
207
|
interactive=args.interactive,
|
|
207
|
-
on_checkpoint=_checkpoint,
|
|
208
|
+
on_checkpoint=_checkpoint if args.interactive else None,
|
|
208
209
|
)
|
|
209
210
|
|
|
210
211
|
# 5. Persist.
|