1import * as Layer from "effect/Layer";
2import { DockerLive } from "../Docker/Docker.ts";
3import * as Provider from "../Provider.ts";
4import { builtinAdapters } from "./BuiltinAdapters.ts";
5import { Deployment, DeploymentProvider } from "./Deployment.ts";
6import { HelmChart, HelmChartProvider } from "./HelmChart.ts";
7import { Job, JobProvider } from "./Job.ts";
8import { LocalCluster, LocalClusterProvider } from "./LocalCluster.ts";
9import { Manifest, ManifestProvider } from "./Manifest.ts";
10
11export class Providers extends Provider.ProviderCollection<Providers>()(
12 "Kubernetes",
13) {}
14
15/**
16 * The Kubernetes provider layer: the cluster-agnostic workload providers
17 * (`Deployment`, `Job`, `Manifest`, `HelmChart`), `LocalCluster`, and the
18 * built-in cluster adapters (`kubeconfig`, `token`, `client-cert`, `exec`).
19 *
20 * Managed-cloud clusters need their platform's adapter alongside — e.g.
21 * targeting an `AWS.EKS.Cluster` requires `AWS.providers()` in the same
22 * stack:
23 *
24 * ```ts
25 * const stack = Alchemy.Stack("app", {
26 * providers: Layer.mergeAll(AWS.providers(), Kubernetes.providers()),
27 * state: AWS.state(),
28 * });
29 * ```
30 */
31export const providers = () =>
32 Layer.effect(
33 Providers,
34 Provider.collection([Deployment, HelmChart, Job, LocalCluster, Manifest]),
35 ).pipe(
36 Layer.provide(
37 Layer.mergeAll(
38 DeploymentProvider(),
39 HelmChartProvider(),
40 JobProvider(),
41 LocalClusterProvider(),
42 ManifestProvider(),
43 ).pipe(
44 // Workloads build `main` / `context` images with the Docker CLI for
45 // connections that declare a `registry`.
46 Layer.provide(DockerLive),
47 ),
48 ),
49 // The built-in adapters are provideMerged (not just provided) so the
50 // workloads' dynamic `findClusterAdapter` lookups see them in the
51 // ambient stack context.
52 Layer.provideMerge(builtinAdapters()),
53 Layer.orDie,
54 );