octopize.deploy_tool 2.2.0__tar.gz → 2.3.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 (270) hide show
  1. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/PKG-INFO +1 -1
  2. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/pyproject.toml +1 -1
  3. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/__init__.py +1 -1
  4. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/defaults.yaml +1 -1
  5. octopize_deploy_tool-2.3.0/src/octopize_avatar_deploy/steps/authentik.py +92 -0
  6. octopize_deploy_tool-2.3.0/src/octopize_avatar_deploy/steps/email.py +178 -0
  7. octopize_deploy_tool-2.3.0/src/octopize_avatar_deploy/steps/nginx.py +188 -0
  8. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/required.py +76 -11
  9. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/telemetry.py +33 -0
  10. {octopize_deploy_tool-2.2.0/tests/fixtures/config_round_trip_second → octopize_deploy_tool-2.3.0/tests/fixtures/basic_deployment}/expected/.deployment-state.yaml +4 -4
  11. {octopize_deploy_tool-2.2.0/tests/fixtures/config_round_trip_second → octopize_deploy_tool-2.3.0/tests/fixtures/basic_deployment}/expected/.env +6 -6
  12. octopize_deploy_tool-2.3.0/tests/fixtures/basic_deployment/output.txt +99 -0
  13. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/.deployment-state.yaml +4 -4
  14. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/.env +6 -6
  15. octopize_deploy_tool-2.3.0/tests/fixtures/cloud_storage/output.txt +99 -0
  16. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/.deployment-state.yaml +4 -4
  17. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/.env +6 -6
  18. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/deployment-config.yaml +4 -4
  19. {octopize_deploy_tool-2.2.0/tests/fixtures/basic_deployment → octopize_deploy_tool-2.3.0/tests/fixtures/config_round_trip_second}/expected/.deployment-state.yaml +4 -4
  20. {octopize_deploy_tool-2.2.0/tests/fixtures/basic_deployment → octopize_deploy_tool-2.3.0/tests/fixtures/config_round_trip_second}/expected/.env +6 -6
  21. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/.deployment-state.yaml +10 -10
  22. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/.env +6 -6
  23. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/output.txt +42 -0
  24. octopize_deploy_tool-2.3.0/tests/fixtures/invalid_port_config/output.txt +100 -0
  25. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/.deployment-state.yaml +4 -4
  26. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/.env +6 -6
  27. octopize_deploy_tool-2.3.0/tests/fixtures/no_telemetry/output.txt +99 -0
  28. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/.deployment-state.yaml +4 -4
  29. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/.env +6 -6
  30. octopize_deploy_tool-2.3.0/tests/fixtures/non_interactive_complete/output.txt +100 -0
  31. octopize_deploy_tool-2.3.0/tests/fixtures/non_interactive_incomplete_config/output.txt +100 -0
  32. octopize_deploy_tool-2.3.0/tests/fixtures/non_interactive_partial_config/output.txt +100 -0
  33. octopize_deploy_tool-2.3.0/tests/fixtures/output_dir_nested/output.txt +99 -0
  34. octopize_deploy_tool-2.3.0/tests/fixtures/prompt_help/output.txt +167 -0
  35. octopize_deploy_tool-2.3.0/tests/fixtures/resume_interrupted/first_run/output.txt +55 -0
  36. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/resume_interrupted/resume/output.txt +12 -0
  37. octopize_deploy_tool-2.3.0/tests/fixtures/save_config_interactive/output.txt +101 -0
  38. octopize_deploy_tool-2.3.0/tests/fixtures/save_config_with_existing/output.txt +102 -0
  39. octopize_deploy_tool-2.3.0/tests/fixtures/type_mismatch_config/output.txt +100 -0
  40. octopize_deploy_tool-2.3.0/tests/steps/test_email.py +251 -0
  41. octopize_deploy_tool-2.3.0/tests/steps/test_nginx.py +131 -0
  42. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_required.py +31 -0
  43. octopize_deploy_tool-2.2.0/src/octopize_avatar_deploy/steps/authentik.py +0 -53
  44. octopize_deploy_tool-2.2.0/src/octopize_avatar_deploy/steps/email.py +0 -103
  45. octopize_deploy_tool-2.2.0/src/octopize_avatar_deploy/steps/nginx.py +0 -76
  46. octopize_deploy_tool-2.2.0/tests/fixtures/basic_deployment/output.txt +0 -57
  47. octopize_deploy_tool-2.2.0/tests/fixtures/cloud_storage/output.txt +0 -57
  48. octopize_deploy_tool-2.2.0/tests/fixtures/invalid_port_config/output.txt +0 -58
  49. octopize_deploy_tool-2.2.0/tests/fixtures/no_telemetry/output.txt +0 -57
  50. octopize_deploy_tool-2.2.0/tests/fixtures/non_interactive_complete/output.txt +0 -58
  51. octopize_deploy_tool-2.2.0/tests/fixtures/non_interactive_incomplete_config/output.txt +0 -58
  52. octopize_deploy_tool-2.2.0/tests/fixtures/non_interactive_partial_config/output.txt +0 -58
  53. octopize_deploy_tool-2.2.0/tests/fixtures/output_dir_nested/output.txt +0 -57
  54. octopize_deploy_tool-2.2.0/tests/fixtures/prompt_help/output.txt +0 -82
  55. octopize_deploy_tool-2.2.0/tests/fixtures/resume_interrupted/first_run/output.txt +0 -25
  56. octopize_deploy_tool-2.2.0/tests/fixtures/save_config_interactive/output.txt +0 -59
  57. octopize_deploy_tool-2.2.0/tests/fixtures/save_config_with_existing/output.txt +0 -60
  58. octopize_deploy_tool-2.2.0/tests/fixtures/type_mismatch_config/output.txt +0 -58
  59. octopize_deploy_tool-2.2.0/tests/steps/test_email.py +0 -130
  60. octopize_deploy_tool-2.2.0/tests/steps/test_nginx.py +0 -52
  61. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/.gitignore +0 -0
  62. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/README.md +0 -0
  63. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/authentik_migration.py +0 -0
  64. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/cli.py +0 -0
  65. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/cli_test_harness.py +0 -0
  66. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/components.py +0 -0
  67. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/configure.py +0 -0
  68. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/deployment_mode.py +0 -0
  69. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/download_templates.py +0 -0
  70. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/generate_env.py +0 -0
  71. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/generate_env_paths.py +0 -0
  72. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/input_gatherer.py +0 -0
  73. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/output_spec.py +0 -0
  74. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/printer.py +0 -0
  75. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/public_url.py +0 -0
  76. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/state_manager.py +0 -0
  77. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/__init__.py +0 -0
  78. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/api_local_source.py +0 -0
  79. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/authentik_blueprint.py +0 -0
  80. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/base.py +0 -0
  81. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/component_selection.py +0 -0
  82. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/database.py +0 -0
  83. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/local_source.py +0 -0
  84. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/logging.py +0 -0
  85. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/service_urls.py +0 -0
  86. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/storage.py +0 -0
  87. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/target_environment.py +0 -0
  88. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/steps/user.py +0 -0
  89. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/template_provisioning.py +0 -0
  90. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/.env.template +0 -0
  91. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/.template-version +0 -0
  92. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/_env_fragment_api.template +0 -0
  93. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/_env_fragment_infra.template +0 -0
  94. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/_env_fragment_web.template +0 -0
  95. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/api.env.template +0 -0
  96. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/branding/favicon.ico +0 -0
  97. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/branding/logo.png +0 -0
  98. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_confirmation.html +0 -0
  99. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_exists.html +0 -0
  100. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_invitation.html +0 -0
  101. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_forgotten_password.html +0 -0
  102. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_changed.html +0 -0
  103. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_reset.html +0 -0
  104. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/octopize-avatar-blueprint.yaml +0 -0
  105. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/authentik/translations.json +0 -0
  106. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/compose.override.yaml.template +0 -0
  107. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/docker-compose.yml.template +0 -0
  108. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/nginx.conf.template +0 -0
  109. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/python_client.env.template +0 -0
  110. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/templates/web.env.template +0 -0
  111. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/topology_urls.py +0 -0
  112. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/url_contract.py +0 -0
  113. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/src/octopize_avatar_deploy/version_compat.py +0 -0
  114. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/TESTING.md +0 -0
  115. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/__init__.py +0 -0
  116. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/conftest.py +0 -0
  117. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/__init__.py +0 -0
  118. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/authentik_migration/licenses.csv +0 -0
  119. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/authentik_migration/organizations.csv +0 -0
  120. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/authentik_migration/users.csv +0 -0
  121. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/branding/favicon.ico +0 -0
  122. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/branding/logo.png +0 -0
  123. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  124. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_account_exists.html +0 -0
  125. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  126. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  127. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_password_changed.html +0 -0
  128. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/custom-templates/email_password_reset.html +0 -0
  129. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  130. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/authentik/translations.json +0 -0
  131. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/docker-compose.yml +0 -0
  132. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/expected/nginx/nginx.conf +0 -0
  133. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/basic_deployment/input.yaml +0 -0
  134. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/branding/favicon.ico +0 -0
  135. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/branding/logo.png +0 -0
  136. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  137. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_account_exists.html +0 -0
  138. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  139. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  140. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_password_changed.html +0 -0
  141. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/custom-templates/email_password_reset.html +0 -0
  142. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  143. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/authentik/translations.json +0 -0
  144. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/docker-compose.yml +0 -0
  145. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/expected/nginx/nginx.conf +0 -0
  146. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/cloud_storage/input.yaml +0 -0
  147. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_not_found/output.txt +0 -0
  148. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/branding/favicon.ico +0 -0
  149. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/branding/logo.png +0 -0
  150. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  151. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_account_exists.html +0 -0
  152. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  153. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  154. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_password_changed.html +0 -0
  155. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/custom-templates/email_password_reset.html +0 -0
  156. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  157. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/authentik/translations.json +0 -0
  158. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/docker-compose.yml +0 -0
  159. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_first/expected/nginx/nginx.conf +0 -0
  160. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/branding/favicon.ico +0 -0
  161. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/branding/logo.png +0 -0
  162. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  163. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_account_exists.html +0 -0
  164. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  165. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  166. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_password_changed.html +0 -0
  167. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/custom-templates/email_password_reset.html +0 -0
  168. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  169. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/authentik/translations.json +0 -0
  170. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/docker-compose.yml +0 -0
  171. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/config_round_trip_second/expected/nginx/nginx.conf +0 -0
  172. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/deploy_help/output.txt +0 -0
  173. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/branding/favicon.ico +0 -0
  174. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/branding/logo.png +0 -0
  175. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  176. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_account_exists.html +0 -0
  177. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  178. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  179. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_password_changed.html +0 -0
  180. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/custom-templates/email_password_reset.html +0 -0
  181. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  182. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/authentik/translations.json +0 -0
  183. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/compose.override.yaml +0 -0
  184. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/docker-compose.yml +0 -0
  185. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/nginx/nginx.conf +0 -0
  186. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/test-.npmrc +0 -0
  187. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/test-avatar-repo/services/api/main.py +0 -0
  188. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/expected/test-avatar-website/package.json +0 -0
  189. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/dev_mode_deployment/input.yaml +0 -0
  190. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/generate_env_help/output.txt +0 -0
  191. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/generate_env_output_dir_error/output.txt +0 -0
  192. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/help/output.txt +0 -0
  193. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/invalid_port_config/config.yaml +0 -0
  194. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/invalid_url_config/config.yaml +0 -0
  195. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/invalid_url_config/output.txt +0 -0
  196. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/malformed_yaml/config.yaml +0 -0
  197. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/malformed_yaml/output.txt +0 -0
  198. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/missing_subcommand/output.txt +0 -0
  199. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/branding/favicon.ico +0 -0
  200. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/branding/logo.png +0 -0
  201. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  202. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_account_exists.html +0 -0
  203. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  204. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  205. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_password_changed.html +0 -0
  206. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/custom-templates/email_password_reset.html +0 -0
  207. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  208. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/authentik/translations.json +0 -0
  209. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/docker-compose.yml +0 -0
  210. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/expected/nginx/nginx.conf +0 -0
  211. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/no_telemetry/input.yaml +0 -0
  212. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/config.yaml +0 -0
  213. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/branding/favicon.ico +0 -0
  214. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/branding/logo.png +0 -0
  215. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_account_confirmation.html +0 -0
  216. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_account_exists.html +0 -0
  217. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_account_invitation.html +0 -0
  218. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_forgotten_password.html +0 -0
  219. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_password_changed.html +0 -0
  220. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/custom-templates/email_password_reset.html +0 -0
  221. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/octopize-avatar-blueprint.yaml +0 -0
  222. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/authentik/translations.json +0 -0
  223. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/docker-compose.yml +0 -0
  224. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_complete/expected/nginx/nginx.conf +0 -0
  225. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_incomplete_config/config.yaml +0 -0
  226. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_no_config/output.txt +0 -0
  227. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/non_interactive_partial_config/config.yaml +0 -0
  228. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/output_dir_permission_denied/output.txt +0 -0
  229. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/prompt_help/input.yaml +0 -0
  230. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/resume_interrupted/input_first_run.yaml +0 -0
  231. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/resume_interrupted/input_resume.yaml +0 -0
  232. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/save_config_with_existing/config.yaml +0 -0
  233. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/save_config_with_existing/input.yaml +0 -0
  234. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/template_from_local_verbose/output.txt +0 -0
  235. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/fixtures/type_mismatch_config/config.yaml +0 -0
  236. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/integration/__init__.py +0 -0
  237. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/integration/test_cli_integration.py +0 -0
  238. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/integration/test_generate_env.py +0 -0
  239. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_api_local_source.py +0 -0
  240. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_authentik.py +0 -0
  241. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_authentik_blueprint.py +0 -0
  242. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_base.py +0 -0
  243. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_component_selection.py +0 -0
  244. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_database.py +0 -0
  245. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_local_source.py +0 -0
  246. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_logging.py +0 -0
  247. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_service_urls.py +0 -0
  248. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_state_manager.py +0 -0
  249. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_storage.py +0 -0
  250. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_target_environment.py +0 -0
  251. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_telemetry.py +0 -0
  252. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_user.py +0 -0
  253. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/steps/test_user_validation.py +0 -0
  254. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/test_cli_harness.py +0 -0
  255. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_authentik_client.py +0 -0
  256. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_authentik_migration.py +0 -0
  257. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_compare_helpers.py +0 -0
  258. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_components.py +0 -0
  259. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_deployment_configurator.py +0 -0
  260. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_deployment_runner.py +0 -0
  261. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_generate_env_cli.py +0 -0
  262. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_generic_prompt.py +0 -0
  263. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_input_gatherer.py +0 -0
  264. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_output_spec.py +0 -0
  265. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_printer.py +0 -0
  266. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_public_url.py +0 -0
  267. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_rich_implementations.py +0 -0
  268. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_step_filtering.py +0 -0
  269. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_topology_urls.py +0 -0
  270. {octopize_deploy_tool-2.2.0 → octopize_deploy_tool-2.3.0}/tests/unit/test_version_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: octopize.deploy_tool
3
- Version: 2.2.0
3
+ Version: 2.3.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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "octopize.deploy_tool"
7
- version = "2.2.0"
7
+ version = "2.3.0"
8
8
  description = "Deployment configuration tool for Octopize Avatar platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -11,7 +11,7 @@ from .version_compat import (
11
11
  validate_template_version,
12
12
  )
13
13
 
14
- __version__ = "2.2.0"
14
+ __version__ = "2.3.0"
15
15
  __all__ = [
16
16
  "main",
17
17
  "DeploymentRunner",
@@ -1,6 +1,6 @@
1
1
  version: 1.0.0
2
2
  images:
3
- api: 2.73.0
3
+ api: 2.77.0
4
4
  web: 0.63.0
5
5
  pdfgenerator: 0.2.3
6
6
  seaweedfs: "4.22"
@@ -0,0 +1,92 @@
1
+ """Authentik configuration step."""
2
+
3
+ import secrets
4
+ from typing import Any
5
+
6
+ from .base import DeploymentStep, PromptConfig
7
+
8
+
9
+ class AuthentikStep(DeploymentStep):
10
+ """Handles Authentik SSO configuration and credentials."""
11
+
12
+ name = "authentik"
13
+ description = "Configure Authentik SSO authentication credentials"
14
+
15
+ def collect_config(self) -> dict[str, Any]:
16
+ """Collect Authentik configuration."""
17
+ config = {}
18
+
19
+ self.printer.print("\n--- Authentik Configuration ---")
20
+ self.printer.print(
21
+ "This section configures Authentik, the identity and access management "
22
+ "service bundled with the Avatar deployment.\n"
23
+ "\n"
24
+ "Authentik is used to:\n"
25
+ " - store and manage users\n"
26
+ " - handle authentication and permissions\n"
27
+ " - provide the login flow for Avatar\n"
28
+ " - optionally connect to an existing identity provider or directory "
29
+ "service\n"
30
+ "\n"
31
+ "Depending on your setup, Authentik can also be integrated with existing "
32
+ "user management and SSO systems such as Microsoft Entra ID, Active "
33
+ "Directory, and other external identity providers.\n"
34
+ "\n"
35
+ "Authentik documentation:\n"
36
+ "https://docs.goauthentik.io/"
37
+ )
38
+
39
+ # Authentik database name and user
40
+ # These are typically set to default values unless customized
41
+ authentik_db_name = self.get_config("AUTHENTIK_DATABASE_NAME", "authentik")
42
+ authentik_db_user = self.get_config("AUTHENTIK_DATABASE_USER", "authentik")
43
+
44
+ config["AUTHENTIK_DATABASE_NAME"] = authentik_db_name
45
+ config["AUTHENTIK_DATABASE_USER"] = authentik_db_user
46
+
47
+ # Bootstrap configuration for automated install (skip OOBE)
48
+ # Default email for akadmin user
49
+ authentik_bootstrap_email = self.get_config_or_prompt_generic(
50
+ PromptConfig(
51
+ config_key="AUTHENTIK_BOOTSTRAP_EMAIL",
52
+ prompt_message="Enter email address for Authentik admin user (akadmin)",
53
+ default_value="admin@example.com",
54
+ prompt_key="authentik.bootstrap_email",
55
+ help_text=(
56
+ "Email address of the initial Authentik administrator account created "
57
+ "during bootstrap.\n"
58
+ "\n"
59
+ "This user will have full administrative access to the Authentik "
60
+ "application. It can manage users, authentication flows, providers, "
61
+ "integrations, and permissions.\n"
62
+ "\n"
63
+ "You can create additional super-admin users later if needed.\n"
64
+ "\n"
65
+ "No signup email is sent to this bootstrap administrator during "
66
+ "installation. It is still recommended to use a real, reachable email "
67
+ "address for operational clarity and future account management, but this "
68
+ "is not strictly required.\n"
69
+ "\n"
70
+ "This email address can also be used to log in."
71
+ ),
72
+ )
73
+ )
74
+ config["AUTHENTIK_BOOTSTRAP_EMAIL"] = authentik_bootstrap_email
75
+
76
+ # Generate bootstrap credentials (these go in .env, not as secrets)
77
+ config["AUTHENTIK_BOOTSTRAP_PASSWORD"] = secrets.token_urlsafe(32)
78
+ config["AUTHENTIK_BOOTSTRAP_TOKEN"] = secrets.token_urlsafe(32)
79
+
80
+ # Update self.config so generate_secrets() can access these values
81
+ self.config.update(config)
82
+
83
+ return config
84
+
85
+ def generate_secrets(self) -> dict[str, str]:
86
+ """Generate Authentik-related secrets."""
87
+ return {
88
+ "authentik_database_name": self.config["AUTHENTIK_DATABASE_NAME"],
89
+ "authentik_database_user": self.config["AUTHENTIK_DATABASE_USER"],
90
+ "authentik_database_password": secrets.token_hex(),
91
+ "authentik_secret_key": secrets.token_hex(),
92
+ }
@@ -0,0 +1,178 @@
1
+ """Email configuration step."""
2
+
3
+ import ipaddress
4
+ from typing import Any
5
+
6
+ from .base import (
7
+ DefaultKey,
8
+ DeploymentStep,
9
+ PromptConfig,
10
+ ValidationError,
11
+ ValidationSuccess,
12
+ parse_str,
13
+ )
14
+
15
+
16
+ def validate_smtp_host(value: str) -> ValidationSuccess[str] | ValidationError:
17
+ """
18
+ Validate that the SMTP host is a hostname or domain name, not a raw IP address.
19
+
20
+ An empty value is allowed (it means SMTP is not yet configured).
21
+
22
+ Args:
23
+ value: The SMTP host value to validate
24
+
25
+ Returns:
26
+ ValidationSuccess with the host string, or ValidationError with a message
27
+ """
28
+ host = str(value).strip()
29
+
30
+ if not host:
31
+ # Empty is allowed — the operator can leave SMTP unconfigured
32
+ return ValidationSuccess(host)
33
+
34
+ # Reject raw IP addresses (both IPv4 and IPv6)
35
+ try:
36
+ ipaddress.ip_address(host)
37
+ return ValidationError(
38
+ f"'{host}' is a raw IP address. "
39
+ "SMTP_HOST must be a hostname or domain name, not an IP address. "
40
+ "Examples: 'smtp.example.com', 'smtp.sendgrid.net', 'mail.example.com'."
41
+ )
42
+ except ValueError:
43
+ pass
44
+
45
+ return ValidationSuccess(host)
46
+
47
+
48
+ class EmailStep(DeploymentStep):
49
+ """Handles email configuration and credentials."""
50
+
51
+ name = "email"
52
+ description = "Configure SMTP email settings and credentials"
53
+
54
+ def collect_config(self) -> dict[str, Any]:
55
+ """Collect email configuration."""
56
+ config = {}
57
+
58
+ print("\n--- Email Configuration ---")
59
+ self.printer.print(
60
+ "This section configures how the deployment sends outbound emails, mainly "
61
+ "for Authentik account and password workflows.\n"
62
+ "\n"
63
+ "The deployment needs an SMTP server to send emails such as account setup, "
64
+ "password reset, and other authentication-related messages.\n"
65
+ "\n"
66
+ "You can use:\n"
67
+ " - your own SMTP provider or mail server\n"
68
+ " - an SMTP service provided by Octopize, based on AWS\n"
69
+ "\n"
70
+ "If Octopize provides the SMTP service, we will give you the SMTP "
71
+ "credentials. In that case, the tool could eventually prefill the standard "
72
+ "connection settings and only ask you for the username and password we "
73
+ "provide."
74
+ )
75
+
76
+ # SMTP configuration
77
+ config["SMTP_HOST"] = self.get_config_or_prompt_generic(
78
+ PromptConfig(
79
+ config_key="SMTP_HOST",
80
+ prompt_message="SMTP host",
81
+ default_value=self.get_default_value("email.smtp.host"),
82
+ prompt_key="email.smtp_host",
83
+ parse_and_validate=validate_smtp_host,
84
+ help_text=(
85
+ "Hostname of the outbound SMTP server used to send emails from the "
86
+ "deployment.\n"
87
+ "\n"
88
+ "Use a mail server hostname or domain name, for example:\n"
89
+ " - smtp.gmail.com\n"
90
+ " - smtp.sendgrid.net\n"
91
+ " - mail.example.com\n"
92
+ "\n"
93
+ "Do not use an IP address here.\n"
94
+ "\n"
95
+ "This SMTP server is used by Authentik to send emails such as account "
96
+ "setup and password reset messages."
97
+ ),
98
+ )
99
+ )
100
+ config["SMTP_PORT"] = self.get_config_or_prompt_generic(
101
+ PromptConfig(
102
+ config_key="SMTP_PORT",
103
+ prompt_message="SMTP port",
104
+ default_value=self.get_default_value("email.smtp.port"),
105
+ prompt_key="email.smtp_port",
106
+ parse_and_validate=parse_str,
107
+ help_text=(
108
+ "TCP port for the SMTP connection.\n"
109
+ "Common values:\n"
110
+ " 587 — STARTTLS (recommended)\n"
111
+ " 465 — TLS/SSL\n"
112
+ " 25 — plain SMTP (often blocked by ISPs)"
113
+ ),
114
+ )
115
+ )
116
+ config["SMTP_USE_TLS"] = self.get_config("SMTP_USE_TLS", DefaultKey("email.smtp.use_tls"))
117
+ config["SMTP_START_TLS"] = self.get_config(
118
+ "SMTP_START_TLS", DefaultKey("email.smtp.start_tls")
119
+ )
120
+ config["SMTP_VERIFY"] = self.get_config("SMTP_VERIFY", DefaultKey("email.smtp.verify"))
121
+ config["SMTP_SENDER_EMAIL"] = self.get_config_or_prompt_generic(
122
+ PromptConfig(
123
+ config_key="SMTP_SENDER_EMAIL",
124
+ prompt_message="SMTP sender email",
125
+ default_value=self.get_default_value("email.smtp.sender_email"),
126
+ prompt_key="email.smtp_sender_email",
127
+ help_text=(
128
+ "The From: address used for all outbound emails sent by the deployment.\n"
129
+ "\n"
130
+ "This address must be authorized to send through the configured SMTP "
131
+ "server.\n"
132
+ "\n"
133
+ "In most cases, you should keep the default or the value recommended for "
134
+ "your SMTP setup. Only change it if you have a specific need, for example "
135
+ "if your SMTP provider requires the sender address to be the same as the "
136
+ "SMTP username.\n"
137
+ "\n"
138
+ "Example:\n"
139
+ " - noreply@avatar.example.com"
140
+ ),
141
+ )
142
+ )
143
+ config["SMTP_USERNAME"] = self.get_config_or_prompt_generic(
144
+ PromptConfig(
145
+ config_key="SMTP_USERNAME",
146
+ prompt_message="SMTP username",
147
+ default_value="",
148
+ prompt_key="email.smtp_username",
149
+ help_text=(
150
+ "Username for SMTP authentication. Leave blank if your server\n"
151
+ "does not require authentication."
152
+ ),
153
+ )
154
+ )
155
+
156
+ self.config.update(config)
157
+
158
+ return config
159
+
160
+ def generate_secrets(self) -> dict[str, str]:
161
+ """Generate email-related secrets."""
162
+ secrets_dict = {}
163
+
164
+ if self.interactive:
165
+ smtp_password = self.prompt(
166
+ "SMTP password (press Enter to skip)",
167
+ default="",
168
+ key="email.smtp_password",
169
+ help_text=(
170
+ "Password for SMTP authentication.\n"
171
+ "\n"
172
+ "Leave blank if your SMTP server does not require a password."
173
+ ),
174
+ )
175
+ if smtp_password:
176
+ secrets_dict["smtp_password"] = smtp_password
177
+
178
+ return secrets_dict
@@ -0,0 +1,188 @@
1
+ """Nginx TLS configuration step."""
2
+
3
+ import socket
4
+ from typing import Any
5
+
6
+ from .base import DeploymentStep, PromptConfig, parse_bool
7
+
8
+
9
+ def is_port_in_use(port: int) -> bool:
10
+ """Return True if something is already listening on *port* on localhost."""
11
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
12
+ sock.settimeout(1)
13
+ return sock.connect_ex(("127.0.0.1", port)) == 0
14
+
15
+
16
+ class NginxTlsStep(DeploymentStep):
17
+ """Handles Nginx TLS configuration."""
18
+
19
+ name = "nginx_tls"
20
+ description = "Configure Nginx TLS and HTTP settings"
21
+
22
+ def collect_config(self) -> dict[str, Any]:
23
+ """Collect Nginx TLS and HTTP configuration."""
24
+ config: dict[str, Any] = {}
25
+
26
+ self.printer.print("\n--- Nginx / TLS Configuration ---")
27
+ self.printer.print(
28
+ "This section defines how users will reach the deployment through the Nginx "
29
+ "reverse proxy.\n"
30
+ "\n"
31
+ "Here you decide whether Nginx serves plain HTTP or terminates HTTPS/TLS "
32
+ "directly. If you enable TLS, you will need to provide the certificate and "
33
+ "private key files used by Nginx.\n"
34
+ "\n"
35
+ "If you plan to enable TLS here, the public URL you entered earlier should be "
36
+ "an HTTPS URL and should match the DNS name covered by your certificate."
37
+ )
38
+
39
+ default_tls_enabled = bool(self.get_default_value("nginx.tls_enabled"))
40
+ default_http_port = str(self.get_default_value("nginx.http_port"))
41
+ default_cert_path = self.get_default_value("nginx.ssl_certificate_path")
42
+ default_key_path = self.get_default_value("nginx.ssl_certificate_key_path")
43
+
44
+ # Use generic prompt with boolean parser and yes/no prompt
45
+ tls_enabled = self.get_config_or_prompt_generic(
46
+ PromptConfig(
47
+ config_key="NGINX_TLS_ENABLED",
48
+ prompt_message="Enable TLS for Nginx?",
49
+ default_value=default_tls_enabled,
50
+ prompt_key="nginx_tls.enabled",
51
+ prompt_function=self.prompt_yes_no,
52
+ parse_and_validate=parse_bool,
53
+ help_text=(
54
+ "Enable this if Nginx should terminate HTTPS/TLS for the deployment.\n"
55
+ "\n"
56
+ "Choose yes only if:\n"
57
+ " - the public URL entered earlier is an https:// URL\n"
58
+ " - the DNS name for that URL points to this deployment\n"
59
+ " - you have a valid certificate and private key for that hostname\n"
60
+ "\n"
61
+ "If you enable TLS, the next prompts will ask for the certificate and "
62
+ "key file paths used by Nginx.\n"
63
+ "\n"
64
+ "If your setup handles TLS elsewhere and Nginx should serve only plain "
65
+ "HTTP locally, choose no."
66
+ ),
67
+ )
68
+ )
69
+
70
+ config["NGINX_TLS_ENABLED"] = tls_enabled
71
+
72
+ if tls_enabled:
73
+ cert_path = self.get_config_or_prompt_generic(
74
+ PromptConfig(
75
+ config_key="NGINX_SSL_CERTIFICATE_PATH",
76
+ prompt_message="Path to TLS certificate (full chain)",
77
+ default_value=default_cert_path,
78
+ prompt_key="nginx_tls.ssl_certificate_path",
79
+ help_text=(
80
+ "Path to the TLS certificate file that Nginx will present to clients.\n"
81
+ "\n"
82
+ "Use a PEM-formatted full-chain certificate file. This should include "
83
+ "the server certificate and the intermediate certificates needed by "
84
+ "clients.\n"
85
+ "\n"
86
+ "Expected input:\n"
87
+ " - a readable file path on the current machine\n"
88
+ " - PEM format\n"
89
+ " - full chain certificate\n"
90
+ "\n"
91
+ "If your certificate is currently in PKCS#12 format, convert it first:\n"
92
+ "https://docs.octopize.io/docs/deploying/self-hosted/self_installation#convert-pkcs12-certificate-to-pem-format\n"
93
+ "\n"
94
+ "Recommended permissions:\n"
95
+ " - certificate file readable by the current user\n"
96
+ " - for example:\n"
97
+ " chmod 644 /app/avatar/tls/server.fullchain.crt\n"
98
+ "\n"
99
+ "Make sure the file exists and is readable by the current user running "
100
+ "the deployment commands."
101
+ ),
102
+ )
103
+ )
104
+
105
+ key_path = self.get_config_or_prompt_generic(
106
+ PromptConfig(
107
+ config_key="NGINX_SSL_CERTIFICATE_KEY_PATH",
108
+ prompt_message="Path to TLS private key (decrypted)",
109
+ default_value=default_key_path,
110
+ prompt_key="nginx_tls.ssl_certificate_key_path",
111
+ help_text=(
112
+ "Path to the TLS private key file that matches the certificate "
113
+ "configured in the previous step.\n"
114
+ "\n"
115
+ "Use a decrypted private key in PEM format.\n"
116
+ "\n"
117
+ "Expected input:\n"
118
+ " - a readable file path on the current machine\n"
119
+ " - PEM format\n"
120
+ " - an unencrypted private key that Nginx can read at startup\n"
121
+ " - a key matching the configured certificate\n"
122
+ "\n"
123
+ "If your key is currently encrypted or bundled in a PKCS#12 archive, "
124
+ "convert/export it first using the deployment documentation:\n"
125
+ "https://docs.octopize.io/docs/deploying/self-hosted/self_installation#convert-pkcs12-certificate-to-pem-format\n"
126
+ "\n"
127
+ "Recommended permissions:\n"
128
+ " - private key readable by the current user\n"
129
+ " - private key kept as restrictive as possible\n"
130
+ " - for example:\n"
131
+ " chmod 600 /app/avatar/tls/private/server.decrypted.key\n"
132
+ "\n"
133
+ "Make sure the file exists and is readable by the current user running "
134
+ "the deployment commands."
135
+ ),
136
+ )
137
+ )
138
+
139
+ config["NGINX_SSL_CERTIFICATE_PATH"] = cert_path
140
+ config["NGINX_SSL_CERTIFICATE_KEY_PATH"] = key_path
141
+ else:
142
+ http_port = self.get_config_or_prompt_generic(
143
+ PromptConfig(
144
+ config_key="NGINX_HTTP_PORT",
145
+ prompt_message="HTTP port for Nginx",
146
+ default_value=default_http_port,
147
+ prompt_key="nginx_tls.http_port",
148
+ help_text=(
149
+ "TCP port on which Nginx will listen for plain HTTP traffic when TLS "
150
+ "is disabled.\n"
151
+ "\n"
152
+ "If you press Enter, the default shown in the prompt will be used.\n"
153
+ "\n"
154
+ "Common choices:\n"
155
+ " - 8080 for a local or reverse-proxied setup\n"
156
+ " - 80 for a directly exposed HTTP service\n"
157
+ "\n"
158
+ "Choose a port that is reachable in your deployment setup and not "
159
+ "already reserved by another service.\n"
160
+ "\n"
161
+ "This setting is only used when TLS is disabled in this tool."
162
+ ),
163
+ )
164
+ )
165
+
166
+ config["NGINX_HTTP_PORT"] = http_port
167
+ config["NGINX_SSL_CERTIFICATE_PATH"] = "/dev/null"
168
+ config["NGINX_SSL_CERTIFICATE_KEY_PATH"] = "/dev/null"
169
+
170
+ try:
171
+ port_number = int(http_port)
172
+ if is_port_in_use(port_number):
173
+ self.printer.print_warning(
174
+ f"Port {http_port} appears to be already in use. "
175
+ "This is expected if you are re-running the tool for an existing "
176
+ "deployment, but may cause startup failures otherwise."
177
+ )
178
+ except (ValueError, OSError):
179
+ # ValueError: http_port is not a valid integer (validation handled elsewhere).
180
+ # OSError: the socket probe itself failed (e.g. unusual network config).
181
+ # Neither case should block configuration; skip the check silently.
182
+ pass
183
+
184
+ return config
185
+
186
+ def generate_secrets(self) -> dict[str, str]:
187
+ """No secrets needed for Nginx TLS paths."""
188
+ return {}
@@ -1,11 +1,31 @@
1
1
  """Required configuration step - collects mandatory deployment settings."""
2
2
 
3
+ import re
3
4
  import secrets
4
5
  from typing import Any
5
6
 
6
7
  from octopize_avatar_deploy.public_url import normalize_public_url
7
8
 
8
- from .base import DefaultKey, DeploymentStep, PromptConfig
9
+ from .base import (
10
+ DefaultKey,
11
+ DeploymentStep,
12
+ PromptConfig,
13
+ ValidationError,
14
+ ValidationResult,
15
+ ValidationSuccess,
16
+ )
17
+
18
+ _ENV_NAME_SLUG_RE = re.compile(r"^[a-z0-9-]+$")
19
+
20
+
21
+ def parse_env_name_slug(value: Any) -> ValidationResult[str]:
22
+ """Parse and validate ENV_NAME as a safe slug."""
23
+ env_name = str(value).strip()
24
+ if not env_name:
25
+ return ValidationError("ENV_NAME is required and cannot be empty")
26
+ if not _ENV_NAME_SLUG_RE.fullmatch(env_name):
27
+ return ValidationError("ENV_NAME must use lowercase letters, numbers, and hyphens only")
28
+ return ValidationSuccess(env_name)
9
29
 
10
30
 
11
31
  class RequiredConfigStep(DeploymentStep):
@@ -28,11 +48,25 @@ class RequiredConfigStep(DeploymentStep):
28
48
  prompt_key="required_config.public_url",
29
49
  parse_and_validate=normalize_public_url,
30
50
  help_text=(
31
- "The publicly accessible URL for your Avatar deployment.\n"
51
+ "The public URL that end users will use to access your Avatar "
52
+ "deployment.\n\n"
32
53
  "Accepted formats:\n"
33
54
  " avatar.example.com (bare hostname — https:// is added)\n"
34
- " https://avatar.example.com (full URL)\n"
35
- "This value is used to build all service URLs and Authentik redirects."
55
+ " https://avatar.example.com (full URL)\n\n"
56
+ "Use the externally reachable DNS name for this deployment:\n"
57
+ " - the hostname that users will type in their browser\n"
58
+ " - the DNS name pointing to your deployment\n"
59
+ " - the hostname covered by your TLS certificate\n\n"
60
+ "Do not use:\n"
61
+ " - an internal hostname\n"
62
+ " - a private IP address\n"
63
+ " - a public IP address\n\n"
64
+ "Even if Avatar runs on a single machine, this value should usually "
65
+ "be the public hostname exposed through Nginx, not the machine name "
66
+ "itself. Nginx acts as the reverse proxy in front of the application "
67
+ "services.\n\n"
68
+ "This value is used to build the public service URLs and Authentik "
69
+ "redirect URLs."
36
70
  ),
37
71
  )
38
72
  )
@@ -45,11 +79,29 @@ class RequiredConfigStep(DeploymentStep):
45
79
  prompt_message="Environment name (e.g., mycompany-prod)",
46
80
  default_value="",
47
81
  prompt_key="required_config.env_name",
82
+ parse_and_validate=parse_env_name_slug,
48
83
  help_text=(
49
- "A short slug that identifies this deployment environment.\n"
50
- "Examples: 'mycompany-prod', 'acme-staging', 'demo'\n"
51
- "Used in log labels, secret names, and the generated docker-compose"
52
- " project name."
84
+ "A short technical name for this deployment environment.\n\n"
85
+ "Examples:\n"
86
+ " - mycompany-prod\n"
87
+ " - acme-staging\n"
88
+ " - demo\n\n"
89
+ "Use a stable, machine-friendly identifier that helps operators "
90
+ "distinguish this deployment from others. This is not a user-facing "
91
+ "label.\n\n"
92
+ "It is written into the generated deployment configuration and passed to "
93
+ "the services as an environment identifier.\n\n"
94
+ "Recommended format:\n"
95
+ " - lowercase letters\n"
96
+ " - numbers\n"
97
+ " - hyphens\n\n"
98
+ "Avoid:\n"
99
+ " - spaces\n"
100
+ " - special characters\n\n"
101
+ "Typical patterns:\n"
102
+ " - customer-prod\n"
103
+ " - customer-staging\n"
104
+ " - internal-demo"
53
105
  ),
54
106
  )
55
107
  )
@@ -63,9 +115,22 @@ class RequiredConfigStep(DeploymentStep):
63
115
  "Organization name (e.g., MyCompany)",
64
116
  key="required_config.organization_name",
65
117
  help_text=(
66
- "The name of your organization as it will appear in the deployment.\n"
67
- "Examples: 'Acme Corp', 'MyCompany', 'Octopize'\n"
68
- "This value is embedded in generated secrets and config files."
118
+ "A short organization identifier used by the deployment configuration.\n\n"
119
+ "Examples:\n"
120
+ " - acme\n"
121
+ " - my-company\n"
122
+ " - octopize\n\n"
123
+ "Use a single lowercase word or slug. Hyphens are allowed.\n\n"
124
+ "Recommended format:\n"
125
+ " - lowercase letters\n"
126
+ " - numbers\n"
127
+ " - hyphens\n\n"
128
+ "Avoid:\n"
129
+ " - spaces\n"
130
+ " - uppercase letters\n"
131
+ " - special characters\n\n"
132
+ "This is a technical identifier used in generated secrets and "
133
+ "configuration files, not a display name for end users."
69
134
  ),
70
135
  )
71
136
  if org_name.strip():
@@ -16,6 +16,21 @@ class TelemetryStep(DeploymentStep):
16
16
  """Collect telemetry configuration."""
17
17
  config = {}
18
18
 
19
+ self.printer.print("\n--- Telemetry Configuration ---")
20
+ self.printer.print(
21
+ "This section configures optional observability features for the deployment.\n"
22
+ "\n"
23
+ "Avatar can send:\n"
24
+ " - error reports to Sentry, to help diagnose application failures\n"
25
+ " - limited usage telemetry to Octopize licensing/support services\n"
26
+ "\n"
27
+ "According to the observability documentation, these flows send metadata "
28
+ "only, not user data or personal data.\n"
29
+ "\n"
30
+ "Documentation:\n"
31
+ "https://docs.octopize.io/docs/deploying/observability"
32
+ )
33
+
19
34
  default_sentry_enabled = self.get_default_value("application.sentry_enabled") == "true"
20
35
  sentry_enabled = self.get_config_or_prompt_generic(
21
36
  PromptConfig(
@@ -25,6 +40,15 @@ class TelemetryStep(DeploymentStep):
25
40
  prompt_key="telemetry.enable_sentry",
26
41
  prompt_function=self.prompt_yes_no,
27
42
  parse_and_validate=parse_bool,
43
+ help_text=(
44
+ "Enable this to send application errors to Sentry for diagnosis and "
45
+ "support.\n"
46
+ "\n"
47
+ "This is used to help investigate failures and improve stability. "
48
+ "According to the observability documentation, Sentry receives error "
49
+ "metadata such as stack traces and environment information, but not user "
50
+ "data or personal data."
51
+ ),
28
52
  )
29
53
  )
30
54
 
@@ -36,6 +60,15 @@ class TelemetryStep(DeploymentStep):
36
60
  "Enable usage telemetry?",
37
61
  default=default_telemetry_enabled,
38
62
  key="telemetry.enable_telemetry",
63
+ help_text=(
64
+ "Enable this to send limited usage telemetry to Octopize "
65
+ "licensing/support services.\n"
66
+ "\n"
67
+ "This helps with license monitoring, support, and faster diagnosis of "
68
+ "operational issues. According to the observability documentation, only "
69
+ "metadata is sent, such as job kind, job name, and username. No user "
70
+ "data, payload content, or personal data is sent."
71
+ ),
39
72
  )
40
73
  if self.interactive
41
74
  else default_telemetry_enabled