From 3e680e036115429dfcee22ef66451aa03a37539a Mon Sep 17 00:00:00 2001 From: Vladimir Vagaytsev <10628074+vvagaytsev@users.noreply.github.com> Date: Wed, 20 Nov 2024 12:36:58 +0100 Subject: [PATCH] fix(k8s): respect pod selector in kubernetes-exec action type (#6657) * fix(k8s): respect pod selector in kubernetes-exec action type * test(k8s): add integration test --- .../kubernetes-type/kubernetes-exec.ts | 14 +++++---- .../kubernetes-type/module-simple/garden.yml | 12 +++++++ .../kubernetes-type/kubernetes-exec-run.ts | 31 ++++++++++++++++++- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/core/src/plugins/kubernetes/kubernetes-type/kubernetes-exec.ts b/core/src/plugins/kubernetes/kubernetes-type/kubernetes-exec.ts index f6260c2252..0e2242ad79 100644 --- a/core/src/plugins/kubernetes/kubernetes-type/kubernetes-exec.ts +++ b/core/src/plugins/kubernetes/kubernetes-type/kubernetes-exec.ts @@ -18,13 +18,13 @@ import type { PluginContext } from "../../../plugin-context.js" import type { RunActionDefinition, TestActionDefinition } from "../../../plugin/action-types.js" import type { RunResult } from "../../../plugin/base.js" import { dedent } from "../../../util/string.js" -import { KubeApi, KubernetesError } from "../api.js" +import { KubernetesError } from "../api.js" import type { KubernetesPluginContext, KubernetesTargetResourceSpec } from "../config.js" import { namespaceNameSchema, runPodResourceSchema } from "../config.js" import { getActionNamespaceStatus } from "../namespace.js" import { k8sGetRunResult } from "../run-results.js" import type { SyncableResource } from "../types.js" -import { execInWorkload, readTargetResource } from "../util.js" +import { execInWorkload, getTargetResource } from "../util.js" import type { KubernetesRunOutputs } from "./config.js" import { kubernetesRunOutputsSchema } from "./config.js" @@ -35,6 +35,7 @@ export interface KubernetesExecRunActionSpec { command: string[] namespace?: string } + export type KubernetesExecRunActionConfig = RunActionConfig<"kubernetes-exec", KubernetesExecRunActionSpec> export type KubernetesExecRunAction = RunAction @@ -124,7 +125,6 @@ async function readAndExec({ const { resource, command } = action.getSpec() const k8sCtx = ctx const provider = k8sCtx.provider - const api = await KubeApi.factory(log, k8sCtx, provider) const namespaceStatus = await getActionNamespaceStatus({ ctx: k8sCtx, log, @@ -137,9 +137,11 @@ async function readAndExec({ let target: SyncableResource try { - target = await readTargetResource({ - api, - namespace, + target = await getTargetResource({ + ctx, + log, + provider, + action, query: resource, }) } catch (err) { diff --git a/core/test/data/test-projects/kubernetes-type/module-simple/garden.yml b/core/test/data/test-projects/kubernetes-type/module-simple/garden.yml index 4b8feab03b..89ec2da6a2 100644 --- a/core/test/data/test-projects/kubernetes-type/module-simple/garden.yml +++ b/core/test/data/test-projects/kubernetes-type/module-simple/garden.yml @@ -54,6 +54,18 @@ spec: name: busybox-deployment command: [echo, ok] +--- +kind: Run +name: echo-run-exec-pod-selector +type: kubernetes-exec +dependencies: + - deploy.module-simple +spec: + resource: + podSelector: + app: busybox + command: [echo, ok] + --- kind: Test name: echo-test-exec diff --git a/core/test/integ/src/plugins/kubernetes/kubernetes-type/kubernetes-exec-run.ts b/core/test/integ/src/plugins/kubernetes/kubernetes-type/kubernetes-exec-run.ts index 579774327d..aa616b02a9 100644 --- a/core/test/integ/src/plugins/kubernetes/kubernetes-type/kubernetes-exec-run.ts +++ b/core/test/integ/src/plugins/kubernetes/kubernetes-type/kubernetes-exec-run.ts @@ -27,7 +27,7 @@ describe("kubernetes-type exec Run", () => { graph = await garden.getConfigGraph({ log: garden.log, emit: false }) }) - it("should run a basic Run", async () => { + it("should run a command in a pod specified by kind and name", async () => { const action = graph.getRun("echo-run-exec") const testTask = new RunTask({ @@ -55,4 +55,33 @@ describe("kubernetes-type exec Run", () => { expect(result?.result?.outputs.log).to.equal("ok") expect(result!.result!.detail?.namespaceStatus).to.exist }) + + it("should run a command in a pod specified by podSelector", async () => { + const action = graph.getRun("echo-run-exec-pod-selector") + + const testTask = new RunTask({ + garden, + graph, + action, + log: garden.log, + force: true, + forceBuild: false, + }) + + // Clear any existing Run result + const provider = await garden.resolveProvider({ log: garden.log, name: "local-kubernetes" }) + const ctx = await garden.getPluginContext({ provider, templateContext: undefined, events: undefined }) + await clearRunResult({ ctx, log: garden.log, action }) + + garden.events.eventLog = [] + const results = await garden.processTasks({ tasks: [testTask], throwOnError: true }) + const result = results.results.getResult(testTask) + expect(findNamespaceStatusEvent(garden.events.eventLog, "kubernetes-type-test-default")).to.exist + + expect(result).to.exist + expect(result?.result).to.exist + expect(result?.outputs).to.exist + expect(result?.result?.outputs.log).to.equal("ok") + expect(result!.result!.detail?.namespaceStatus).to.exist + }) })