diff --git a/core/src/plugin/handlers/Provider/getEnvironmentStatus.ts b/core/src/plugin/handlers/Provider/getEnvironmentStatus.ts index 44adae03c62..ee907b9f596 100644 --- a/core/src/plugin/handlers/Provider/getEnvironmentStatus.ts +++ b/core/src/plugin/handlers/Provider/getEnvironmentStatus.ts @@ -31,10 +31,11 @@ export interface EnvironmentStatusMap { [providerName: string]: EnvironmentStatus } +// TODO @eysi: Update text export const getEnvironmentStatus = () => ({ description: dedent` - Check if the current environment is ready for use by this plugin. Use this action in combination - with \`prepareEnvironment\`. + Helper handler to check if the current environment is ready for use by this plugin. Only called + with commands that set \`statusOnly: true\`. Called before \`prepareEnvironment\`. If this returns \`ready: true\`, the \`prepareEnvironment\` action is not called. diff --git a/core/src/plugin/handlers/Provider/prepareEnvironment.ts b/core/src/plugin/handlers/Provider/prepareEnvironment.ts index 2b851a6ff53..1495632ea73 100644 --- a/core/src/plugin/handlers/Provider/prepareEnvironment.ts +++ b/core/src/plugin/handlers/Provider/prepareEnvironment.ts @@ -14,11 +14,7 @@ import { joi } from "../../../config/common.js" import { environmentStatusSchema } from "../../../config/status.js" import type { GenericProviderConfig } from "../../../config/provider.js" -export interface PrepareEnvironmentParams< - C extends GenericProviderConfig = any, - T extends EnvironmentStatus = EnvironmentStatus, -> extends PluginActionParamsBase { - status: T +export interface PrepareEnvironmentParams extends PluginActionParamsBase { force: boolean } @@ -27,6 +23,7 @@ export interface PrepareEnvironmentResult ({ + // TODO @eysi: Update text description: dedent` Make sure the environment is set up for this plugin. Use this action to do any bootstrapping required before deploying services. diff --git a/core/src/plugins/exec/exec.ts b/core/src/plugins/exec/exec.ts index 4cd4aa72402..ea1acc4a9c5 100644 --- a/core/src/plugins/exec/exec.ts +++ b/core/src/plugins/exec/exec.ts @@ -80,11 +80,6 @@ export const execProvider = execPlugin.createProvider({ }), }) -execProvider.addHandler("getEnvironmentStatus", async ({ ctx }) => { - // Return ready if there is no initScript to run - return { ready: !ctx.provider.config.initScript, outputs: {} } -}) - execProvider.addHandler("prepareEnvironment", async ({ ctx, log }) => { const execLog = log.createLog({ name: "exec" }) if (ctx.provider.config.initScript) { diff --git a/core/src/plugins/kubernetes/commands/cluster-init.ts b/core/src/plugins/kubernetes/commands/cluster-init.ts index 47c50e34cee..11c3459dff7 100644 --- a/core/src/plugins/kubernetes/commands/cluster-init.ts +++ b/core/src/plugins/kubernetes/commands/cluster-init.ts @@ -33,7 +33,6 @@ export const clusterInit: PluginCommand = { ctx, log, force: true, - status, }) } diff --git a/core/src/plugins/kubernetes/init.ts b/core/src/plugins/kubernetes/init.ts index 6314fbc6e46..f957d64e355 100644 --- a/core/src/plugins/kubernetes/init.ts +++ b/core/src/plugins/kubernetes/init.ts @@ -145,16 +145,19 @@ export async function getIngressMisconfigurationWarnings( /** * Deploys system services (if any) and creates the default app namespace. + * TODO @eysi: Ensure secrets here */ export async function prepareEnvironment( - params: PrepareEnvironmentParams + params: PrepareEnvironmentParams ): Promise { - const { ctx, log, status } = params + const { ctx, log } = params const k8sCtx = ctx const provider = k8sCtx.provider const config = provider.config + const api = await KubeApi.factory(log, ctx, provider) + // create default app namespace if it doesn't exist - await prepareNamespaces({ ctx, log }) + const nsStatuses = await prepareNamespaces({ ctx, log }) // make sure that the system namespace exists await getSystemNamespace(ctx, ctx.provider, log) @@ -162,11 +165,30 @@ export async function prepareEnvironment( if (config.setupIngressController === "nginx") { // Install nginx ingress controller await ingressControllerInstall(k8sCtx, log) + } else { + // We only need to warn about missing ingress classes if we're not using garden installed nginx + const ingressApiVersion = await getIngressApiVersion(log, api, supportedIngressApiVersions) + const ingressWarnings = await getIngressMisconfigurationWarnings( + provider.config.ingressClass, + ingressApiVersion, + log, + api + ) + ingressWarnings.forEach((w) => log.warn(w)) } - const nsStatus = await getNamespaceStatus({ ctx: k8sCtx, log, provider }) - ctx.events.emit("namespaceStatus", nsStatus) - return { status: { ready: true, outputs: status.outputs } } + // prepareNamespaces already does this + // const nsStatus = await getNamespaceStatus({ ctx: k8sCtx, log, provider }) + // ctx.events.emit("namespaceStatus", nsStatus) + return { + status: { + ready: true, + outputs: { + "app-namespace": nsStatuses["app-namespace"].namespaceName, + "default-hostname": provider.config.defaultHostname || null, + }, + }, + } } export async function cleanupEnvironment({ diff --git a/core/src/plugins/kubernetes/local/local.ts b/core/src/plugins/kubernetes/local/local.ts index cfeb656c07e..70c09933200 100644 --- a/core/src/plugins/kubernetes/local/local.ts +++ b/core/src/plugins/kubernetes/local/local.ts @@ -67,7 +67,13 @@ async function prepareEnvironment( const { ctx, log } = params const provider = ctx.provider - const result = await _prepareEnvironmentBase(params) + // This should be set in the configureProvider handler but we need the + // plugin context to get the cluster type + if (!provider.config.clusterType) { + provider.config.clusterType = await getClusterType(ctx, log) + } + + const prepareEnvResult = await _prepareEnvironmentBase(params) if (provider.config.clusterType === "minikube") { await setMinikubeDockerEnv() @@ -76,7 +82,7 @@ async function prepareEnvironment( await configureMicrok8sAddons(log, microk8sAddons) } - return result + return prepareEnvResult } async function getClusterType(ctx: KubernetesPluginContext, log: Log): Promise { diff --git a/core/src/plugins/otel-collector/otel-collector.ts b/core/src/plugins/otel-collector/otel-collector.ts index 65c03648797..94c99989915 100644 --- a/core/src/plugins/otel-collector/otel-collector.ts +++ b/core/src/plugins/otel-collector/otel-collector.ts @@ -120,10 +120,6 @@ const providerConfigSchema = s.object({ export const provider = gardenPlugin.createProvider({ configSchema: providerConfigSchema, outputsSchema: s.object({}) }) -provider.addHandler("getEnvironmentStatus", async () => { - return { ready: false, outputs: {} } -}) - provider.addHandler("prepareEnvironment", async ({ ctx, log }) => { const scopedLog = log.createLog({ name: "otel-collector" }) scopedLog.debug("Preparing the environment for the otel-collector") diff --git a/core/src/tasks/resolve-provider.ts b/core/src/tasks/resolve-provider.ts index 11b5412f936..817df9657fa 100644 --- a/core/src/tasks/resolve-provider.ts +++ b/core/src/tasks/resolve-provider.ts @@ -31,7 +31,6 @@ import { stableStringify } from "../util/string.js" import { OtelTraced } from "../util/open-telemetry/decorators.js" import { LogLevel } from "../logger/logger.js" import type { Log } from "../logger/log-entry.js" -import { styles } from "../logger/styles.js" import type { ObjectPath } from "../config/base.js" import fsExtra from "fs-extra" import { RemoteSourceConfigContext } from "../config/template-contexts/project.js" @@ -412,43 +411,43 @@ export class ResolveProviderTask extends BaseTask { return cachedStatus } - // TODO: avoid calling the handler manually (currently doing it to override the plugin context) - const handler = await actions.provider["getPluginHandler"]({ - handlerType: "getEnvironmentStatus", - pluginName, - defaultHandler: async () => defaultEnvironmentStatus, - }) - - let status = await handler!({ ctx, log: providerLog }) - - if (!statusOnly && (this.forceInit || !status.ready)) { - const statusMsg = status.ready - ? `${styles.highlight("Ready")}, will ${styles.highlight("force re-initialize")}` - : `${styles.highlight("Not ready")}, will initialize` - providerLog.info(statusMsg) - // TODO: avoid calling the handler manually - const prepareHandler = await actions.provider["getPluginHandler"]({ - handlerType: "prepareEnvironment", + if (statusOnly) { + // TODO: avoid calling the handler manually (currently doing it to override the plugin context) + const getStatusHandler = await actions.provider["getPluginHandler"]({ + handlerType: "getEnvironmentStatus", pluginName, - defaultHandler: async () => ({ status }), + defaultHandler: async () => defaultEnvironmentStatus, }) - const result = await prepareHandler!({ ctx, log: providerLog, force: this.forceInit, status }) + const envStatus = await getStatusHandler!({ ctx, log: providerLog }) + if (envStatus.ready) { + providerLog.success(`Provider is ready`) + } else { + providerLog.warn(`Provider is not ready`) + } - status = result.status + return envStatus } - if (!status.ready && !statusOnly) { + providerLog.info(`Preparing provider environment`) + // TODO: avoid calling the handler manually + const prepareHandler = await actions.provider["getPluginHandler"]({ + handlerType: "prepareEnvironment", + pluginName, + defaultHandler: async () => ({ status: { ready: true, outputs: {} } }), + }) + + const result = await prepareHandler!({ ctx, log: providerLog, force: this.forceInit }) + + const status = result.status + + if (!status.ready) { providerLog.error("Failed initializing provider") throw new PluginError({ message: `Provider ${pluginName} reports status as not ready and could not prepare the configured environment.`, }) } - if (!status.ready && statusOnly) { - providerLog.success("Provider not ready. Current command only checks status, not preparing environment") - return status - } providerLog.success("Provider ready") if (!status.disableCache) { diff --git a/core/test/integ/src/plugins/kubernetes/ingress-controller.ts b/core/test/integ/src/plugins/kubernetes/ingress-controller.ts index 6b7c5191dc5..fef3914da3f 100644 --- a/core/test/integ/src/plugins/kubernetes/ingress-controller.ts +++ b/core/test/integ/src/plugins/kubernetes/ingress-controller.ts @@ -13,7 +13,6 @@ import { ingressControllerReady } from "../../../../../src/plugins/kubernetes/ng import { uninstallGardenServices } from "../../../../../src/plugins/kubernetes/commands/uninstall-garden-services.js" import { prepareEnvironment } from "../../../../../src/plugins/kubernetes/init.js" import type { PrepareEnvironmentParams } from "../../../../../src/plugin/handlers/Provider/prepareEnvironment.js" -import { defaultEnvironmentStatus } from "../../../../../src/plugin/handlers/Provider/getEnvironmentStatus.js" import { getContainerTestGarden } from "./container/container.js" import type { Garden } from "../../../../../src/garden.js" @@ -59,7 +58,6 @@ describe("It should manage ingress controller for respective cluster type", () = const params: PrepareEnvironmentParams = { ctx, log: garden.log, - status: defaultEnvironmentStatus, force: false, } ctx.provider.config.setupIngressController = "nginx" @@ -72,7 +70,6 @@ describe("It should manage ingress controller for respective cluster type", () = const params: PrepareEnvironmentParams = { ctx, log: garden.log, - status: defaultEnvironmentStatus, force: false, } ctx.provider.config.setupIngressController = "null" @@ -86,7 +83,6 @@ describe("It should manage ingress controller for respective cluster type", () = const params: PrepareEnvironmentParams = { ctx, log: garden.log, - status: defaultEnvironmentStatus, force: false, } ctx.provider.config.setupIngressController = "nginx" diff --git a/core/test/integ/src/plugins/kubernetes/provider.ts b/core/test/integ/src/plugins/kubernetes/provider.ts index ba1de62d985..63cb7c4965e 100644 --- a/core/test/integ/src/plugins/kubernetes/provider.ts +++ b/core/test/integ/src/plugins/kubernetes/provider.ts @@ -69,11 +69,9 @@ describe("kubernetes provider handlers", () => { }) it("should prepare the environment with the prepareEnvironment handler", async () => { - const status = await getEnvironmentStatus({ ctx, log }) const params: PrepareEnvironmentParams = { ctx, log: garden.log, - status, force: false, } const envStatus = await prepareEnvironment(params) diff --git a/core/test/unit/src/commands/get/get-outputs.ts b/core/test/unit/src/commands/get/get-outputs.ts index e5bde8a6ec3..0c230da91ca 100644 --- a/core/test/unit/src/commands/get/get-outputs.ts +++ b/core/test/unit/src/commands/get/get-outputs.ts @@ -34,8 +34,8 @@ describe("GetOutputsCommand", () => { const plugin = createGardenPlugin({ name: "test", handlers: { - async getEnvironmentStatus() { - return { ready: true, outputs: { test: "test-value" } } + async prepareEnvironment() { + return { status: { ready: true, outputs: { test: "test-value" } } } }, }, }) diff --git a/core/test/unit/src/garden.ts b/core/test/unit/src/garden.ts index 0a0241729dc..740ac9fe480 100644 --- a/core/test/unit/src/garden.ts +++ b/core/test/unit/src/garden.ts @@ -2497,10 +2497,12 @@ describe("Garden", () => { const testA = createGardenPlugin({ name: "test-a", handlers: { - getEnvironmentStatus: async () => { + prepareEnvironment: async () => { return { - ready: true, - outputs: { foo: "bar" }, + status: { + ready: true, + outputs: { foo: "bar" }, + }, } }, }, diff --git a/core/test/unit/src/outputs.ts b/core/test/unit/src/outputs.ts index 2378b50bcd0..363da9c58f5 100644 --- a/core/test/unit/src/outputs.ts +++ b/core/test/unit/src/outputs.ts @@ -48,8 +48,8 @@ describe("resolveProjectOutputs", () => { const plugin = createGardenPlugin({ name: "test", handlers: { - async getEnvironmentStatus() { - return { ready: true, outputs: { test: "test-value" } } + async prepareEnvironment() { + return { status: { ready: true, outputs: { test: "test-value" } } } }, }, }) diff --git a/core/test/unit/src/router/provider.ts b/core/test/unit/src/router/provider.ts index d49de52f031..ecc2612ce81 100644 --- a/core/test/unit/src/router/provider.ts +++ b/core/test/unit/src/router/provider.ts @@ -138,7 +138,6 @@ describe("provider actions", async () => { log, pluginName: "test-plugin-a", force: false, - status: { ready: true, outputs: {} }, events: undefined, }) expect(result).to.eql({ diff --git a/plugins/terraform/src/init.ts b/plugins/terraform/src/init.ts index 3ae27b215e0..c015d794d8a 100644 --- a/plugins/terraform/src/init.ts +++ b/plugins/terraform/src/init.ts @@ -56,6 +56,16 @@ export const prepareEnvironment: ProviderHandlers["prepareEnvironment"] = async return { status: { ready: true, outputs: {} } } } + const envStatus = await getEnvironmentStatus({ ctx, log }) + if (envStatus.ready) { + return { + status: { + ready: true, + outputs: envStatus.outputs, + }, + } + } + const root = getRoot(ctx, provider) const workspace = provider.config.workspace || null