octopize.deploy_tool 3.3.0__tar.gz → 3.4.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.
Files changed (402) hide show
  1. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/PKG-INFO +12 -5
  2. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/README.md +11 -4
  3. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/pyproject.toml +1 -1
  4. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/__init__.py +1 -1
  5. octopize_deploy_tool-3.4.0/src/octopize_avatar_deploy/app_root.py +123 -0
  6. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/install_command.py +2 -2
  7. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/migrate_command.py +2 -2
  8. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/create_users.py +62 -5
  9. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/update_command.py +3 -2
  10. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/authentik_migration.py +12 -3
  11. octopize_deploy_tool-3.4.0/src/octopize_avatar_deploy/authentik_user_types.py +23 -0
  12. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/__init__.py +9 -0
  13. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/config_resolver.py +29 -7
  14. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/defaults.yaml +1 -1
  15. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/input_gatherer.py +114 -10
  16. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/resources/config.example.yaml +11 -2
  17. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/base.py +13 -2
  18. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/email.py +9 -4
  19. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/required.py +2 -0
  20. octopize_deploy_tool-3.4.0/src/octopize_avatar_deploy/templates/.env.template +3 -0
  21. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/_env_fragment_api.template +0 -1
  22. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/_env_fragment_infra.template +1 -0
  23. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/test_lifecycle.py +32 -0
  24. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/.env +2 -1
  25. {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_apply_output → octopize_deploy_tool-3.4.0/tests/fixtures/install_render_output}/.env +2 -1
  26. {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_render_output → octopize_deploy_tool-3.4.0/tests/fixtures/update_interactive_diff/expected_apply_output}/.env +2 -1
  27. {octopize_deploy_tool-3.3.0/tests/fixtures/install_render_output → octopize_deploy_tool-3.4.0/tests/fixtures/update_interactive_diff/expected_render_output}/.env +2 -1
  28. octopize_deploy_tool-3.4.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +102 -0
  29. octopize_deploy_tool-3.4.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +102 -0
  30. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_cli_integration.py +44 -0
  31. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_document_step_runner.py +7 -0
  32. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_email.py +86 -2
  33. octopize_deploy_tool-3.4.0/tests/unit/steps/test_prompt_text.py +107 -0
  34. octopize_deploy_tool-3.4.0/tests/unit/test_app_root.py +104 -0
  35. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_client.py +68 -0
  36. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_migration.py +12 -4
  37. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_config_resolver.py +123 -1
  38. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_create_users.py +139 -6
  39. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_diff_command.py +9 -24
  40. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_input_gatherer.py +97 -0
  41. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_rich_implementations.py +42 -0
  42. octopize_deploy_tool-3.3.0/src/octopize_avatar_deploy/templates/.env.template +0 -3
  43. octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +0 -101
  44. octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +0 -101
  45. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/.gitignore +0 -0
  46. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/infra/deployment/deployment-tool/src/octopize_avatar_deploy/steps/user.py +0 -0
  47. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/infra/deployment/deployment-tool/tests/fixtures/generate_env_output_dir_error/output.txt +0 -0
  48. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/infra/deployment/deployment-tool/tests/fixtures/help/output.txt +0 -0
  49. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/infra/deployment/deployment-tool/tests/fixtures/missing_subcommand/output.txt +0 -0
  50. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/__init__.py +0 -0
  51. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/_guards.py +0 -0
  52. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/apply_command.py +0 -0
  53. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/authentik_env.py +0 -0
  54. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/authentik_login.py +0 -0
  55. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/authentik_readiness.py +0 -0
  56. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/checks.py +0 -0
  57. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/client_compatibility_report.py +0 -0
  58. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/subcommand_ports.py +0 -0
  59. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/__init__.py +0 -0
  60. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/authentik_migrate.py +0 -0
  61. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_command.py +0 -0
  62. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_task.py +0 -0
  63. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/provision_admin.py +0 -0
  64. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/reconcile_blueprint.py +0 -0
  65. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/tasks/registry.py +0 -0
  66. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/commands/verify_command.py +0 -0
  67. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/configure_command.py +0 -0
  68. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/configure_resume_policy.py +0 -0
  69. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/deployment_markers.py +0 -0
  70. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/deployment_paths.py +0 -0
  71. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/diff_command.py +0 -0
  72. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/legacy_layout.py +0 -0
  73. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/operator_owned_files.py +0 -0
  74. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/polling.py +0 -0
  75. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/ports.py +0 -0
  76. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/render_command.py +0 -0
  77. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/secret_files.py +0 -0
  78. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/start_command.py +0 -0
  79. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/stop_command.py +0 -0
  80. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/uninstall_command.py +0 -0
  81. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/application/user_config.py +0 -0
  82. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cert_generator.py +0 -0
  83. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/certificate_verifier.py +0 -0
  84. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/_shared.py +0 -0
  85. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/__init__.py +0 -0
  86. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/apply.py +0 -0
  87. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/configure.py +0 -0
  88. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/diff.py +0 -0
  89. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/install.py +0 -0
  90. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/migrate.py +0 -0
  91. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/render.py +0 -0
  92. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/start.py +0 -0
  93. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/stop.py +0 -0
  94. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/tasks.py +0 -0
  95. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/uninstall.py +0 -0
  96. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/update.py +0 -0
  97. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli/handlers/verify.py +0 -0
  98. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli_dependencies.py +0 -0
  99. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/cli_test_harness.py +0 -0
  100. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/control_flags.py +0 -0
  101. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/deployment_mode.py +0 -0
  102. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/__init__.py +0 -0
  103. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/client_compatibility.py +0 -0
  104. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/configure_preset.py +0 -0
  105. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/deployment_item.py +0 -0
  106. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/deployment_item_registry.py +0 -0
  107. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/deployment_state.py +0 -0
  108. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/generation.py +0 -0
  109. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/placement.py +0 -0
  110. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/service_versions.py +0 -0
  111. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/validation.py +0 -0
  112. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/domain/version_id.py +0 -0
  113. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/download_templates.py +0 -0
  114. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/environment.py +0 -0
  115. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/exceptions.py +0 -0
  116. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/__init__.py +0 -0
  117. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/cert_infra.py +0 -0
  118. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/current_version_resolver.py +0 -0
  119. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/docker_client.py +0 -0
  120. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/document_step_runner.py +0 -0
  121. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/env_file_reader.py +0 -0
  122. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/filesystem.py +0 -0
  123. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/filesystem_legacy_source.py +0 -0
  124. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/filesystem_user_config_scaffolder.py +0 -0
  125. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/httpx2_http_client.py +0 -0
  126. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/in_memory_state_repository.py +0 -0
  127. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/noop_docker_client.py +0 -0
  128. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/offline_http_client.py +0 -0
  129. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/package_defaults_source.py +0 -0
  130. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/package_template_provider.py +0 -0
  131. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/package_version_provider.py +0 -0
  132. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/preset_loader.py +0 -0
  133. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/system_clock.py +0 -0
  134. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/yaml_config_source.py +0 -0
  135. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/infra/yaml_state_repository.py +0 -0
  136. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/normalizers.py +0 -0
  137. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/output_spec.py +0 -0
  138. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/printer.py +0 -0
  139. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/public_url.py +0 -0
  140. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/renderer.py +0 -0
  141. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/resources/__init__.py +0 -0
  142. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/secret_factory.py +0 -0
  143. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/self_signed_ssl.py +0 -0
  144. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/__init__.py +0 -0
  145. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/authentik.py +0 -0
  146. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/authentik_blueprint.py +0 -0
  147. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/database.py +0 -0
  148. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/logging.py +0 -0
  149. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/nginx.py +0 -0
  150. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/service_urls.py +0 -0
  151. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/storage.py +0 -0
  152. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/telemetry.py +0 -0
  153. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/steps/user.py +0 -0
  154. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/template_provisioning.py +0 -0
  155. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/.template-version +0 -0
  156. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/_env_fragment_web.template +0 -0
  157. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/api.env.template +0 -0
  158. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/branding/favicon.ico +0 -0
  159. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/branding/logo.png +0 -0
  160. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_confirmation.html +0 -0
  161. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_exists.html +0 -0
  162. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_invitation.html +0 -0
  163. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_forgotten_password.html +0 -0
  164. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_changed.html +0 -0
  165. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_reset.html +0 -0
  166. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/octopize-avatar-blueprint.yaml +0 -0
  167. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/authentik/translations.json +0 -0
  168. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/compose.override.yaml.template +0 -0
  169. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/docker-compose.yml.template +0 -0
  170. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/nginx.conf.template +0 -0
  171. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/python_client.env.template +0 -0
  172. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/templates/web.env.template +0 -0
  173. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/tls_types.py +0 -0
  174. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/topology_urls.py +0 -0
  175. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/url_contract.py +0 -0
  176. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/verbosity.py +0 -0
  177. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/src/octopize_avatar_deploy/version_compat.py +0 -0
  178. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/TESTING.md +0 -0
  179. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/__init__.py +0 -0
  180. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/conftest.py +0 -0
  181. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/__init__.py +0 -0
  182. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/conftest.py +0 -0
  183. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/test_migrate_start_provision_verify.py +0 -0
  184. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/test_update_reapplies_blueprint.py +0 -0
  185. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/e2e/user_disable_revokes_api_key.py +0 -0
  186. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/__init__.py +0 -0
  187. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/apply_help/output.txt +0 -0
  188. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/authentik_migration/licenses.csv +0 -0
  189. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/authentik_migration/organizations.csv +0 -0
  190. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/authentik_migration/users.csv +0 -0
  191. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/configure_happy_path/expected/.deployment_states/v1/deployment_state.yaml +0 -0
  192. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/configure_happy_path/input.yaml +0 -0
  193. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/configure_happy_path/output.txt +0 -0
  194. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/configure_help/output.txt +0 -0
  195. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_help/output.txt +0 -0
  196. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/from/.env +0 -0
  197. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/from/nginx/nginx.conf +0 -0
  198. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/output.txt +0 -0
  199. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/to/.env +0 -0
  200. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/to/docker-compose.yml +0 -0
  201. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/diff_integration/to/nginx/nginx.conf +0 -0
  202. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.env +0 -0
  203. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/admin_emails +0 -0
  204. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/authjwt_secret_key +0 -0
  205. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/clevercloud_sso_salt +0 -0
  206. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_password +0 -0
  207. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_user +0 -0
  208. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_name +0 -0
  209. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_password +0 -0
  210. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_user +0 -0
  211. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/file_jwt_secret_key +0 -0
  212. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/organization_name +0 -0
  213. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/pepper +0 -0
  214. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/smtp_password +0 -0
  215. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_access_key_id +0 -0
  216. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_secret_access_key +0 -0
  217. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/help/output.txt +0 -0
  218. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/.permissions.json +0 -0
  219. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/branding/favicon.ico +0 -0
  220. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/branding/logo.png +0 -0
  221. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  222. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  223. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  224. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  225. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  226. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  227. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  228. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/authentik/translations.json +0 -0
  229. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/docker-compose.yml +0 -0
  230. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_apply_output/nginx/nginx.conf +0 -0
  231. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_help/output.txt +0 -0
  232. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/.permissions.json +0 -0
  233. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/branding/favicon.ico +0 -0
  234. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/branding/logo.png +0 -0
  235. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  236. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  237. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  238. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  239. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  240. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  241. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  242. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/authentik/translations.json +0 -0
  243. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/docker-compose.yml +0 -0
  244. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/install_render_output/nginx/nginx.conf +0 -0
  245. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/migrate_help/output.txt +0 -0
  246. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/missing_subcommand/output.txt +0 -0
  247. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/non_interactive_complete/config.yaml +0 -0
  248. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/non_interactive_no_telemetry/config.yaml +0 -0
  249. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/render_help/output.txt +0 -0
  250. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/start_help/output.txt +0 -0
  251. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/stop_help/output.txt +0 -0
  252. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_authentik_migrate_help/output.txt +0 -0
  253. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_create_self_signed_cert_help/output.txt +0 -0
  254. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_create_users_help/output.txt +0 -0
  255. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_help/output.txt +0 -0
  256. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_provision_admin_help/output.txt +0 -0
  257. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/tasks_reconcile_blueprint_help/output.txt +0 -0
  258. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/uninstall_help/output.txt +0 -0
  259. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_help/output.txt +0 -0
  260. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/base_v1/generated_files/.env +0 -0
  261. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.needs_blueprint_reconcile +0 -0
  262. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.permissions.json +0 -0
  263. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/favicon.ico +0 -0
  264. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/logo.png +0 -0
  265. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  266. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  267. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  268. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  269. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  270. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  271. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  272. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/translations.json +0 -0
  273. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/docker-compose.yml +0 -0
  274. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_apply_output/nginx/nginx.conf +0 -0
  275. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/.permissions.json +0 -0
  276. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/favicon.ico +0 -0
  277. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/logo.png +0 -0
  278. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  279. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  280. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  281. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  282. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  283. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  284. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  285. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/translations.json +0 -0
  286. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/docker-compose.yml +0 -0
  287. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_interactive_diff/expected_render_output/nginx/nginx.conf +0 -0
  288. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/base_v1/generated_files/.env +0 -0
  289. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.needs_blueprint_reconcile +0 -0
  290. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.permissions.json +0 -0
  291. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/favicon.ico +0 -0
  292. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/logo.png +0 -0
  293. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  294. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  295. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  296. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  297. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  298. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  299. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  300. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/translations.json +0 -0
  301. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/docker-compose.yml +0 -0
  302. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/nginx/nginx.conf +0 -0
  303. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/.permissions.json +0 -0
  304. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/favicon.ico +0 -0
  305. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/logo.png +0 -0
  306. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  307. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  308. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  309. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  310. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  311. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  312. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  313. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/translations.json +0 -0
  314. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/docker-compose.yml +0 -0
  315. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/nginx/nginx.conf +0 -0
  316. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/fixtures/verify_help/output.txt +0 -0
  317. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/__init__.py +0 -0
  318. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/fakes.py +0 -0
  319. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/fixture_dir_comparison.py +0 -0
  320. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/normalization.py +0 -0
  321. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/printers.py +0 -0
  322. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/steps.py +0 -0
  323. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/helpers/tls_fixtures.py +0 -0
  324. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/__init__.py +0 -0
  325. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_authentik_migrate_task.py +0 -0
  326. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_client_compatibility_output.py +0 -0
  327. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_configure_command.py +0 -0
  328. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_create_self_signed_cert_task.py +0 -0
  329. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_diff_command.py +0 -0
  330. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_install_command.py +0 -0
  331. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_legacy_app_root.py +0 -0
  332. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_migrate_first_run.py +0 -0
  333. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_migrate_relative_tls_paths.py +0 -0
  334. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_migrate_without_tls_keys.py +0 -0
  335. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/integration/test_update_command.py +0 -0
  336. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/test_cli_harness.py +0 -0
  337. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/__init__.py +0 -0
  338. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/conftest.py +0 -0
  339. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_docker_client.py +0 -0
  340. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_filesystem.py +0 -0
  341. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_filesystem_legacy_source.py +0 -0
  342. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_httpx2_http_client.py +0 -0
  343. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_preset_loader.py +0 -0
  344. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_yaml_config_source.py +0 -0
  345. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/infra/test_yaml_deployment_state_repository.py +0 -0
  346. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_authentik.py +0 -0
  347. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_authentik_blueprint.py +0 -0
  348. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_database.py +0 -0
  349. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_logging.py +0 -0
  350. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_nginx.py +0 -0
  351. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_required.py +0 -0
  352. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_service_urls.py +0 -0
  353. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_storage.py +0 -0
  354. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_telemetry.py +0 -0
  355. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/steps/test_user.py +0 -0
  356. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_apply_command.py +0 -0
  357. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_env.py +0 -0
  358. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_login.py +0 -0
  359. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_migrate_command.py +0 -0
  360. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_migrate_for_docker.py +0 -0
  361. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_migrate_parsers.py +0 -0
  362. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_authentik_readiness.py +0 -0
  363. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_cert_generator.py +0 -0
  364. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_certificate_verifier.py +0 -0
  365. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_cli_verify_ssl.py +0 -0
  366. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_client_compatibility.py +0 -0
  367. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_compare_helpers.py +0 -0
  368. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_config_resolver_consistency.py +0 -0
  369. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_configure_command.py +0 -0
  370. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_create_self_signed_cert_task.py +0 -0
  371. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_deployment_item.py +0 -0
  372. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_docs_command_references.py +0 -0
  373. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_environment.py +0 -0
  374. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_generation.py +0 -0
  375. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_generic_prompt.py +0 -0
  376. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_install_command.py +0 -0
  377. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_migrate_command.py +0 -0
  378. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_normalizers.py +0 -0
  379. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_output_spec.py +0 -0
  380. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_placement.py +0 -0
  381. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_polling.py +0 -0
  382. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_preflight_checks.py +0 -0
  383. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_printer.py +0 -0
  384. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_provision_admin.py +0 -0
  385. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_public_url.py +0 -0
  386. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_reconcile_blueprint.py +0 -0
  387. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_render_command.py +0 -0
  388. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_renderer.py +0 -0
  389. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_secret_factory.py +0 -0
  390. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_secret_files.py +0 -0
  391. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_select_authentik_migrate_parser.py +0 -0
  392. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_service_versions.py +0 -0
  393. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_start_command.py +0 -0
  394. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_stop_command.py +0 -0
  395. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_task_registry.py +0 -0
  396. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_uninstall_command.py +0 -0
  397. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_update_command.py +0 -0
  398. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_user_config.py +0 -0
  399. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_validation.py +0 -0
  400. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_verify_command.py +0 -0
  401. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.0}/tests/unit/test_version_id.py +0 -0
  402. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.4.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.0
3
+ Version: 3.4.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. Every command and
100
- `tasks` sub-command takes `--verbosity {1,2}`, where `1` is essential (the default) and `2` is
101
- verbose. Every command's `--help` lists its full option set.
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
 
@@ -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. Every command and
67
- `tasks` sub-command takes `--verbosity {1,2}`, where `1` is essential (the default) and `2` is
68
- verbose. Every command's `--help` lists its full option set.
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
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "octopize.deploy_tool"
7
- version = "3.3.0"
7
+ version = "3.4.0"
8
8
  description = "Deployment configuration tool for Octopize Avatar platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -9,7 +9,7 @@ from .version_compat import (
9
9
  validate_template_version,
10
10
  )
11
11
 
12
- __version__ = "3.3.0"
12
+ __version__ = "3.4.0"
13
13
  __all__ = [
14
14
  "SCRIPT_VERSION",
15
15
  "ConsolePrinter",
@@ -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"
@@ -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
- "Run 'start' to bring up the stack."
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
- "Run 'start' to bring up the stack."
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._printer.print(f" {spec.email} — already exists, skipping")
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
- "Run 'start' to bring up the stack and re-apply the Authentik blueprint."
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
@@ -16,6 +16,12 @@ from typing import IO, Any
16
16
  import httpx
17
17
  import pandas as pd
18
18
 
19
+ from octopize_avatar_deploy.authentik_user_types import (
20
+ EXTERNAL_USER_TYPE,
21
+ AuthentikUserType,
22
+ user_type_for_avatar_role,
23
+ )
24
+
19
25
 
20
26
  class OperationType(Enum):
21
27
  """Types of operations that can be performed."""
@@ -126,6 +132,7 @@ class MigrationParser:
126
132
  if pd.isna(user["email"]) and pd.isna(user.get("username")):
127
133
  continue
128
134
 
135
+ role = str(user["role"]) if pd.notna(user["role"]) else None
129
136
  user_data = {
130
137
  "name": (
131
138
  str(user["username"])
@@ -137,9 +144,9 @@ class MigrationParser:
137
144
  str(user["username"]) if pd.notna(user.get("username")) else str(user["email"])
138
145
  ),
139
146
  "is_active": True,
140
- "type": "external",
147
+ "type": user_type_for_avatar_role(role),
141
148
  "attributes": {
142
- "role": str(user["role"]) if pd.notna(user["role"]) else None,
149
+ "role": role,
143
150
  "must_reset_password": True,
144
151
  },
145
152
  }
@@ -234,6 +241,7 @@ class AuthentikClient:
234
241
  name: str,
235
242
  email: str | None,
236
243
  attributes: dict[str, Any],
244
+ user_type: AuthentikUserType = EXTERNAL_USER_TYPE,
237
245
  ) -> int:
238
246
  """Create a user in authentik.
239
247
 
@@ -245,7 +253,7 @@ class AuthentikClient:
245
253
  "username": username,
246
254
  "name": name,
247
255
  "is_active": True,
248
- "type": "external",
256
+ "type": user_type,
249
257
  "attributes": attributes,
250
258
  }
251
259
  if email:
@@ -349,6 +357,7 @@ class AuthentikClient:
349
357
  name=op.data["name"],
350
358
  email=op.data.get("email"),
351
359
  attributes=op.data["attributes"],
360
+ user_type=op.data.get("type", EXTERNAL_USER_TYPE),
352
361
  )
353
362
  counts["users_created"] += 1
354
363
  print(f"✓ Created user: {op.data['username']}") # noqa: T201
@@ -0,0 +1,23 @@
1
+ """Authentik user types, and which one an Avatar user needs.
2
+
3
+ Authentik only serves its admin interface to internal users, superuser group
4
+ membership or not — so an Avatar admin has to be created as an internal user.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Literal
10
+
11
+ AuthentikUserType = Literal["internal", "external"]
12
+
13
+ INTERNAL_USER_TYPE: AuthentikUserType = "internal"
14
+ EXTERNAL_USER_TYPE: AuthentikUserType = "external"
15
+
16
+ ADMIN_ROLE = "admin"
17
+
18
+
19
+ def user_type_for_avatar_role(role: str | None) -> AuthentikUserType:
20
+ """Map an Avatar user role onto the Authentik user type it needs."""
21
+ if role is not None and role.strip().lower() == ADMIN_ROLE:
22
+ return INTERNAL_USER_TYPE
23
+ return EXTERNAL_USER_TYPE
@@ -9,6 +9,7 @@ from collections.abc import Callable
9
9
 
10
10
  from rich_argparse import RawDescriptionRichHelpFormatter, RichHelpFormatter
11
11
 
12
+ from octopize_avatar_deploy.app_root import validate_app_root
12
13
  from octopize_avatar_deploy.application._guards import CommandError
13
14
  from octopize_avatar_deploy.cli.handlers import (
14
15
  apply,
@@ -274,6 +275,10 @@ def _build_parser() -> argparse.ArgumentParser:
274
275
  return parser
275
276
 
276
277
 
278
+ # Commands that only read the deployment root, so a read-only root does not stop
279
+ # an operator from shutting the stack down or inspecting it.
280
+ _READ_ONLY_COMMANDS = frozenset({"stop", "diff", "verify"})
281
+
277
282
  # Maps each subcommand to its handler. Every handler has the same
278
283
  # ``(args, deps)`` signature so dispatch is a single dictionary lookup.
279
284
  _COMMAND_HANDLERS: dict[str, Callable[[argparse.Namespace, CliDependencies], None]] = {
@@ -311,6 +316,10 @@ def main(argv: list[str] | None = None, deps: CliDependencies | None = None) ->
311
316
  deps = (deps or CliDependencies()).with_production_defaults()
312
317
 
313
318
  try:
319
+ if getattr(args, "app_root", None) is not None:
320
+ args.app_root = validate_app_root(
321
+ args.app_root, require_write=args.command not in _READ_ONLY_COMMANDS
322
+ )
314
323
  handler = _COMMAND_HANDLERS.get(args.command)
315
324
  if handler is None:
316
325
  raise RuntimeError(f"Unsupported command: {args.command}")
@@ -119,11 +119,15 @@ class ConfigResolver(Protocol):
119
119
  def prompt_bool(
120
120
  self,
121
121
  message: str,
122
- default: bool = True,
122
+ default: bool | None = True,
123
123
  key: str | None = None,
124
124
  help_text: str | None = None,
125
125
  ) -> bool:
126
- """Prompt for a yes/no value."""
126
+ """Prompt for a yes/no value.
127
+
128
+ ``default=None`` makes the answer mandatory: Enter is refused and the
129
+ operator has to state yes or no.
130
+ """
127
131
  ...
128
132
 
129
133
  def prompt_choice(
@@ -184,6 +188,15 @@ def _navigate_defaults(
184
188
  return value
185
189
 
186
190
 
191
+ def _lacks_usable_default(config: PromptConfig[Any], default_value: Any) -> bool:
192
+ """Whether *config* is required and has nothing the tool could accept for it.
193
+
194
+ Such an item has no default in any meaningful sense: the prompt must not
195
+ advertise one, and a non-interactive run has nothing to fall back on.
196
+ """
197
+ return config.required and not default_value
198
+
199
+
187
200
  class ConcreteConfigResolver:
188
201
  """Production :class:`ConfigResolver` over a shared config dict.
189
202
 
@@ -239,6 +252,11 @@ class ConcreteConfigResolver:
239
252
  return value
240
253
 
241
254
  # 3. Non-interactive: fall back to the default.
255
+ if _lacks_usable_default(config, default_value):
256
+ raise ValueError(
257
+ f"'{config.config_key}' is required and no value was provided. "
258
+ "Add it to your configuration file, or run interactively."
259
+ )
242
260
  self.resolved_sources[config.config_key] = DeploymentItemSource.DEFAULT
243
261
  return self._parse_or_raise(
244
262
  default_value,
@@ -260,6 +278,10 @@ class ConcreteConfigResolver:
260
278
  )
261
279
  return value
262
280
 
281
+ prompt_default = (
282
+ None if _lacks_usable_default(config, default_value) else str(default_value)
283
+ )
284
+
263
285
  if config.parse_and_validate:
264
286
  # Capture the parsed value so it is not parsed twice.
265
287
  parsed_value: Any = None
@@ -277,7 +299,7 @@ class ConcreteConfigResolver:
277
299
 
278
300
  self.input_gatherer.prompt(
279
301
  config.prompt_message,
280
- str(default_value),
302
+ prompt_default,
281
303
  capturing_validator,
282
304
  config.prompt_key,
283
305
  config.help_text,
@@ -286,7 +308,7 @@ class ConcreteConfigResolver:
286
308
 
287
309
  return self.input_gatherer.prompt(
288
310
  config.prompt_message,
289
- str(default_value),
311
+ prompt_default,
290
312
  None,
291
313
  config.prompt_key,
292
314
  config.help_text,
@@ -346,7 +368,7 @@ class ConcreteConfigResolver:
346
368
  def prompt_bool(
347
369
  self,
348
370
  message: str,
349
- default: bool = True,
371
+ default: bool | None = True,
350
372
  key: str | None = None,
351
373
  help_text: str | None = None,
352
374
  ) -> bool:
@@ -496,7 +518,7 @@ class FixedConfigResolver:
496
518
  def prompt_bool(
497
519
  self,
498
520
  message: str,
499
- default: bool = True,
521
+ default: bool | None = True,
500
522
  key: str | None = None,
501
523
  help_text: str | None = None,
502
524
  ) -> bool:
@@ -571,7 +593,7 @@ class RecordingConfigResolver:
571
593
  def prompt_bool(
572
594
  self,
573
595
  message: str,
574
- default: bool = True,
596
+ default: bool | None = True,
575
597
  key: str | None = None,
576
598
  help_text: str | None = None,
577
599
  ) -> bool:
@@ -1,6 +1,6 @@
1
1
  version: 1.0.0
2
2
  images:
3
- api: 3.6.1
3
+ api: 3.8.0
4
4
  web: 0.68.0
5
5
  seaweedfs: "4.44"
6
6
  authentik: 2026.2.6