feat(ci): wire commander e2e end-to-end (kubeconfig connect mode + enable-modules step)#33
feat(ci): wire commander e2e end-to-end (kubeconfig connect mode + enable-modules step)#33duckhawk wants to merge 4 commits into
Conversation
Code Coverage OverviewLanguages: Go Go / code-coverage/goThe overall coverage in the branch remains at 18%, unchanged from the branch. Show a code coverage summary of the most impacted files.
Updated |
Squashed set of the commander e2e-pipeline work (PR #33): - Commander provider fetches the cluster kubeconfig over SSH (via bastion) when the Commander API does not expose it; writes a <kubeconfig>.sshinfo sidecar. - Raise the commander HTTP client / bootstrap timeouts for slow cluster create. - kubeconfig cluster-connect mode (no SSH) + cmd/enable-modules + wait for the Deckhouse ModuleConfig API. - Reusable workflow: commander bootstrap uploads kubeconfig; run-tests opens an SSH tunnel to the master API and enables the module in-process (no separate enable-modules job). All commander wiring is provider-gated so dvp/other modes are unchanged; run-tests depends only on [resolve, bootstrap]. go mod download (not tidy) is used at run time. docs/CI.md + WORKLOG updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8c2e415 to
b1d2126
Compare
Squashed set of the commander e2e-pipeline work (PR #33): - Commander provider fetches the cluster kubeconfig over SSH (via bastion) when the Commander API does not expose it; writes a <kubeconfig>.sshinfo sidecar. - Raise the commander HTTP client / bootstrap timeouts for slow cluster create. - kubeconfig cluster-connect mode (no SSH) + cmd/enable-modules + wait for the Deckhouse ModuleConfig API. - Reusable workflow: commander bootstrap uploads kubeconfig; run-tests opens an SSH tunnel to the master API and enables the module in-process (no separate enable-modules job). All commander wiring is provider-gated so dvp/other modes are unchanged; run-tests depends only on [resolve, bootstrap]. go mod download (not tidy) is used at run time. docs/CI.md + WORKLOG updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b1d2126 to
0c7365d
Compare
| } | ||
|
|
||
| func main() { | ||
| kubeconfigPath := os.Getenv("KUBE_CONFIG_PATH") |
There was a problem hiding this comment.
Я kubeconfig уже положил в E2E_DVP_BASE_CLUSTER_KUBECONFIG
| // from a kubeconfig file (KUBE_CONFIG_PATH) with no SSH tunnel. Used by the CI | ||
| // pipeline's run-tests step, where the cluster was bootstrapped out-of-band | ||
| // (e.g. by the Commander provider) and its kubeconfig handed off as an artifact. | ||
| ClusterCreateModeKubeconfig = "kubeconfig" |
There was a problem hiding this comment.
я эти устаревшие режимы удалить хотел, не нужно дальше развивать эту логику
storage-e2e/pkg/clusterprovider/config.go
Line 25 in 9407e44
Тут лежит новый конфиг который хранит режимы
Режимы лежат тут - https://github.com/deckhouse/storage-e2e/blob/main/pkg/clusterprovider/mode.go
| // key and the (usually required) jump host. SSHUser overrides the | ||
| // Commander-reported master user; the jump key defaults to the master key. | ||
| SSHPrivateKeyPath string `env:"E2E_COMMANDER_SSH_PRIVATE_KEY_PATH"` | ||
| SSHUser string `env:"E2E_COMMANDER_SSH_USER"` |
There was a problem hiding this comment.
Можем эти переменные унифицировать, чтобы одни и те же не копировать, мне для dvp тоже нужны большая часть из этих переменных, можем нейтрально назвать чтобы и тебе и мне подходили
| return fmt.Errorf("no SSH user for the master of cluster %q (set E2E_COMMANDER_SSH_USER)", name) | ||
| } | ||
|
|
||
| var sshClient ssh.SSHClient |
There was a problem hiding this comment.
можешь пожалуйста на новый ssh client переехать, я сделал, в целом основные механизмы у меня готовы. Exec сейчас подолью, OpenTunnel уже есть
There was a problem hiding this comment.
От старой версии планирую избавиться, нет смысла с ним дальше жить
| // out-of-band (e.g. by the Commander provider, whose kubeconfig is handed off as | ||
| // an artifact). The returned resources carry only the Kubeconfig; teardown only | ||
| // needs to release the lock (the separate teardown job removes the cluster). | ||
| func ConnectViaKubeconfig(ctx context.Context) (*TestClusterResources, error) { |
There was a problem hiding this comment.
Вот этот механизм я думаю в Provider вынести, чтобы у провайдера был метод Connect, пока не решил что он должен возвращать, по этому не добавлял. Можем согласовать что тебе пригодится оттуда кроме rest.Config
| ctx, cancel := context.WithTimeout(context.Background(), config.ClusterCreationTimeout) | ||
| defer cancel() | ||
|
|
||
| GinkgoWriter.Printf(" ▶️ Connecting via kubeconfig (mode: %s, KUBE_CONFIG_PATH=%s)\n", config.TestClusterCreateMode, config.KubeConfigPath) |
There was a problem hiding this comment.
ginko лучше не использовать, из пакета я ее выпилю, лучше на обычный slog перейти, лишний пакет нет смысла тащить сюда
| @@ -0,0 +1,82 @@ | |||
| #!/usr/bin/env bash | |||
There was a problem hiding this comment.
тут обсудить надо почему на скриптах хочешь сделать
| # The commander provider fetches the new cluster's kubeconfig over SSH | ||
| # (the Commander API does not expose it), typically via a jump host, so the | ||
| # SSH key secret is materialized to disk here. | ||
| - name: Materialize commander SSH key |
There was a problem hiding this comment.
тут тоже сделать в конфиге нужно по примеру тут -
Сделать 2 режима, 1 для CI, там мы обычно content храним, работать с ним тоже можно
А для локального запуска оставить поддержку PATH
| # server is the node-local 127.0.0.1:<port>). ALL commander wiring lives in | ||
| # the commander-gated steps below, so for other providers (dvp, …) the | ||
| # "Run E2E tests" step runs with exactly its previous environment. | ||
| - name: Download cluster kubeconfig |
There was a problem hiding this comment.
а нужен ли тут download? или же мы просто можем получить его, я у себя планировал использовать тот что положили для bootstrap, открыть туннель, и достать с мастера нужный ключ в рамках connect
Чтобы Ci максимально легким был
Squashed set of the commander e2e-pipeline work (PR #33): - Commander provider fetches the cluster kubeconfig over SSH (via bastion) when the Commander API does not expose it; writes a <kubeconfig>.sshinfo sidecar. - Raise the commander HTTP client / bootstrap timeouts for slow cluster create. - kubeconfig cluster-connect mode (no SSH) + cmd/enable-modules + wait for the Deckhouse ModuleConfig API. - Reusable workflow: commander bootstrap uploads kubeconfig; run-tests opens an SSH tunnel to the master API and enables the module in-process (no separate enable-modules job). All commander wiring is provider-gated so dvp/other modes are unchanged; run-tests depends only on [resolve, bootstrap]. go mod download (not tidy) is used at run time. docs/CI.md + WORKLOG updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…facts Address @fastrapier's review by rebuilding the commander provider on the new abstractions instead of the legacy SSH client and CI plumbing. - Provider migrated to internal/infrastructure/ssh/v2: a connector (connect.go) mirrors the DVP one — Route(jump, master) + NewWithRetry, Exec-fetches the kubeconfig off the master, opens an in-process API tunnel, returns (*rest.Config, cleanup). No more legacy ssh client, no exportKubeconfig/.sshinfo sidecar. - config.go gains the DVP-style path-or-inline credentials (Validate + Resolve + Credentials); jump key optional (defaults to the master key). - enable-modules and the test suite connect IN-PROCESS via the connector, so the CI drops the kubeconfig artifact upload/download, the external SSH tunnel and e2e-api-tunnel.sh (deleted); a single gated step injects the connection env so "Run E2E tests" stays byte-identical for dvp. - Remove the legacy-extending bits: ConnectViaKubeconfig and the kubeconfig create-mode are replaced by ClusterCreateModeCommanderConnect wired to the connector; drops the ginkgo-based kubeconfig case. Remaining coordination (per review): unify the SSH env-var vocabulary across dvp/commander, and fold suite connect into a formal clusterprovider Provider.Connect — the connector here is shaped to slot into that. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0c7365d to
33c3a52
Compare
LoadConfig (used by the in-process Connect for enable-modules and the suite) parsed the whole Config, whose TemplateName carried env `required` — but connect never creates a cluster, so enable-modules failed with `E2E_COMMANDER_TEMPLATE_NAME is not set`. Drop the struct-tag requirement and validate TemplateName in createCluster (Bootstrap) instead, where it is actually needed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ConnectToCommanderCluster passed the caller's ClusterCreationTimeout context to the connector, which ties the SSH client + tunnel serve loop to it. When the connect dispatch block returned (defer cancel) the tunnel listener closed, so every later suite API call failed with "dial tcp 127.0.0.1:<port>: connect: connection refused" and BeforeSuite timed out. Detach cancellation (context.WithoutCancel) so the tunnel lives until CleanupTestCluster tears it down; connect setup stays bounded by the connector's NewWithRetry timeout. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
What
Adds a Deckhouse Commander cluster provider and the wiring to run a module's e2e suite against a Commander-created cluster, without regressing the existing (dvp / other) providers. Rebased on current
mainand realigned onto the newssh/v2+ connector abstractions per review.Provider (
internal/provisioning/commander)Mirrors the DVP provider's shape:
config.go— path-or-inline SSH credentials (Validate/Resolve/Credentials), likedvp/config.go. The master host is resolved from the Commander connection info (not configured); the jump key is optional and defaults to the master key.connect.go— a connector built oninternal/infrastructure/ssh/v2:Route(jump, master)+NewWithRetry,Exec-fetches the kubeconfig off the master (super-admin.conf/admin.conf), opens an in-process API tunnel (OpenTunnel), and returns(*rest.Config, cleanup). A package-levelConnect(ctx, environ, logger)is the shared entry point.kubeconfig.go—buildRestConfig(overrides the server to the tunnel's local addr), same as dvp.provider.go—Bootstrap/Removenow only talk to the Commander API (create + wait Ready / delete). No legacy SSH client, noexportKubeconfig/.sshinfosidecar.Connect + module enablement
cmd/enable-modulesand the test suite both connect through the commander connector — SSH to the master via the bastion, kubeconfig fetched off the master, in-process API tunnel. No kubeconfig artifact, no external SSH tunnel.cmd/enable-modulesenables the module-under-test viaEnableAndConfigureModules(ModuleConfig + ModulePullOverride fromcluster_config), after waiting for the Deckhousedeckhouse.io/v1alpha1ModuleConfig API.ClusterCreateModeKubeconfig+ConnectViaKubeconfig(which extended the legacy path) are gone; replaced byClusterCreateModeCommanderConnectwired to the connector. Interim connect-side of the provider flow, shaped to fold into a formalclusterproviderProvider.Connect.Reusable workflow (
.github/workflows/e2e.yml)cluster_provider(dvpdefault |commander) andmodule_image_tag.resolve → bootstrap → run-tests → teardown.bootstrap(commander) only calls the Commander API — no kubeconfig artifact.run-tests(commander): a single gated step injects the connection env (TEST_CLUSTER_CREATE_MODE=commanderConnect+E2E_COMMANDER_*, SSH key inline via$GITHUB_ENV); enable-modules and the suite connect in-process.e2e-api-tunnel.shdeleted, no download-artifact, no key-file materialization. TheRun E2E testsstep stays byte-identical for other providers (dvp).docs/CI.mdupdated.Validation
go build/go vet/gofmt/ unit tests are green after the rebase + realignment. The commander flow was previously proven end-to-end againstsds-object(deckhouse/sds-object#20: bootstrap → enable-modules → System + Lightweight specs, 16/16 → teardown); re-validation against this realigned workflow is in progress.Follow-ups / coordination (from review)
E2E_COMMANDER_SSH_*prefix mirroring dvp's field shape; happy to rename both providers to a neutral shared set (e.g.E2E_SSH_*) once we agree on names.Provider.Connect— the connector already returns(*rest.Config, cleanup); ready to fold suite connect into a formalclusterprovider.Provider.Connectonce its return contract is settled.🤖 Generated with Claude Code