ellf-cli 22.0.3__tar.gz → 22.0.5__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 (432) hide show
  1. {ellf_cli-22.0.3/ellf_cli.egg-info → ellf_cli-22.0.5}/PKG-INFO +1 -1
  2. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/README.md +12 -13
  3. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/__main__.py +3 -3
  4. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cli.py +40 -3
  5. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cluster_config.py +1 -13
  6. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/clusters.py +31 -6
  7. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/_helpers.py +57 -55
  8. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/deploy.py +211 -67
  9. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/init.py +37 -16
  10. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/init_values.py +77 -56
  11. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/register.py +30 -34
  12. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/start.py +28 -78
  13. ellf_cli-22.0.5/ellf_cli/commands/infra/tls.py +302 -0
  14. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf.json +62 -75
  15. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/helm.py +30 -31
  16. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/messages.py +3 -1
  17. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ty.py +2 -0
  18. ellf_cli-22.0.5/ellf_cli/version/22.0.3_2026-10-31-16-57-27_patch_e818d7fa-a4ba-4041-abdd-c6363fcc0a30 +3 -0
  19. ellf_cli-22.0.5/ellf_cli/version/22.0.4_2026-11-01-12-41-57_patch_1af4ec08-f257-4eb8-99ba-3ad69b89f4e7 +3 -0
  20. {ellf_cli-22.0.3 → ellf_cli-22.0.5/ellf_cli.egg-info}/PKG-INFO +1 -1
  21. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/SOURCES.txt +3 -0
  22. ellf_cli-22.0.5/tests/test_cluster_status.py +46 -0
  23. ellf_cli-22.0.5/tests/test_infra_deploy_registry_key.py +243 -0
  24. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_init.py +71 -5
  25. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_register.py +16 -20
  26. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_start_fixes.py +10 -14
  27. ellf_cli-22.0.5/tests/test_infra_tls.py +379 -0
  28. ellf_cli-22.0.3/ellf_cli/commands/infra/tls.py +0 -571
  29. ellf_cli-22.0.3/tests/test_infra_deploy_registry_key.py +0 -46
  30. ellf_cli-22.0.3/tests/test_infra_tls.py +0 -262
  31. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/LICENSE +0 -0
  32. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/MANIFEST.in +0 -0
  33. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/__init__.py +0 -0
  34. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/about.json +0 -0
  35. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/about.py +0 -0
  36. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/agents.py +0 -0
  37. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/appdirs.py +0 -0
  38. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/auth.py +0 -0
  39. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cloud/__init__.py +0 -0
  40. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cloud/gcp.py +0 -0
  41. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/__init__.py +0 -0
  42. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_cluster_select.py +0 -0
  43. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_org_select.py +0 -0
  44. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_project_scope.py +0 -0
  45. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_recipe_file.py +0 -0
  46. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_recipe_subcommand.py +0 -0
  47. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_state.py +0 -0
  48. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_usage.py +0 -0
  49. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/actions.py +0 -0
  50. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/agents.py +0 -0
  51. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/assets.py +0 -0
  52. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/config.py +0 -0
  53. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/datasets.py +0 -0
  54. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/__init__.py +0 -0
  55. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/cp.py +0 -0
  56. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/ls.py +0 -0
  57. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/rm.py +0 -0
  58. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/rsync.py +0 -0
  59. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/stats.py +0 -0
  60. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/general.py +0 -0
  61. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/import_export.py +0 -0
  62. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/__init__.py +0 -0
  63. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/_config_io.py +0 -0
  64. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/configure.py +0 -0
  65. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/hibernate.py +0 -0
  66. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/pause.py +0 -0
  67. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/provision.py +0 -0
  68. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/setup.py +0 -0
  69. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/terraform.py +0 -0
  70. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/jobs.py +0 -0
  71. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/mcp.py +0 -0
  72. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/packages.py +0 -0
  73. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/paths.py +0 -0
  74. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/plans.py +0 -0
  75. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/projects.py +0 -0
  76. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/publish_code.py +0 -0
  77. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/publish_data.py +0 -0
  78. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/recipes.py +0 -0
  79. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/secrets.py +0 -0
  80. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/services.py +0 -0
  81. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/sessions.py +0 -0
  82. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/support.py +0 -0
  83. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/tasks.py +0 -0
  84. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/todos.py +0 -0
  85. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/users.py +0 -0
  86. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/config.py +0 -0
  87. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/.gitignore +0 -0
  88. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/render.py +0 -0
  89. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.assistant.md +0 -0
  90. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.coding.md +0 -0
  91. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.assistant.md +0 -0
  92. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.coding.md +0 -0
  93. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_ellf_annotation_recipes.assistant.md +0 -0
  94. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_ellf_annotation_recipes.coding.md +0 -0
  95. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/builtin_prodigy_recipes.coding.md +0 -0
  96. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.assistant.md +0 -0
  97. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.coding.md +0 -0
  98. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
  99. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.assistant.md +0 -0
  100. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.assistant.md +0 -0
  101. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.coding.md +0 -0
  102. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.assistant.md +0 -0
  103. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.coding.md +0 -0
  104. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.assistant.md +0 -0
  105. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.coding.md +0 -0
  106. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/scripts.coding/check_training.py +0 -0
  107. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.assistant.md +0 -0
  108. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.coding.md +0 -0
  109. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/references.coding/data_infra_cli.md +0 -0
  110. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/scripts.coding/run_job.py +0 -0
  111. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.coding.md +0 -0
  112. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
  113. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.coding.md +0 -0
  114. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_action_recipe.py +0 -0
  115. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_agent_recipe.py +0 -0
  116. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_blocks_ui.py +0 -0
  117. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
  118. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_custom_ui.py +0 -0
  119. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
  120. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_pages_ui.py +0 -0
  121. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
  122. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_service_recipe.py +0 -0
  123. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_task_recipe.py +0 -0
  124. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
  125. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
  126. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
  127. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
  128. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
  129. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
  130. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.assistant.md +0 -0
  131. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.coding.md +0 -0
  132. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/annotation_agents.md +0 -0
  133. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/consulting_patterns.md +0 -0
  134. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/explosion_strategy.md +0 -0
  135. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/jev.coding.md +0 -0
  136. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.assistant.md +0 -0
  137. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.coding.md +0 -0
  138. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.assistant.md +0 -0
  139. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.coding.md +0 -0
  140. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/SKILL.coding.md +0 -0
  141. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/references/template_format.md +0 -0
  142. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/scripts/placeholders.py +0 -0
  143. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.coding.md +0 -0
  144. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.assistant.md +0 -0
  145. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.coding.md +0 -0
  146. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_advanced.coding.md +0 -0
  147. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_architectures.coding.md +0 -0
  148. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_training.coding.md +0 -0
  149. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/diagnostics.md +0 -0
  150. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/evaluation_guide.md +0 -0
  151. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/experiment_patterns.coding.md +0 -0
  152. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/model_selection.md +0 -0
  153. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/training_paradigms.md +0 -0
  154. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/training_troubleshooting.coding.md +0 -0
  155. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.assistant.md +0 -0
  156. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.coding.md +0 -0
  157. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/scripts.coding/ellf_logger.py +0 -0
  158. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/errors.py +0 -0
  159. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/interactivity.py +0 -0
  160. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/key_pair.py +0 -0
  161. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/main.py +0 -0
  162. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/mcp_proxy.py +0 -0
  163. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/pypi_auth.py +0 -0
  164. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/query.py +0 -0
  165. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
  166. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
  167. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
  168. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
  169. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
  170. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
  171. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
  172. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
  173. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/__init__.py +0 -0
  174. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/recipes/example_task.py +0 -0
  175. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/testing/__init__.py +0 -0
  176. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ui.py +0 -0
  177. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/url.py +0 -0
  178. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/util.py +0 -0
  179. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.114_2026-08-19-08-36-57__1a4e37c1-471e-4a81-b4d5-1ffe7dec3a61 +0 -0
  180. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.114_2026-08-19-09-25-21_patch_33ff1e26-0e5e-46d8-8052-ab1d032e8b6c +0 -0
  181. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.115_2026-08-19-09-27-13_patch_4ac728c3-0342-4a36-adbc-e28d2d99b1ba +0 -0
  182. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.116_2026-08-19-09-30-47_patch_c706fef6-6813-4183-b268-12e7b00d7d0b +0 -0
  183. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.117_2026-08-19-09-39-14_patch_c6b0495f-2f88-4aa8-9ebf-0a235b4c407e +0 -0
  184. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.118_2026-08-19-09-52-00_patch_b395655a-8d78-4344-9266-6901c20f6517 +0 -0
  185. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.119_2026-08-19-10-22-38_patch_8f95c49d-aedc-41b8-816d-ccb95f048831 +0 -0
  186. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.120_2026-08-19-10-26-58_patch_7fbf35e6-cc01-4b75-8c9a-f5d054bcaf93 +0 -0
  187. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.121_2026-08-19-10-42-02_patch_31a81b02-a886-4dea-84e0-67cc6ca412d5 +0 -0
  188. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.122_2026-08-19-11-16-49_patch_1c4d7307-48d4-493e-936d-80af799d644b +0 -0
  189. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.123_2026-08-19-11-47-32_patch_d3d78d04-9989-45b1-91b1-93b571d8814a +0 -0
  190. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.124_2026-08-20-08-03-17_patch_57f4c389-2d19-41ce-aca4-13b61c62f387 +0 -0
  191. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.125_2026-08-20-08-25-05_patch_7f368148-0d1c-4525-bbdf-c6d257ad861a +0 -0
  192. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.126_2026-08-20-14-51-36_patch_a99abcc8-3371-4c63-a759-bb7ea5b32432 +0 -0
  193. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.127_2026-08-21-05-48-58_patch_34b4ccee-7596-4f57-93e9-774973cca58e +0 -0
  194. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.128_2026-08-21-10-47-20_patch_693112b9-927c-4a8f-8553-b06eef86079d +0 -0
  195. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.129_2026-08-21-11-16-54_patch_7a981666-01d9-4d1b-9ba3-2129744e3bd5 +0 -0
  196. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.130_2026-08-21-13-09-36_patch_b7ad1a76-ce70-4d70-9d1a-7c414eba5bb4 +0 -0
  197. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.131_2026-08-21-14-31-10_patch_9128ef66-193e-4caf-8710-afd86128e638 +0 -0
  198. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.132_2026-08-24-08-59-34_patch_c600fc14-86a5-460f-9c4e-f0177056f756 +0 -0
  199. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.133_2026-08-24-10-28-29_patch_b6ce3e32-9d7b-48ac-981a-270c22c180dd +0 -0
  200. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.134_2026-08-24-11-00-51_patch_a4fc0484-4a64-46a2-94f8-aa805254c7b0 +0 -0
  201. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.135_2026-08-24-12-12-41_patch_a870a56f-9a65-49eb-92da-f572b26667d8 +0 -0
  202. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.136_2026-08-24-12-42-46_patch_9b399356-6482-4291-8da7-e748a99c4b53 +0 -0
  203. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.137_2026-08-24-12-53-57_patch_f7979348-1910-40cd-a535-90299eca84ee +0 -0
  204. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.138_2026-08-24-14-36-30_patch_ed0f8750-f663-498b-85e7-0d3f2213fcfe +0 -0
  205. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.139_2026-08-25-08-37-26_patch_3ba87e19-902b-4f76-b64c-90e5c0ca1fc6 +0 -0
  206. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.140_2026-08-25-09-52-45_patch_abc830f2-df15-4385-b797-cdaf72c10752 +0 -0
  207. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.141_2026-08-25-11-37-20_patch_1d9ec01e-06f6-4c8e-b095-af17d5b62b00 +0 -0
  208. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.142_2026-08-26-07-38-49_patch_3dd23e36-e7df-494c-986f-a412861a8d40 +0 -0
  209. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.143_2026-08-26-09-32-32_patch_7b7ebd34-de27-4b73-98a7-3e1501e16cd5 +0 -0
  210. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.144_2026-08-26-10-56-43_patch_166064f2-2208-4c9b-9e25-25dc4cd32084 +0 -0
  211. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.145_2026-08-26-11-37-29_patch_b997f3ee-d7d3-4408-9f2f-c8b6d08bdb3b +0 -0
  212. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.146_2026-08-26-12-15-20_patch_afbbb893-25db-468c-81db-2663ca373068 +0 -0
  213. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.147_2026-08-26-14-10-50_patch_fd753b1f-2fa1-4ddb-a9e7-de690da85254 +0 -0
  214. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.148_2026-08-27-09-08-35_patch_23814c0b-7f77-489c-b4a8-ceadd18146e3 +0 -0
  215. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.149_2026-08-27-09-40-17_patch_8879d72e-a3d8-4abc-a16a-d9dcf75f0fa1 +0 -0
  216. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.150_2026-08-27-10-57-25_patch_afbe60ed-3e23-4d88-be3c-f800d7002a7d +0 -0
  217. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.151_2026-08-28-09-02-46_patch_1d4ca23b-aeae-4ea8-96b1-8cf57371f29d +0 -0
  218. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.152_2026-08-28-15-37-24_patch_c9d0bdc1-a7e1-432b-92b9-92dc76fe0c78 +0 -0
  219. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.153_2026-08-29-09-03-27_patch_7531573a-1b33-4092-aa9c-0e65f47b201f +0 -0
  220. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.154_2026-08-29-11-56-35_patch_919f5787-39c8-4dc1-ae6a-f27c28380f21 +0 -0
  221. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.155_2026-08-29-15-15-59_patch_822f9ed8-c366-4e5f-9791-dee8467cf3ce +0 -0
  222. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.156_2026-08-29-16-19-01_patch_3ac2bf36-20f7-4c9f-9fdb-295d4466d59e +0 -0
  223. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.157_2026-08-30-17-32-17_patch_4302354c-c9c5-4be7-acd3-542872a748d8 +0 -0
  224. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.158_2026-08-31-09-28-33_patch_3523774f-c25d-4102-8c1a-92fff046a48d +0 -0
  225. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.159_2026-08-31-10-31-01_patch_fe3e6290-2553-4154-a0a0-8b8a418280ed +0 -0
  226. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.160_2026-08-31-11-23-39_patch_e701a085-3d23-4212-b0af-73b1d419a4c1 +0 -0
  227. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.161_2026-08-31-12-41-01_patch_074d7bde-c493-44db-bc15-e81fd91e2921 +0 -0
  228. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.162_2026-08-31-13-58-06_patch_84db1d60-4280-433b-bd3a-22e5611cd315 +0 -0
  229. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.163_2026-08-31-15-25-54_patch_1931c5ba-73df-48cb-8dcb-555ace0af267 +0 -0
  230. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.163_2026-08-31-15-44-37_patch_3962e805-2a92-494a-a87b-b6e6d66c40a0 +0 -0
  231. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.165_2026-08-31-19-48-59_patch_86e5b923-2b99-4b86-b542-469b197614be +0 -0
  232. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.166_2026-09-01-07-39-57_patch_c344892f-d542-4e7b-8f27-02365a411e15 +0 -0
  233. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.167_2026-09-01-08-21-53_patch_e199d419-282a-4dbb-8756-cf98b7037e2b +0 -0
  234. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.168_2026-09-01-09-12-31_patch_235c9fe0-da15-431d-bb56-01e2b9b15f4b +0 -0
  235. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.169_2026-09-01-11-54-19_patch_98b617ab-d130-42b5-93f2-19cae56d4c4c +0 -0
  236. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.170_2026-09-02-09-27-28_patch_e448d2e6-b7ec-4235-96bf-0173b3623c87 +0 -0
  237. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.171_2026-09-02-12-52-44_patch_e6a241c2-1d62-482c-a9eb-9e3373395c50 +0 -0
  238. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.172_2026-09-04-08-47-04_patch_daae079f-c104-4fcd-bb57-7bff68e80ad9 +0 -0
  239. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.173_2026-09-04-12-34-42_patch_399c4cbd-0c28-4dfd-a4ec-e569420a36e4 +0 -0
  240. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.174_2026-09-04-13-08-48_patch_f5cfe3d5-808e-45e4-bafc-00d0554838ee +0 -0
  241. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.175_2026-09-04-17-20-46_patch_1ef542fa-5d8e-4d90-aa15-9fc4cea3dfec +0 -0
  242. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.176_2026-09-05-08-25-05_patch_ced5521f-f9da-4640-a921-95fcb5cd2e6d +0 -0
  243. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.177_2026-09-05-09-00-16_patch_803c1ad4-a9af-4953-92c5-d882dec03ea2 +0 -0
  244. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.178_2026-09-05-09-30-34_patch_012f6259-2e3f-4591-9806-1920fd06cb1f +0 -0
  245. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.179_2026-09-05-09-33-43_patch_f4bdf28c-d584-47a5-b699-8c883330162c +0 -0
  246. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.180_2026-09-05-12-02-21_patch_34a14b01-d22d-44a8-ac63-be0370a61422 +0 -0
  247. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.181_2026-09-05-12-47-46_patch_56b18867-99f6-4d5c-8215-7b9d60d34010 +0 -0
  248. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.182_2026-09-05-13-35-18_patch_61b7d4d1-73c8-4603-9b0c-593e7405587f +0 -0
  249. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.183_2026-09-06-07-27-09_patch_d76331b2-e3a3-4c0b-8412-ecd131b6ac02 +0 -0
  250. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.184_2026-09-06-10-21-47_patch_7680b7a1-49f0-4eef-b12e-4c854407448c +0 -0
  251. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.185_2026-09-06-10-30-40_patch_e56c2183-77f8-44ef-a92e-7377ea6ce8c1 +0 -0
  252. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.186_2026-09-07-10-00-51_patch_67de5683-d208-4bc0-8fb6-7677377908e7 +0 -0
  253. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.187_2026-09-07-10-18-13_patch_2086cee2-276b-48f7-80ce-6a17397b9541 +0 -0
  254. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.188_2026-09-07-12-51-28_patch_d6590822-068f-4a19-814d-34bbf204ba6e +0 -0
  255. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.189_2026-09-07-12-55-23_patch_7e0fb04b-4d40-4490-974f-c74ba2ae55a1 +0 -0
  256. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.190_2026-09-08-08-58-03_patch_15e3ac1e-4475-4272-bdd8-d00bb0db8f17 +0 -0
  257. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.191_2026-09-08-09-55-58_patch_3d350e50-ee53-4282-bc75-d2251142c46e +0 -0
  258. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.192_2026-09-08-11-12-21_patch_0733223b-1ae2-4b5b-897f-dfc57574ff83 +0 -0
  259. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.193_2026-09-08-21-48-17_patch_8d07d4e6-3555-4720-85c9-9452570fae2d +0 -0
  260. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.194_2026-09-09-07-53-43_patch_69559429-aa42-4b62-9bd7-cdfded1c00d0 +0 -0
  261. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.195_2026-09-09-09-55-40_patch_bbf67f1d-3b9a-43a2-b1bc-22df3fed8a34 +0 -0
  262. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.196_2026-09-09-09-59-47_patch_70d76812-7b3c-4192-ad49-fcaccc29b0da +0 -0
  263. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.197_2026-09-09-13-06-06_patch_d455be0b-5421-492a-b952-fab0fd8110f8 +0 -0
  264. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.198_2026-09-09-13-14-34_patch_267f54e5-311e-435e-882f-8e19191325ea +0 -0
  265. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.199_2026-09-09-22-24-18_patch_81e3e453-ca0e-42fa-9c21-8f94d43c05f2 +0 -0
  266. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.200_2026-09-10-07-19-50_patch_911714fa-1fa3-4165-bfe6-d10c650bf5bf +0 -0
  267. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.201_2026-09-10-10-14-19_patch_864015f2-b0b0-4563-a1c8-155629cb9126 +0 -0
  268. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.202_2026-09-10-11-00-05_patch_18270ecf-e770-4e69-8bcf-e5143c39929b +0 -0
  269. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.203_2026-09-10-11-10-41_patch_ff273ab1-44f3-4bc0-b184-3396e943df04 +0 -0
  270. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.204_2026-09-10-13-02-02_patch_d4ee41e2-d13c-4941-8605-3f1a42b56b22 +0 -0
  271. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.205_2026-09-10-13-57-50_patch_284df67e-5957-4b0c-bc64-5581db6ddecc +0 -0
  272. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.206_2026-09-11-10-18-50_patch_1ac7e410-0e62-4eef-bbe4-ebf93c9d0869 +0 -0
  273. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/17.0.207_2026-09-11-15-26-02_major_3f1b3ed7-eaac-41f5-b740-0af3331595d9 +0 -0
  274. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.0_2026-09-12-10-01-10_patch_8995783a-a9fa-4c4e-90b3-6386a4c481eb +0 -0
  275. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.10_2026-09-14-16-09-38_patch_9403d562-eed0-4125-a8b3-09cd92a13298 +0 -0
  276. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.11_2026-09-15-09-05-57_patch_8b22dba2-d931-4c4d-ae60-db3238d5e73d +0 -0
  277. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.12_2026-09-15-11-18-52_patch_81314afa-e70d-4ad8-b45b-3f8d62b983e7 +0 -0
  278. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.13_2026-09-16-08-00-55_patch_bfa30fc0-3281-4de6-bb56-d7290c98d1c3 +0 -0
  279. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.14_2026-09-16-14-38-26_patch_aae6e9b0-88f4-4bcf-b611-3308c7fcd6eb +0 -0
  280. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.15_2026-09-17-07-58-54_patch_43d40582-effd-4925-a8bd-e70fecf1faab +0 -0
  281. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.16_2026-09-17-08-12-37_patch_b4db2d23-88f1-45c1-82d9-78d38014fcb6 +0 -0
  282. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.17_2026-09-18-09-38-19_patch_25697fc3-e9a8-4980-962b-e6cb0a4760c5 +0 -0
  283. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.18_2026-09-18-09-54-33_patch_d37d9c71-c469-4d94-90d7-4898915ee991 +0 -0
  284. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.19_2026-09-18-10-47-33_patch_47607b3c-d1b6-4864-b9b0-00a2a8d2ac32 +0 -0
  285. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.1_2026-09-12-17-33-30_patch_f6ea2c99-a715-4c4d-876a-23ed8c62a83d +0 -0
  286. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.20_2026-09-18-11-07-21_patch_5a336f91-63a6-4877-97ed-da89395cc8f5 +0 -0
  287. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.21_2026-09-18-13-34-52_patch_c56462e1-63d9-498f-a912-c80c5f0171d1 +0 -0
  288. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.22_2026-09-20-08-10-45_patch_6afa2c20-bcef-4b7d-8685-2c9815d8683f +0 -0
  289. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.23_2026-09-20-08-38-35_patch_a7f169e5-37ab-4ec0-bf89-d14770181303 +0 -0
  290. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.24_2026-09-20-15-49-27_patch_c1222081-ff44-4f20-aea2-5840b6d76efd +0 -0
  291. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.25_2026-09-21-06-11-40_patch_6df46dd9-e7d3-4e71-bec4-e5c93b4ac863 +0 -0
  292. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.26_2026-09-21-07-54-11_patch_cc52dd36-5eba-4094-a1b0-d6f79f103441 +0 -0
  293. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.27_2026-09-21-08-36-49_patch_a25fa125-9bcd-4317-8da5-851c1c329631 +0 -0
  294. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.28_2026-09-21-09-44-01_patch_4430a721-0b3c-4f6a-b9bc-a53e667161bb +0 -0
  295. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.29_2026-09-21-10-58-07_patch_83b2b942-60a4-4bef-afd1-99690ba52b69 +0 -0
  296. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.2_2026-09-13-06-36-33_patch_176bb944-1c49-4dd3-a001-8fce908825a0 +0 -0
  297. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.30_2026-09-21-12-51-16_patch_519b9a65-d400-4234-b113-36b46e315507 +0 -0
  298. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.31_2026-09-22-06-53-35_patch_5c45a235-81b6-4d05-801a-07dc7db61400 +0 -0
  299. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.32_2026-09-22-07-42-04_patch_f12c6415-8166-4063-9e5d-26601b929d63 +0 -0
  300. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.33_2026-09-22-08-12-32_patch_cec31bb0-a6cb-43e6-8407-25aba322b54c +0 -0
  301. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.34_2026-09-23-07-09-16_patch_659fccbb-c0a0-4f6f-bc87-e6abaa8815a7 +0 -0
  302. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.35_2026-09-23-09-38-52_patch_023f904d-807a-4833-8a40-570365e8ec06 +0 -0
  303. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.36_2026-09-23-10-05-33_patch_846fb491-2b1b-47ed-ac1f-ba40e744e199 +0 -0
  304. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.37_2026-09-23-13-08-30_patch_8e4b1d24-156e-4ffe-8e4a-b8740ec18588 +0 -0
  305. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.38_2026-09-24-06-41-37_patch_67adb1d6-3f49-4357-a67f-b1d48f23a972 +0 -0
  306. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.39_2026-09-24-15-24-32_patch_e5dd375d-5643-4514-9b65-8d877c4a2bb2 +0 -0
  307. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.3_2026-09-13-12-32-46_patch_58e5ce3a-f2a7-4789-b2cd-5cc75c72b6ec +0 -0
  308. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.40_2026-09-24-19-58-14_patch_ff18824b-be51-4a3d-a621-e96279e53c3e +0 -0
  309. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.41_2026-09-26-09-24-52_patch_b9979267-30f9-440a-a4ce-c611991d4886 +0 -0
  310. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.42_2026-09-28-12-39-34_patch_dda535d9-8922-4eb9-ab51-6ecff0650c10 +0 -0
  311. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.43_2026-09-28-13-35-27_minor_aca1168a-1286-4326-9d0c-2f2587c9fe92 +0 -0
  312. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.4_2026-09-13-12-45-14_patch_b6c79d55-8f85-4f47-a304-df52b122c38c +0 -0
  313. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.5_2026-09-13-14-11-18_patch_9b111116-5e62-472a-b72c-d1bbafa22c97 +0 -0
  314. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.5_2026-09-13-17-01-11_patch_d4bf61c0-83ac-4dd3-b512-a65805d298c8 +0 -0
  315. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.6_2026-09-14-11-31-04_patch_fd2ebda6-22cb-4e7d-9452-2f6f2640e828 +0 -0
  316. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.7_2026-09-13-17-06-08_patch_428af161-0b27-43c2-8751-e5f7874df120 +0 -0
  317. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.0.9_2026-09-14-12-37-42_patch_b2ca0529-4b67-4fa4-8fdc-5f5e9f5d5166 +0 -0
  318. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.1.0_2026-09-28-14-27-54_patch_324444f7-d24e-4189-b21f-1188894a3109 +0 -0
  319. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/18.1.1_2026-09-28-21-03-07_major_e266a14a-7d96-4ece-92a3-8f34e64438a5 +0 -0
  320. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.0_2026-09-29-11-05-31_patch_77d6f9f8-ead3-4d79-a4b2-b084b2dffc98 +0 -0
  321. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.10_2026-10-02-12-56-52_patch_14e97576-73ca-44b8-82c9-7dad6f1789ab +0 -0
  322. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.11_2026-10-04-10-31-19_patch_088eb371-1799-4949-a119-286cf1cd55d1 +0 -0
  323. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.12_2026-10-06-18-00-25_patch_36554bed-49c5-41cb-9fd4-48cc6af74c09 +0 -0
  324. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.13_2026-10-07-12-24-08_patch_a540a364-3a0d-4960-b278-06ba2c7cc258 +0 -0
  325. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.14_2026-10-07-12-52-39_patch_e3a6fc5c-2ee4-414c-a2dd-4910a655a7dd +0 -0
  326. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.15_2026-10-09-04-15-56_patch_bd7a9b06-867b-4fea-9678-973a05e3022d +0 -0
  327. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.16_2026-10-09-16-11-56_patch_a1135435-7dea-4f00-8c98-203ba3974382 +0 -0
  328. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.17_2026-10-09-17-44-55_patch_faeacad8-541a-40f2-ab9c-abcd66fcd00e +0 -0
  329. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.18_2026-10-10-07-29-38_major_02601a1e-9bdb-45bf-ad67-a07b7dcd0002 +0 -0
  330. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.1_2026-09-29-11-59-38_patch_bbf4753c-d641-4c2f-ac7c-02be6bd8e7c2 +0 -0
  331. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.2_2026-09-29-12-44-07_patch_19fdaa94-60dc-464b-93b8-c17607ebc7b6 +0 -0
  332. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.3_2026-09-29-14-16-00_patch_3cb60272-95cf-4311-8897-721e1b5c2c88 +0 -0
  333. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.4_2026-09-29-16-24-53_patch_9fe8ad2b-e3ec-4558-a5fc-9c44c5c266dc +0 -0
  334. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.5_2026-09-29-17-13-16_patch_e48d2dd2-f41a-402e-a441-756b23c01dcb +0 -0
  335. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.6_2026-09-29-17-22-11_patch_3b1c79e9-9002-4e96-ba78-10668c33be6a +0 -0
  336. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.7_2026-09-30-07-50-58_patch_e8b1f046-d819-499c-9cd5-3e1a20fc9acf +0 -0
  337. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.8_2026-10-01-13-41-44_patch_7d63af18-e0af-4127-ab58-aede2407490f +0 -0
  338. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/19.0.9_2026-10-01-15-57-35_patch_143863cb-8f63-4ef7-bd78-c1114fc93a2d +0 -0
  339. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.0_2026-10-10-09-36-17_patch_d2618f39-cdc9-4d3a-ba40-1a0ad6265f3b +0 -0
  340. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.1_2026-10-11-10-24-33_patch_e29a8713-eecb-4eb1-9641-789d3cfab21a +0 -0
  341. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.2_2026-10-12-07-22-24_patch_f4053ad1-8fcd-4591-a68d-bf1e23485ba7 +0 -0
  342. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.3_2026-10-14-14-29-16_patch_070af1c4-f9d9-4f97-8112-058de90d3ea8 +0 -0
  343. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.4_2026-10-14-16-20-24_patch_c6672844-8227-4e0a-9fb5-36af7e7141dc +0 -0
  344. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.5_2026-10-15-08-53-28_patch_10154146-8afd-4632-b250-9b4b9f5bf67c +0 -0
  345. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.6_2026-10-15-14-17-40_patch_df3a5d3c-f0e0-46cb-aeaf-15b51c8a0f13 +0 -0
  346. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/20.0.7_2026-10-16-07-09-40_major_3e5dfba3-2810-47b4-85a9-938bfff72a04 +0 -0
  347. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.0_2026-10-16-10-44-29_patch_1058e453-613f-492b-a3c7-f3ca2abe8c2d +0 -0
  348. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.10_2026-10-30-14-29-34_major_4fd535f6-6e41-4f34-b29c-543e1a9bac51 +0 -0
  349. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.1_2026-10-16-16-06-10_patch_e20b4ad2-b87f-478e-b4f4-323c8bcc5ea9 +0 -0
  350. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.2_2026-10-19-13-54-31_patch_bf091df4-00bb-43c8-9117-51047944e305 +0 -0
  351. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.3_2026-10-19-14-58-29_patch_9b985381-1b1d-4531-b242-b02cea2484c5 +0 -0
  352. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.4_2026-10-20-17-08-51_patch_38d02583-cb5c-4adc-b5d7-614b483acf19 +0 -0
  353. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.5_2026-10-21-09-28-47_patch_fabd5cfe-2d04-4215-abf1-58fba226acb7 +0 -0
  354. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.6_2026-10-22-16-07-37_patch_d2bb27d7-6304-4c99-abbc-46d3dd7e363b +0 -0
  355. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.7_2026-10-27-11-41-55_patch_6b50567f-209d-42c9-a2cd-d251a2bc8fbf +0 -0
  356. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.8_2026-10-29-13-48-18_patch_bdab3ee6-fba8-4625-9243-c4cbe839ba32 +0 -0
  357. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/21.0.9_2026-10-29-17-51-00_patch_803a4c70-2e2b-4024-8598-c7d91c9db0d2 +0 -0
  358. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/22.0.0_2026-10-30-15-25-42_patch_1f39caf4-aadc-4d26-9124-a854d945b32a +0 -0
  359. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/22.0.1_2026-10-30-17-30-37_patch_4a6e6cfb-d86e-4f1e-84c5-02d4c071f75b +0 -0
  360. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/22.0.2_2026-10-31-11-13-43_patch_54d644d8-cebd-4b6a-ba8f-685e2ffee481 +0 -0
  361. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/__init__.py +0 -0
  362. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/read_version.py +0 -0
  363. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/dependency_links.txt +0 -0
  364. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/entry_points.txt +0 -0
  365. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/not-zip-safe +0 -0
  366. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/requires.txt +0 -0
  367. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/top_level.txt +0 -0
  368. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/pyproject.toml +0 -0
  369. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/setup.cfg +0 -0
  370. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/setup.py +0 -0
  371. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_agents.py +0 -0
  372. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_agents_info_stats.py +0 -0
  373. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_appdirs.py +0 -0
  374. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_auth.py +0 -0
  375. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_clusters_info_stats.py +0 -0
  376. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_config.py +0 -0
  377. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_datasets_export.py +0 -0
  378. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_errors.py +0 -0
  379. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_files_cp.py +0 -0
  380. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_files_cp_helpers.py +0 -0
  381. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_helm.py +0 -0
  382. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_import_export.py +0 -0
  383. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_info.py +0 -0
  384. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_config_io.py +0 -0
  385. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_configure.py +0 -0
  386. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_deploy_node_labels.py +0 -0
  387. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_deploy_preflight.py +0 -0
  388. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_destroy.py +0 -0
  389. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_get_terraform.py +0 -0
  390. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_hibernate.py +0 -0
  391. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_pause.py +0 -0
  392. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_provision.py +0 -0
  393. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_start_validation.py +0 -0
  394. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_state_bucket.py +0 -0
  395. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_terraform_init.py +0 -0
  396. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_invalid_secrets.py +0 -0
  397. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_job_list_project_filter.py +0 -0
  398. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_jobs_info_hides_creator.py +0 -0
  399. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_jobs_list_unmatched.py +0 -0
  400. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_key_pair.py +0 -0
  401. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_login.py +0 -0
  402. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_logout.py +0 -0
  403. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_main.py +0 -0
  404. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_mcp_proxy.py +0 -0
  405. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_org_select.py +0 -0
  406. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_plans.py +0 -0
  407. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_projects.py +0 -0
  408. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_projects_delete_confirm.py +0 -0
  409. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_build_poll.py +0 -0
  410. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_data.py +0 -0
  411. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_import_root.py +0 -0
  412. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_requirements.py +0 -0
  413. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_versions.py +0 -0
  414. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_pypi_auth.py +0 -0
  415. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_query.py +0 -0
  416. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_file.py +0 -0
  417. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_help.py +0 -0
  418. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_required_args.py +0 -0
  419. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipes.py +0 -0
  420. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipes_init.py +0 -0
  421. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_sessions.py +0 -0
  422. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_state.py +0 -0
  423. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_support.py +0 -0
  424. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_todos.py +0 -0
  425. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ty.py +0 -0
  426. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ui.py +0 -0
  427. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ui_extras.py +0 -0
  428. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_usage_counts.py +0 -0
  429. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_assign.py +0 -0
  430. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_info_stats.py +0 -0
  431. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_list.py +0 -0
  432. {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ellf-cli
3
- Version: 22.0.3
3
+ Version: 22.0.5
4
4
  Summary: Ellf Command Line Interface
5
5
  Home-page: https://prodi.gy
6
6
  Author: ExplosionAI GmbH
@@ -358,7 +358,7 @@ Get detailed info for a cluster
358
358
  | Argument | Type | Description | Default |
359
359
  | --- | --- | --- | --- |
360
360
  | `name_or_id` | `Union[str, UUID]` | Name or ID of the cluster | |
361
- | `--select` | `list[str]` | Comma-separated fields to select and show in output. Available: ['id', 'created', 'updated', 'org_id', 'name', 'address', 'state', 'cloud_provider', 'cloud', 'managed_subdomain', 'gcp_project', 'is_hosted'] | `None` |
361
+ | `--select` | `list[str]` | Comma-separated fields to select and show in output. Available: ['id', 'created', 'updated', 'org_id', 'name', 'address', 'state', 'cloud_provider', 'cloud', 'managed_subdomain', 'gcp_project', 'is_hosted', 'ca_certificate'] | `None` |
362
362
  | `--json` | `bool` | Output the result as JSON | `False` |
363
363
 
364
364
  #### `ellf clusters update`
@@ -659,14 +659,14 @@ Deploy and manage cluster infrastructure (Kubernetes, TLS, Terraform)
659
659
 
660
660
  #### `ellf infra register`
661
661
 
662
- Register a new cluster with PAM and write credentials to cluster-creds.json. Pass --domain to use your own DNS, or omit it to be allocated a managed subdomain (with base + wildcard A records) under an Explosion-controlled zone. An org on the free Solo plan has no managed subdomain: omitting --domain registers it at http://localhost.
662
+ Register a new cluster with PAM. Pass --domain to use your own DNS, or omit it to be allocated a managed subdomain (with an A record) under an Explosion-controlled zone. An org on the free Solo plan has no managed subdomain: omitting --domain registers it at http://localhost.
663
663
 
664
664
  | Argument | Type | Description | Default |
665
665
  | --- | --- | --- | --- |
666
666
  | `--name` | `str` | Human-readable name for the cluster | |
667
- | `--domain` | `str` | Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'http://localhost' for a cluster on this machine, which needs no certificate and is what the free Solo plan uses by default; Safari can't reach it there, so for Safari use 'https://localhost[:port]', see 'ellf infra tls'). Stored verbatim as the cluster address; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. | `None` |
667
+ | `--domain` | `str` | Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com' for a hosted cluster on port 443, or 'http://localhost' for a cluster on this machine, which needs no certificate and is what the free Solo plan uses by default; Safari can't reach it there, so for Safari use 'https://localhost[:port]', and to reach it from other devices 'https://<its IP address on your network>'; Ellf issues those a certificate, see 'ellf infra tls'). Stored as the cluster address without its scheme, which is https unless you give http://; the chart derives the bare hostname for K8s ingress / cert SAN where a port isn't allowed. Omit to get a managed subdomain under an Explosion-controlled zone. | `None` |
668
668
  | `--subdomain` | `str` | Requested label for a managed subdomain (e.g. 'acme' for acme.<zone>). Only valid without --domain; defaults to a slug derived from your org/cluster name. | `None` |
669
- | `--public-ip` | `str` | Cluster ingress IP to point the managed subdomain at. Omit to reserve the name now and re-run with --public-ip once the load balancer IP is known. | `None` |
669
+ | `--public-ip` | `str` | Cluster ingress IP to point the managed subdomain at: a public IPv4 address. Omit to reserve the name now and re-run with --public-ip once the load balancer IP is known. A cluster on a private network uses --domain with your own DNS instead. | `None` |
670
670
  | `--cloud-provider` | `str` | Cloud provider: gcp, k3s, aws, azure | |
671
671
  | `--gcp-project` | `str` | GCP project the cluster is billed under. Recorded on the cluster record as the precondition for cloud-cost collection (see docs/drafts/cloud-costs.md). Re-running register updates it. | `None` |
672
672
  | `--hosted` | `bool` | Mark the cluster as Explosion-hosted. Hosted clusters get their metered cloud costs charged back with a margin — Explosion-operators only, not for BYO clusters. | `False` |
@@ -722,14 +722,13 @@ Destroy the cluster infrastructure created by 'infra terraform', including every
722
722
 
723
723
  #### `ellf infra tls`
724
724
 
725
- Serve a cluster on this machine at https://localhost. Only Safari needs this: it blocks Ellf from calling a cluster at http://localhost, which every other browser allows. Register and deploy the cluster at https://localhost (or https://localhost:<port>) and 'infra deploy' issues its certificate from a CA the CLI keeps, which can only sign for localhost. Then trust that CA once with --trust. Run on the machine the cluster runs on, with kubectl pointed at it.
725
+ Trust the certificate Ellf issues a cluster on localhost or a private network. Such a cluster is served over https with a certificate from a CA Ellf keeps for it, which can only certify the cluster's own address. Run this with --trust on each device you open Ellf on, once. It needs only your Ellf login, not kubectl.
726
726
 
727
727
  | Argument | Type | Description | Default |
728
728
  | --- | --- | --- | --- |
729
- | `--self-signed` | `bool` | Issue the cluster a certificate from the localhost-only CA | `False` |
730
- | `--trust` | `bool` | Print the commands to trust the localhost-only CA | `False` |
731
- | `--status` | `bool` | Show the cluster's TLS setup | `False` |
732
- | `--namespace` | `str` | Kubernetes namespace | `'ellf'` |
729
+ | `--trust` | `bool` | Fetch the cluster's certificate authority from Ellf and print the commands to trust it on this device | `False` |
730
+ | `--status` | `bool` | Show the certificate authority Ellf keeps for the cluster | `False` |
731
+ | `--cluster` | `str` | Name or ID of the cluster (default: the current one) | `None` |
733
732
  | `--output` | `str` | Output format for trust commands: human, json, shell | `'human'` |
734
733
 
735
734
  #### `ellf infra init`
@@ -844,15 +843,16 @@ Recreate a cluster hibernated with 'ellf infra hibernate'. Starts the database,
844
843
 
845
844
  #### `ellf infra init-values`
846
845
 
847
- Generate a values.yaml for Helm deployment from credentials and provider defaults.
846
+ Generate a values.yaml for Helm deployment of a registered cluster. The file holds no secrets, so it's safe to keep with the rest of your configuration: 'infra deploy' hands the cluster its registry and licence keys from PAM, and keeps its database password in the cluster.
848
847
 
849
848
  | Argument | Type | Description | Default |
850
849
  | --- | --- | --- | --- |
851
- | `--creds` | `Path` | Path to cluster-creds.json from 'infra register' | |
852
850
  | `--cloud-provider` | `str` | Cloud provider: gcp, k3s, aws, azure | |
853
- | `--domain` | `str` | Public address the cluster is reached on, host or host:port (e.g. 'cluster.example.com'). Use 'http://localhost' for a cluster on this machine, which needs no certificate and works in every browser but Safari; 'https://localhost[:port]' serves it with a certificate from a localhost-only CA the CLI keeps, for Safari (see 'ellf infra tls'). Match what was passed to 'infra register' — it flows into ELLF_BROKER_HOST so the cluster emits matching OIDC / token URLs. | |
851
+ | `--cluster` | `str` | Name or ID of the registered cluster (default: the one 'infra register' registered last) | `None` |
852
+ | `--domain` | `str` | Public address the cluster is reached on, host or host:port (default: the address it was registered at). Use 'http://localhost' for a cluster on this machine, which needs no certificate and works in every browser but Safari. 'https://localhost[:port]', or https at an IP address on a private network (for other devices to reach), is served with a certificate Ellf issues the cluster, which each device trusts once (see 'ellf infra tls'). It flows into ELLF_BROKER_HOST so the cluster emits matching OIDC / token URLs. | `None` |
854
853
  | `--out` | `Path` | Output path for generated values.yaml | `'values.yaml'` |
855
854
  | `--acme-email` | `str` | Email for Let's Encrypt certificates | `None` |
855
+ | `--tls-secret-name` | `str` | Serve the cluster with a certificate you provide: the name of a kubernetes.io/tls Secret in the cluster's namespace, made however you like (your own cert-manager issuer, a company CA, by hand). For a cluster on a private network or at an IP address, which Let's Encrypt can't certify. | `None` |
856
856
 
857
857
  #### `ellf infra provision`
858
858
 
@@ -886,7 +886,6 @@ Start a cluster on infrastructure configured under your own cloud account.
886
886
  | `src` | `Path` | Path to cluster definition files | `'.'` |
887
887
  | `config_path` | `Path` | Path to config yaml | `None` |
888
888
  | `--config-key` | `str` | Top-level key for the cluster config. | `None` |
889
- | `--offline` | `Path` | Path to a credentials JSON file. Deploys without connecting to PAM. | `None` |
890
889
 
891
890
  ### `ellf jobs`
892
891
 
@@ -7,9 +7,9 @@ import truststore
7
7
  # Use the OS native trust store (macOS Keychain, /etc/ssl/certs on Linux,
8
8
  # Windows certificate store) for every httpx/urllib/requests call this
9
9
  # CLI makes — instead of httpx's default certifi bundle — so a CA the
10
- # machine already trusts (a corporate proxy's, a dev stack's, or the
11
- # localhost CA from `ellf infra tls`) is trusted by the browser, curl and
12
- # the CLI alike, with no SSL_CERT_FILE or separate bundle to maintain.
10
+ # machine already trusts (a corporate proxy's, a dev stack's, or a cluster's
11
+ # CA trusted with `ellf infra tls --trust`) is trusted by the browser, curl
12
+ # and the CLI alike, with no SSL_CERT_FILE or separate bundle to maintain.
13
13
  # Must run before any code constructs an ssl.SSLContext, so it sits at
14
14
  # module top.
15
15
  truststore.inject_into_ssl()
@@ -1,11 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import dataclasses
3
4
  import json
4
5
  import sys
5
6
  from pathlib import Path
6
- from typing import Any
7
+ from typing import Any, Callable, TypeVar
7
8
 
8
- from radicli import Radicli, get_list_converter
9
+ from radicli import Arg, Command, Radicli, get_list_converter
10
+ from radicli.util import DEFAULT_PLACEHOLDER, ArgparseArg
9
11
  from wasabi import msg
10
12
 
11
13
  from ellf_broker_sdk.errors import BrokerError
@@ -18,6 +20,8 @@ from .messages import Messages
18
20
 
19
21
  HELP = """Ellf Command Line Interface."""
20
22
 
23
+ _F = TypeVar("_F", bound=Callable[..., Any])
24
+
21
25
 
22
26
  def _emit_error(title: str, detail: str | None = None) -> int:
23
27
  if not isatty(sys.stderr):
@@ -95,7 +99,40 @@ ERRORS = {
95
99
  }
96
100
 
97
101
 
98
- cli = Radicli(
102
+ class _Radicli(Radicli):
103
+ """Radicli that says which options are required in their help.
104
+
105
+ radicli checks required options itself rather than through argparse,
106
+ which would trip over subcommands, so argparse's usage line shows every
107
+ option in brackets, as if optional. Marked when the command registers,
108
+ so the static ellf.json the CLI runs from carries it too.
109
+ """
110
+
111
+ def _command(
112
+ self,
113
+ name: str,
114
+ args: dict[str, Arg],
115
+ registry: dict[str, Command],
116
+ **kwargs: Any,
117
+ ) -> Callable[[_F], _F]:
118
+ register = super()._command(name, args, registry, **kwargs)
119
+
120
+ def cli_wrapper(cli_func: _F) -> _F:
121
+ register(cli_func)
122
+ command = registry[name]
123
+ command.args = [_mark_required(arg) for arg in command.args]
124
+ return cli_func
125
+
126
+ return cli_wrapper
127
+
128
+
129
+ def _mark_required(arg: ArgparseArg) -> ArgparseArg:
130
+ if not arg.arg.option or arg.default is not DEFAULT_PLACEHOLDER:
131
+ return arg
132
+ return dataclasses.replace(arg, help=f"{arg.help or ''} (required)".lstrip())
133
+
134
+
135
+ cli = _Radicli(
99
136
  prog=about.__prog__,
100
137
  help=HELP,
101
138
  version=about.__version__,
@@ -1,9 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- import json
4
- import tempfile
5
- from contextlib import contextmanager
6
- from typing import Annotated, Iterator, Literal
3
+ from typing import Annotated, Literal
7
4
 
8
5
  from pydantic import AliasChoices, BaseModel, Field, model_validator
9
6
 
@@ -249,14 +246,5 @@ class ClusterConfigOverrides(BaseModel):
249
246
  node_pools: list[NodePool] | None = None
250
247
  default_worker_type: str | None = None
251
248
 
252
- @contextmanager
253
- def write_to_temp(self) -> Iterator[str]:
254
- """Write override values to a temp JSON file, yielding its path."""
255
- data = self.model_dump(by_alias=True, exclude_none=True)
256
- with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=True) as tmp:
257
- tmp.write(json.dumps(data, indent=2))
258
- tmp.flush()
259
- yield tmp.name
260
-
261
249
 
262
250
  _check_overrides_match(ClusterConfig, ClusterConfigOverrides)
@@ -1,6 +1,7 @@
1
1
  import base64
2
2
  import builtins
3
3
  import json
4
+ import ssl
4
5
  import subprocess
5
6
  import time
6
7
  import uuid
@@ -49,6 +50,24 @@ DEFAULT_NAMESPACE = "ellf"
49
50
  DEFAULT_RELEASE = "ellf"
50
51
 
51
52
 
53
+ def is_untrusted_certificate(exc: BaseException) -> bool:
54
+ """Whether a connection failed because this device doesn't trust the
55
+ cluster's certificate, rather than because nothing answered.
56
+
57
+ That's how a cluster served with a certificate Ellf issues it (on
58
+ localhost or a private network) looks until 'ellf infra tls --trust'.
59
+ httpx reports it as a ConnectError, with the SSL error in its chain.
60
+ """
61
+ seen: set[int] = set()
62
+ current: Optional[BaseException] = exc
63
+ while current is not None and id(current) not in seen:
64
+ if isinstance(current, ssl.SSLCertVerificationError):
65
+ return True
66
+ seen.add(id(current))
67
+ current = current.__cause__ or current.__context__
68
+ return "CERTIFICATE_VERIFY_FAILED" in str(exc)
69
+
70
+
52
71
  def check_cluster_status(
53
72
  cluster: ellf_pam_sdk_models.ClusterSummary,
54
73
  ) -> ClusterStatusCheck:
@@ -68,7 +87,9 @@ def check_cluster_status(
68
87
  return ClusterStatusCheck.ISSUES
69
88
  except InvalidURL:
70
89
  return ClusterStatusCheck.INVALID_ADDRESS
71
- except (ConnectTimeout, ConnectError):
90
+ except (ConnectTimeout, ConnectError) as e:
91
+ if is_untrusted_certificate(e):
92
+ return ClusterStatusCheck.UNTRUSTED_CERTIFICATE
72
93
  # This could mean the cluster is down, but could also mean we have no network access
73
94
  return ClusterStatusCheck.NOT_FOUND
74
95
  except RequestError as e:
@@ -312,13 +333,12 @@ def _check_result(
312
333
  label: str, ok: bool, detail: str = "", *, quiet: bool = False
313
334
  ) -> tuple[str, bool, str]:
314
335
  """Print a check result line (unless quiet) and return (label, ok, detail)."""
315
- symbol = "\u2714" if ok else "\u2718"
316
336
  suffix = f" ({detail})" if detail else ""
317
337
  if not quiet:
318
338
  if ok:
319
- msg.good(f"{symbol} {label}{suffix}")
339
+ msg.good(f"{label}{suffix}")
320
340
  else:
321
- msg.fail(f"{symbol} {label}{suffix}")
341
+ msg.fail(f"{label}{suffix}")
322
342
  return (label, ok, detail)
323
343
 
324
344
 
@@ -387,12 +407,17 @@ def check(
387
407
  quiet=as_json,
388
408
  )
389
409
  )
390
- except (httpx.ConnectError, httpx.ConnectTimeout):
410
+ except (httpx.ConnectError, httpx.ConnectTimeout) as exc:
391
411
  results.append(
392
412
  _check_result(
393
413
  f"Cluster API responding on {broker_url}",
394
414
  False,
395
- detail="connection failed",
415
+ detail=(
416
+ "this device doesn't trust the cluster's certificate: "
417
+ "run 'ellf infra tls --trust'"
418
+ if is_untrusted_certificate(exc)
419
+ else "connection failed"
420
+ ),
396
421
  quiet=as_json,
397
422
  )
398
423
  )
@@ -2,13 +2,14 @@
2
2
 
3
3
  import base64
4
4
  import json
5
+ import os
5
6
  import subprocess
6
7
  import tempfile
8
+ from contextlib import contextmanager
7
9
  from pathlib import Path
8
- from typing import TYPE_CHECKING, Annotated
10
+ from typing import TYPE_CHECKING, ContextManager, Iterator, Optional
9
11
  from uuid import UUID
10
12
 
11
- from pydantic import AliasChoices, BaseModel, Field, StringConstraints
12
13
  from wasabi import msg
13
14
 
14
15
  from ellf_pam_sdk import Client
@@ -17,32 +18,6 @@ from ellf_pam_sdk.models import ClusterCredentials, ClusterDetail
17
18
  if TYPE_CHECKING:
18
19
  from ...cluster_config import ClusterConfig
19
20
 
20
- # Matches pam/ellf_pam/config.py's NonEmptyStr convention.
21
- NonEmptyStr = Annotated[str, StringConstraints(min_length=1)]
22
-
23
-
24
- class ClusterCredsFile(BaseModel):
25
- """Schema for cluster-creds.json, written by `infra register` and read by
26
- `infra init-values` and `infra start --offline`.
27
-
28
- cluster_id/upstream_registry are required — nothing downstream can work
29
- without them. The rest are legitimately blank on a fresh cluster PAM
30
- hasn't released anything to yet (callers warn, not fail, on those).
31
- """
32
-
33
- cluster_id: NonEmptyStr
34
- # The upstream Ellf registry the cluster pulls release images from.
35
- # Renamed from the ambiguous 'container_registry' (which read like the
36
- # cluster's own registry); creds files written before the rename are
37
- # still read via the alias.
38
- upstream_registry: NonEmptyStr = Field(
39
- validation_alias=AliasChoices("upstream_registry", "container_registry")
40
- )
41
- container_sa_key: str = ""
42
- prodigy_license_key: str = ""
43
- target_broker_version: str = ""
44
- target_cpl_version: str = ""
45
-
46
21
 
47
22
  # Tolerations for the system node-pool taint the terraform modules apply:
48
23
  # ellf/role=system on GKE and EKS, and AKS's own CriticalAddonsOnly on AKS,
@@ -419,25 +394,57 @@ def ensure_cert_manager() -> None:
419
394
  Path(tmp_path).unlink(missing_ok=True)
420
395
 
421
396
 
422
- def helm_registry_login(registry: str, sa_key_b64: str) -> None:
423
- """Authenticate the local Helm client to an OCI registry.
397
+ # A registry config helm reads no credentials from but still treats as
398
+ # configured. Given a config with no credentials at all, helm falls back to the
399
+ # OS credential store (the macOS keychain, Docker's credsStore), reading
400
+ # whatever is stored there for the host and saving any login into it.
401
+ _NO_CREDENTIALS_HOST = "ellf.invalid"
402
+
424
403
 
425
- The image pull secret only covers the kubelet; Helm's chart pull runs on
426
- the workstation and needs its own login. Creds persist in
427
- ~/.config/helm/registry/config.json, and the login is idempotent.
404
+ @contextmanager
405
+ def helm_registry_config(
406
+ registry: Optional[str] = None, sa_key_b64: Optional[str] = None
407
+ ) -> Iterator[Path]:
408
+ """A throwaway helm registry config, deleted on exit.
409
+
410
+ Pass it to helm with --registry-config. Without *registry* and
411
+ *sa_key_b64* it holds no credentials, for a chart anyone can pull, and
412
+ keeps helm away from the OS credential store. With them it holds the
413
+ registry key for the registry's host: the cluster's own credential, which
414
+ otherwise would stay in the installer's keychain, and replace whatever
415
+ they had stored for that host, long after the deploy.
428
416
  """
429
- host = registry.split("/", 1)[0]
430
- sa_key_json = base64.b64decode(sa_key_b64, validate=True).decode("utf-8")
431
- result = subprocess.run(
432
- ["helm", "registry", "login", host, "-u", "_json_key", "--password-stdin"],
433
- input=sa_key_json,
434
- text=True,
435
- capture_output=True,
436
- )
437
- if result.returncode != 0:
438
- msg.fail(f"helm registry login failed for {host}: {result.stderr.strip()}")
417
+ auths: dict[str, dict[str, str]] = {_NO_CREDENTIALS_HOST: {}}
418
+ if registry and sa_key_b64:
419
+ host = registry.split("/", 1)[0]
420
+ sa_key_json = base64.b64decode(sa_key_b64, validate=True).decode("utf-8")
421
+ token = base64.b64encode(f"_json_key:{sa_key_json}".encode()).decode()
422
+ auths[host] = {"auth": token}
423
+ with tempfile.TemporaryDirectory(prefix="ellf-helm-") as tmp:
424
+ path = Path(tmp) / "registry.json"
425
+ fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
426
+ with os.fdopen(fd, "w") as f:
427
+ json.dump({"auths": auths}, f)
428
+ yield path
429
+
430
+
431
+ def chart_source(
432
+ creds: ClusterCredentials, registry: Optional[str], sa_key_b64: Optional[str]
433
+ ) -> "tuple[str, ContextManager[Path]]":
434
+ """The chart to install and the helm registry config to pull it with.
435
+
436
+ PAM names a chart anyone can pull, which needs no credentials. A PAM
437
+ that predates the public chart repository names none: the chart is then
438
+ only in the upstream registry, behind the registry key.
439
+ """
440
+ if creds.image.chart:
441
+ return creds.image.chart, helm_registry_config()
442
+ if not registry:
443
+ msg.fail(
444
+ "registries.upstream (or legacy image.registry) is empty in values.yaml"
445
+ )
439
446
  raise SystemExit(1)
440
- msg.info(f"Authenticated Helm to {host}")
447
+ return f"oci://{registry}/ellf", helm_registry_config(registry, sa_key_b64)
441
448
 
442
449
 
443
450
  def get_cluster_auth(
@@ -482,7 +489,7 @@ def point_managed_dns(
482
489
  ip: "str | None",
483
490
  hostname: "str | None" = None,
484
491
  ) -> None:
485
- """Point a cluster's managed subdomain (base + wildcard) at its ingress.
492
+ """Point a cluster's managed subdomain at its ingress.
486
493
 
487
494
  No-op for clusters without a managed subdomain (bring-your-own DNS).
488
495
  Idempotent server-side, so safe to call on every provision/start.
@@ -491,25 +498,20 @@ def point_managed_dns(
491
498
  return
492
499
  if ip:
493
500
  allocated = client.cluster.allocate_domain(cluster.id, ip=ip)
494
- msg.good(
495
- f"Pointed managed domain {allocated.fqdn} (and *.{allocated.fqdn}) at {ip}"
496
- )
501
+ msg.good(f"Pointed managed domain {allocated.fqdn} at {ip}")
497
502
  elif hostname:
498
- # AWS ELBs expose a hostname, never an IP — the records become CNAMEs.
503
+ # AWS ELBs expose a hostname, never an IP — the record becomes a CNAME.
499
504
  allocated = client.cluster.allocate_domain(cluster.id, hostname=hostname)
500
505
  if allocated.hostname:
501
- msg.good(
502
- f"Pointed managed domain {allocated.fqdn} (and "
503
- f"*.{allocated.fqdn}) at {hostname} (CNAME)"
504
- )
506
+ msg.good(f"Pointed managed domain {allocated.fqdn} at {hostname} (CNAME)")
505
507
  else:
506
508
  # A PAM that predates CNAME support silently ignores the
507
509
  # hostname field. Never fail a deploy over this — tell the user
508
510
  # how to point DNS themselves instead.
509
511
  msg.warn(
510
512
  f"This PAM deployment's managed DNS does not support "
511
- f"hostname (CNAME) targets yet. Create CNAME records for "
512
- f"{cluster.address} and *.{cluster.address} pointing at "
513
+ f"hostname (CNAME) targets yet. Create a CNAME record for "
514
+ f"{cluster.address} pointing at "
513
515
  f"{hostname} in your own DNS, or register the cluster with "
514
516
  f"--domain to use bring-your-own DNS."
515
517
  )