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.
- {ellf_cli-22.0.3/ellf_cli.egg-info → ellf_cli-22.0.5}/PKG-INFO +1 -1
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/README.md +12 -13
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/__main__.py +3 -3
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cli.py +40 -3
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cluster_config.py +1 -13
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/clusters.py +31 -6
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/_helpers.py +57 -55
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/deploy.py +211 -67
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/init.py +37 -16
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/init_values.py +77 -56
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/register.py +30 -34
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/start.py +28 -78
- ellf_cli-22.0.5/ellf_cli/commands/infra/tls.py +302 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf.json +62 -75
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/helm.py +30 -31
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/messages.py +3 -1
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ty.py +2 -0
- 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
- 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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5/ellf_cli.egg-info}/PKG-INFO +1 -1
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/SOURCES.txt +3 -0
- ellf_cli-22.0.5/tests/test_cluster_status.py +46 -0
- ellf_cli-22.0.5/tests/test_infra_deploy_registry_key.py +243 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_init.py +71 -5
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_register.py +16 -20
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_start_fixes.py +10 -14
- ellf_cli-22.0.5/tests/test_infra_tls.py +379 -0
- ellf_cli-22.0.3/ellf_cli/commands/infra/tls.py +0 -571
- ellf_cli-22.0.3/tests/test_infra_deploy_registry_key.py +0 -46
- ellf_cli-22.0.3/tests/test_infra_tls.py +0 -262
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/LICENSE +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/MANIFEST.in +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/about.json +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/about.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/agents.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/appdirs.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/auth.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cloud/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/cloud/gcp.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_cluster_select.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_org_select.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_project_scope.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_recipe_file.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_recipe_subcommand.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_state.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/_usage.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/actions.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/agents.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/assets.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/config.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/datasets.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/cp.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/ls.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/rm.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/rsync.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/files/stats.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/general.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/import_export.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/_config_io.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/configure.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/hibernate.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/pause.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/provision.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/setup.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/infra/terraform.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/jobs.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/mcp.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/packages.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/paths.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/plans.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/projects.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/publish_code.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/publish_data.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/recipes.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/secrets.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/services.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/sessions.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/support.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/tasks.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/todos.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/commands/users.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/config.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/.gitignore +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/render.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/annotation_audit.coding.md +0 -0
- {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
- {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
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-annotate/references/label_schemes.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ask/SKILL.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-handoff/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/annotation_metrics.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/references/training_monitoring.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-monitor/scripts.coding/check_training.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/SKILL.coding.md +0 -0
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-ops/scripts.coding/run_job.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-patterns/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-patterns/references/pattern_strategies.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/SKILL.coding.md +0 -0
- {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
- {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
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_correct.py +0 -0
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_manual.py +0 -0
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_routing.py +0 -0
- {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
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/assets/templates/template_teach.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/builtin_recipes.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/ellf_recipe_sdk.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/lint_recipe.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/prodigy_recipe_api.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-prodigy/references/template_index.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/annotation_agents.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/consulting_patterns.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/explosion_strategy.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/jev.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-project/references/label_schemes.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-support/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/references/template_format.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-template/scripts/placeholders.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-todo/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/SKILL.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_advanced.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_architectures.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/config_training.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/diagnostics.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/evaluation_guide.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/experiment_patterns.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/model_selection.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/training_paradigms.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/training_troubleshooting.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.assistant.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/references/workflow.coding.md +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ellf_skills/skills/ellf-train/scripts.coding/ellf_logger.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/errors.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/interactivity.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/key_pair.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/main.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/mcp_proxy.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/pypi_auth.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/query.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/cookiecutter.json +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/.gitignore +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/README.md.tmpl +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements-dev.in +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/requirements.in +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/setup.py.tmpl +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/recipes_cookiecutter/{{cookiecutter.package_dir}}/{{cookiecutter.package_name}}/about.py +0 -0
- {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
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/testing/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/ui.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/url.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/util.py +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/__init__.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli/version/read_version.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/dependency_links.txt +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/entry_points.txt +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/not-zip-safe +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/requires.txt +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/ellf_cli.egg-info/top_level.txt +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/pyproject.toml +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/setup.cfg +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/setup.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_agents.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_agents_info_stats.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_appdirs.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_auth.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_clusters_info_stats.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_config.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_datasets_export.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_errors.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_files_cp.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_files_cp_helpers.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_helm.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_import_export.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_info.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_config_io.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_configure.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_deploy_node_labels.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_deploy_preflight.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_destroy.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_get_terraform.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_hibernate.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_pause.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_provision.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_start_validation.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_state_bucket.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_infra_terraform_init.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_invalid_secrets.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_job_list_project_filter.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_jobs_info_hides_creator.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_jobs_list_unmatched.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_key_pair.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_login.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_logout.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_main.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_mcp_proxy.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_org_select.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_plans.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_projects.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_projects_delete_confirm.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_build_poll.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_data.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_import_root.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_requirements.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_publish_versions.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_pypi_auth.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_query.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_file.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_help.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipe_required_args.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipes.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_recipes_init.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_sessions.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_state.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_support.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_todos.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ty.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ui.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_ui_extras.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_usage_counts.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_assign.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_info_stats.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_users_list.py +0 -0
- {ellf_cli-22.0.3 → ellf_cli-22.0.5}/tests/test_util.py +0 -0
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
| `--
|
|
730
|
-
| `--
|
|
731
|
-
| `--
|
|
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
|
|
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
|
-
| `--
|
|
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
|
|
11
|
-
#
|
|
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
|
-
|
|
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
|
|
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"{
|
|
339
|
+
msg.good(f"{label}{suffix}")
|
|
320
340
|
else:
|
|
321
|
-
msg.fail(f"{
|
|
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=
|
|
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,
|
|
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
|
-
|
|
423
|
-
|
|
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
|
-
|
|
426
|
-
|
|
427
|
-
|
|
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
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
512
|
-
f"{cluster.address}
|
|
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
|
)
|