@gezelligate/core 0.1.0

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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/bridgeManifest.d.ts +67 -0
  4. package/dist/bridgeManifest.d.ts.map +1 -0
  5. package/dist/bridgeManifest.js +35 -0
  6. package/dist/bridgeManifest.js.map +1 -0
  7. package/dist/capabilities.d.ts +23 -0
  8. package/dist/capabilities.d.ts.map +1 -0
  9. package/dist/capabilities.js +15 -0
  10. package/dist/capabilities.js.map +1 -0
  11. package/dist/catalog/bootstrap.d.ts +25 -0
  12. package/dist/catalog/bootstrap.d.ts.map +1 -0
  13. package/dist/catalog/bootstrap.js +56 -0
  14. package/dist/catalog/bootstrap.js.map +1 -0
  15. package/dist/catalog/index.d.ts +4 -0
  16. package/dist/catalog/index.d.ts.map +1 -0
  17. package/dist/catalog/index.js +4 -0
  18. package/dist/catalog/index.js.map +1 -0
  19. package/dist/catalog/projectPin.d.ts +22 -0
  20. package/dist/catalog/projectPin.d.ts.map +1 -0
  21. package/dist/catalog/projectPin.js +39 -0
  22. package/dist/catalog/projectPin.js.map +1 -0
  23. package/dist/catalog/reader.d.ts +44 -0
  24. package/dist/catalog/reader.d.ts.map +1 -0
  25. package/dist/catalog/reader.js +7 -0
  26. package/dist/catalog/reader.js.map +1 -0
  27. package/dist/catalog/tarball.d.ts +48 -0
  28. package/dist/catalog/tarball.d.ts.map +1 -0
  29. package/dist/catalog/tarball.js +114 -0
  30. package/dist/catalog/tarball.js.map +1 -0
  31. package/dist/cluster.d.ts +4 -0
  32. package/dist/cluster.d.ts.map +1 -0
  33. package/dist/cluster.js +46 -0
  34. package/dist/cluster.js.map +1 -0
  35. package/dist/dedicatedPeer.d.ts +43 -0
  36. package/dist/dedicatedPeer.d.ts.map +1 -0
  37. package/dist/dedicatedPeer.js +38 -0
  38. package/dist/dedicatedPeer.js.map +1 -0
  39. package/dist/dependencies.d.ts +6 -0
  40. package/dist/dependencies.d.ts.map +1 -0
  41. package/dist/dependencies.js +124 -0
  42. package/dist/dependencies.js.map +1 -0
  43. package/dist/index.d.ts +15 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +17 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/ingress.d.ts +4 -0
  48. package/dist/ingress.d.ts.map +1 -0
  49. package/dist/ingress.js +17 -0
  50. package/dist/ingress.js.map +1 -0
  51. package/dist/keycloak.d.ts +61 -0
  52. package/dist/keycloak.d.ts.map +1 -0
  53. package/dist/keycloak.js +161 -0
  54. package/dist/keycloak.js.map +1 -0
  55. package/dist/numericId.d.ts +2 -0
  56. package/dist/numericId.d.ts.map +1 -0
  57. package/dist/numericId.js +22 -0
  58. package/dist/numericId.js.map +1 -0
  59. package/dist/providers/lifecycle.d.ts +81 -0
  60. package/dist/providers/lifecycle.d.ts.map +1 -0
  61. package/dist/providers/lifecycle.js +22 -0
  62. package/dist/providers/lifecycle.js.map +1 -0
  63. package/dist/providers.d.ts +4 -0
  64. package/dist/providers.d.ts.map +1 -0
  65. package/dist/providers.js +45 -0
  66. package/dist/providers.js.map +1 -0
  67. package/dist/render.d.ts +22 -0
  68. package/dist/render.d.ts.map +1 -0
  69. package/dist/render.js +354 -0
  70. package/dist/render.js.map +1 -0
  71. package/dist/repository.d.ts +4 -0
  72. package/dist/repository.d.ts.map +1 -0
  73. package/dist/repository.js +31 -0
  74. package/dist/repository.js.map +1 -0
  75. package/dist/schema/clusterYaml.d.ts +39 -0
  76. package/dist/schema/clusterYaml.d.ts.map +1 -0
  77. package/dist/schema/clusterYaml.js +24 -0
  78. package/dist/schema/clusterYaml.js.map +1 -0
  79. package/dist/schema/configYaml.d.ts +90 -0
  80. package/dist/schema/configYaml.d.ts.map +1 -0
  81. package/dist/schema/configYaml.js +32 -0
  82. package/dist/schema/configYaml.js.map +1 -0
  83. package/dist/schema/providerYaml.d.ts +312 -0
  84. package/dist/schema/providerYaml.d.ts.map +1 -0
  85. package/dist/schema/providerYaml.js +54 -0
  86. package/dist/schema/providerYaml.js.map +1 -0
  87. package/dist/schema/serviceYaml.d.ts +2407 -0
  88. package/dist/schema/serviceYaml.d.ts.map +1 -0
  89. package/dist/schema/serviceYaml.js +200 -0
  90. package/dist/schema/serviceYaml.js.map +1 -0
  91. package/dist/secrets.d.ts +4 -0
  92. package/dist/secrets.d.ts.map +1 -0
  93. package/dist/secrets.js +31 -0
  94. package/dist/secrets.js.map +1 -0
  95. package/dist/secretsSummary.d.ts +2 -0
  96. package/dist/secretsSummary.d.ts.map +1 -0
  97. package/dist/secretsSummary.js +50 -0
  98. package/dist/secretsSummary.js.map +1 -0
  99. package/dist/services.d.ts +7 -0
  100. package/dist/services.d.ts.map +1 -0
  101. package/dist/services.js +66 -0
  102. package/dist/services.js.map +1 -0
  103. package/dist/sharedDb.d.ts +3 -0
  104. package/dist/sharedDb.d.ts.map +1 -0
  105. package/dist/sharedDb.js +104 -0
  106. package/dist/sharedDb.js.map +1 -0
  107. package/dist/target.d.ts +35 -0
  108. package/dist/target.d.ts.map +1 -0
  109. package/dist/target.js +7 -0
  110. package/dist/target.js.map +1 -0
  111. package/dist/templates/dedicated-postgres.docker.yaml.tmpl +12 -0
  112. package/dist/templates/dedicated-postgres.k8s.yaml.tmpl +57 -0
  113. package/dist/templates/dedicated-redis.docker.yaml.tmpl +9 -0
  114. package/dist/templates/dedicated-redis.k8s.yaml.tmpl +46 -0
  115. package/dist/templating.d.ts +2 -0
  116. package/dist/templating.d.ts.map +1 -0
  117. package/dist/templating.js +15 -0
  118. package/dist/templating.js.map +1 -0
  119. package/package.json +65 -0
@@ -0,0 +1,22 @@
1
+ import { createHash } from "node:crypto";
2
+ // Deterministically derive a non-zero positive int64 (as a decimal string)
3
+ // from a username. Mattermost Team Edition's `gitlab` OAuth provider parses
4
+ // the userinfo `id` field as int64 and rejects 0; Keycloak users have UUID
5
+ // primary keys with no built-in numeric ID, so we hash the username and use
6
+ // that as the user's `mattermost_id` attribute in the realm import.
7
+ //
8
+ // Implementation: take the first 8 bytes of SHA-256(username), interpret as
9
+ // big-endian unsigned 64-bit, mask off the top bit so the value fits in a
10
+ // signed int64, and bump 0 → 1 on the off chance it lands there.
11
+ export function usernameToNumericId(username) {
12
+ const digest = createHash("sha256").update(username, "utf8").digest();
13
+ let n = 0n;
14
+ for (let i = 0; i < 8; i++) {
15
+ n = (n << 8n) | BigInt(digest[i]);
16
+ }
17
+ n &= 0x7fffffffffffffffn;
18
+ if (n === 0n)
19
+ n = 1n;
20
+ return n.toString(10);
21
+ }
22
+ //# sourceMappingURL=numericId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numericId.js","sourceRoot":"","sources":["../src/numericId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,oEAAoE;AACpE,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;IACtE,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;IACrC,CAAC;IACD,CAAC,IAAI,mBAAmB,CAAC;IACzB,IAAI,CAAC,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,CAAC;IACrB,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,81 @@
1
+ import type { ClusterYaml } from "../schema/clusterYaml.js";
2
+ import type { ProviderYaml } from "../schema/providerYaml.js";
3
+ /**
4
+ * Runtime context handed to every imperative lifecycle hook. Lifecycle
5
+ * implementations stay pure-ish by receiving `run`/`capture` callbacks
6
+ * instead of importing `child_process` themselves — this keeps the engine
7
+ * in charge of process orchestration and makes hooks trivially testable
8
+ * with a fake runner.
9
+ */
10
+ export interface LifecycleContext {
11
+ rootDir: string;
12
+ tofuDir: string;
13
+ /** Path that `captureKubeconfig` writes to. */
14
+ kubeconfigPath: string;
15
+ /** Already merged with credential envMap + extraEnv from beforeTofuInit. */
16
+ env: NodeJS.ProcessEnv;
17
+ cluster: ClusterYaml;
18
+ run(cmd: string, args: string[], cwd?: string, env?: NodeJS.ProcessEnv): Promise<void>;
19
+ capture(cmd: string, args: string[], cwd?: string, env?: NodeJS.ProcessEnv): Promise<string>;
20
+ }
21
+ export interface ValidateResult {
22
+ ok: boolean;
23
+ error?: string;
24
+ }
25
+ /**
26
+ * Pure-function hooks invoked from the server + renderer (no process work).
27
+ * These describe how a provider's typed config maps to credentials, where
28
+ * its resources live, and what Kubernetes-side glue it needs.
29
+ */
30
+ export interface ClusterLifecycleStatic {
31
+ /** Credential field → tofu env var name (e.g. "apiToken" → "HCLOUD_TOKEN"). */
32
+ envMap(cluster: ClusterYaml): Record<string, string>;
33
+ /** Human-readable location label for confirmation dialogs etc. */
34
+ locationLabel(cluster: ClusterYaml): string;
35
+ /** Server-side credential validation: pings the provider API. */
36
+ validate?(cluster: ClusterYaml): Promise<ValidateResult>;
37
+ /** Wizard "what am I paying for" listing. Returns the route payload as-is. */
38
+ listResources?(cluster: ClusterYaml): Promise<unknown>;
39
+ /** Live catalog lookup (e.g. orderable node types for a chosen geography). */
40
+ catalogLookup?(cluster: ClusterYaml, kind: string, params: Record<string, string>): Promise<unknown>;
41
+ /** Annotations added to the LoadBalancer Service block in helm values. */
42
+ kubernetesLbAnnotations?(cluster: ClusterYaml, baseDomain: string | undefined): Record<string, string>;
43
+ }
44
+ /**
45
+ * Imperative deploy / destroy hooks. Each runs at a specific point in the
46
+ * CLI pipeline — see deploy.ts / destroy.ts for the call order.
47
+ */
48
+ export interface ClusterLifecycleDynamic {
49
+ /** Extra env vars to set before any `tofu` invocation (SSH key paths, k3s token). */
50
+ beforeTofuInit?(ctx: LifecycleContext): Promise<{
51
+ extraEnv?: Record<string, string>;
52
+ } | void>;
53
+ /** Runs between `tofu init` and `tofu apply` / `tofu destroy` (orphan adoption). */
54
+ beforeTofuOperation?(ctx: LifecycleContext, op: "apply" | "destroy"): Promise<void>;
55
+ /** Returns the kubeconfig contents after `tofu apply`. Default: `tofu output -raw kubeconfig`. */
56
+ captureKubeconfig?(ctx: LifecycleContext): Promise<string>;
57
+ /** Runs after kubeconfig is on disk and the API is ready, before install.sh (e.g. CCM install). */
58
+ afterKubeconfig?(ctx: LifecycleContext): Promise<void>;
59
+ /** Runs after install.sh (e.g. LB target reconciliation). */
60
+ afterInstall?(ctx: LifecycleContext): Promise<void>;
61
+ /** Runs after `tofu destroy` (e.g. sweep up in-cluster-created LBs). */
62
+ afterTofuDestroy?(ctx: LifecycleContext): Promise<void>;
63
+ /** Collect provider-specific deploy metadata (e.g. control plane IP). */
64
+ collectMetadata?(ctx: LifecycleContext): Promise<{
65
+ controlPlaneIp?: string;
66
+ }>;
67
+ }
68
+ export type ClusterLifecycle = ClusterLifecycleStatic & ClusterLifecycleDynamic;
69
+ export interface LoadedProvider {
70
+ manifest: ProviderYaml;
71
+ lifecycle: ClusterLifecycle;
72
+ }
73
+ /**
74
+ * Dynamically import the lifecycle module declared by a provider manifest.
75
+ * The module must export `lifecycle: ClusterLifecycle` as a named export.
76
+ *
77
+ * Tests can inject a synthetic provider via the optional `registry` map
78
+ * keyed by provider name, bypassing the filesystem.
79
+ */
80
+ export declare function loadLifecycle(providerDir: string, manifest: ProviderYaml, registry?: Map<string, ClusterLifecycle>): Promise<LoadedProvider>;
81
+ //# sourceMappingURL=lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/providers/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import path from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ /**
4
+ * Dynamically import the lifecycle module declared by a provider manifest.
5
+ * The module must export `lifecycle: ClusterLifecycle` as a named export.
6
+ *
7
+ * Tests can inject a synthetic provider via the optional `registry` map
8
+ * keyed by provider name, bypassing the filesystem.
9
+ */
10
+ export async function loadLifecycle(providerDir, manifest, registry) {
11
+ const fromRegistry = registry?.get(manifest.name);
12
+ if (fromRegistry)
13
+ return { manifest, lifecycle: fromRegistry };
14
+ const modulePath = path.join(providerDir, manifest.lifecycleModule);
15
+ const url = pathToFileURL(modulePath).href;
16
+ const mod = await import(url);
17
+ if (!mod.lifecycle || typeof mod.lifecycle.envMap !== "function") {
18
+ throw new Error(`Provider ${manifest.name}: ${manifest.lifecycleModule} must export a ClusterLifecycle named "lifecycle"`);
19
+ }
20
+ return { manifest, lifecycle: mod.lifecycle };
21
+ }
22
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/providers/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuFzC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,WAAmB,EACnB,QAAsB,EACtB,QAAwC;IAExC,MAAM,YAAY,GAAG,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,YAAY;QAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAE/D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IAC3C,MAAM,GAAG,GAAqC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;IAChE,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,YAAY,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,eAAe,mDAAmD,CAC1G,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type ProviderYaml } from "./schema/providerYaml.js";
2
+ export type Providers = Map<string, ProviderYaml>;
3
+ export declare function loadProviders(rootDir: string): Promise<Providers>;
4
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEjF,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAElD,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA0CvE"}
@@ -0,0 +1,45 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { ProviderYamlSchema } from "./schema/providerYaml.js";
5
+ export async function loadProviders(rootDir) {
6
+ let entries;
7
+ try {
8
+ entries = await fs.readdir(rootDir, { withFileTypes: true });
9
+ }
10
+ catch (err) {
11
+ if (err.code === "ENOENT") {
12
+ // No catalog at this path — treat as empty (parallels how loadRepository
13
+ // skips directories that lack service.yaml). Callers can still 404 on
14
+ // a missing provider name and act accordingly.
15
+ return new Map();
16
+ }
17
+ throw err;
18
+ }
19
+ const dirs = entries.filter((e) => e.isDirectory());
20
+ const providers = new Map();
21
+ for (const dir of dirs) {
22
+ const yamlPath = path.join(rootDir, dir.name, "provider.yaml");
23
+ let raw;
24
+ try {
25
+ raw = await fs.readFile(yamlPath, "utf8");
26
+ }
27
+ catch {
28
+ // Directory has no provider.yaml — not a provider entry. Skip it.
29
+ continue;
30
+ }
31
+ const parsed = yaml.load(raw);
32
+ const result = ProviderYamlSchema.safeParse(parsed);
33
+ if (!result.success) {
34
+ throw new Error(`Invalid provider.yaml for ${dir.name}: ${result.error.issues
35
+ .map((i) => `${i.path.join(".")}: ${i.message}`)
36
+ .join("; ")}`);
37
+ }
38
+ if (result.data.name !== dir.name) {
39
+ throw new Error(`Provider name "${result.data.name}" does not match directory "${dir.name}"`);
40
+ }
41
+ providers.set(result.data.name, result.data);
42
+ }
43
+ return providers;
44
+ }
45
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAqB,MAAM,0BAA0B,CAAC;AAIjF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAe;IACjD,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,yEAAyE;YACzE,sEAAsE;YACtE,+CAA+C;YAC/C,OAAO,IAAI,GAAG,EAAE,CAAC;QACnB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAEpD,MAAM,SAAS,GAAc,IAAI,GAAG,EAAE,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAC/D,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;YAClE,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,MAAM;iBAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;iBAC/C,IAAI,CAAC,IAAI,CAAC,EAAE,CAChB,CAAC;QACJ,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,kBAAkB,MAAM,CAAC,IAAI,CAAC,IAAI,+BAA+B,GAAG,CAAC,IAAI,GAAG,CAC7E,CAAC;QACJ,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { RenderTargets } from "./target.js";
2
+ export interface RenderOptions {
3
+ /** Project root: contains services/, output/, and global.yaml. */
4
+ projectDir: string;
5
+ /** Service-catalog root: where service.yaml + templates live. May be outside the project. */
6
+ repositoryDir: string;
7
+ /** Provider-catalog root: where provider.yaml + templates live. Defaults to projectDir/providers. */
8
+ providersDir?: string;
9
+ /**
10
+ * Target renderers, injected by the caller. Required for whichever target the
11
+ * project's global.yaml selects (`docker`, `kubernetes`, or `both`). Core has
12
+ * no compile-time dep on the renderer packages — this is what keeps the
13
+ * `@gezelligate/core` ↔ `@gezelligate/{docker,k8s}` cycle from existing.
14
+ */
15
+ targets: RenderTargets;
16
+ }
17
+ export interface RenderResult {
18
+ enabledServices: string[];
19
+ outputFiles: string[];
20
+ }
21
+ export declare function render(opts: RenderOptions): Promise<RenderResult>;
22
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAoBjD,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,qGAAqG;IACrG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA+SvE"}
package/dist/render.js ADDED
@@ -0,0 +1,354 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import yaml from "js-yaml";
5
+ import { loadRepository } from "./repository.js";
6
+ import { loadServices, loadEnv, writeEnv } from "./services.js";
7
+ import { resolveEnabledServices } from "./dependencies.js";
8
+ import { generateMissingSecrets } from "./secrets.js";
9
+ import { buildRealmImport, userTempPasswordKey } from "./keycloak.js";
10
+ import { generateSecret } from "./secrets.js";
11
+ import { loadClusterConfig, renderClusterModule } from "./cluster.js";
12
+ import { loadProviders } from "./providers.js";
13
+ import { loadLifecycle } from "./providers/lifecycle.js";
14
+ import { buildSecretsSummary } from "./secretsSummary.js";
15
+ import { buildInitSql } from "./sharedDb.js";
16
+ import { buildBridgeManifest } from "./bridgeManifest.js";
17
+ import { findOne } from "./capabilities.js";
18
+ import { resolveDbContext, resolveRedisContext, emitDedicatedPostgresDocker, emitDedicatedPostgresK8s, emitDedicatedRedisDocker, emitDedicatedRedisK8s } from "./dedicatedPeer.js";
19
+ import { GlobalConfigSchema } from "./schema/configYaml.js";
20
+ export async function render(opts) {
21
+ const repoDir = opts.repositoryDir;
22
+ const providersDir = opts.providersDir ?? path.join(opts.projectDir, "providers");
23
+ const servicesDir = path.join(opts.projectDir, "services");
24
+ const outputDir = path.join(opts.projectDir, "output");
25
+ const global = await loadGlobalConfig(opts.projectDir);
26
+ const effectiveGlobal = {
27
+ ...global,
28
+ baseDomain: global.baseDomain ?? (global.mode === "local" ? "localhost" : undefined)
29
+ };
30
+ if (effectiveGlobal.baseDomain === undefined) {
31
+ throw new Error("baseDomain is required in public mode");
32
+ }
33
+ const repo = await loadRepository(repoDir);
34
+ const services = await loadServices(servicesDir);
35
+ const enabled = resolveEnabledServices(services, repo);
36
+ // For each enabled service: load .env, fill in missing secrets, persist.
37
+ // First pass: build env-only states.
38
+ const envStates = [];
39
+ const envByService = {};
40
+ for (const [name, cfg] of enabled) {
41
+ const def = repo.get(name);
42
+ const existingEnv = await loadEnv(servicesDir, name);
43
+ const env = generateMissingSecrets(def.secrets, existingEnv);
44
+ await writeEnv(servicesDir, name, env);
45
+ envStates.push({ def, config: cfg, env });
46
+ envByService[name] = env;
47
+ }
48
+ // Identify shared peer providers by capability (never by name).
49
+ const sharedDbProvider = envStates.find((s) => s.def.provides.sharedDatabase !== undefined);
50
+ const sharedRedisProvider = envStates.find((s) => s.def.provides.sharedRedis !== undefined);
51
+ // Second pass: enrich each state with resolved db / redis contexts.
52
+ const states = envStates.map((s) => ({
53
+ ...s,
54
+ db: resolveDbContext(s.def, sharedDbProvider?.def.name),
55
+ redis: resolveRedisContext(s.def, sharedRedisProvider?.def.name)
56
+ }));
57
+ // Combine all env vars (prefixed) so realm-import can find OIDC client secrets.
58
+ const combinedEnv = {};
59
+ for (const [name, env] of Object.entries(envByService)) {
60
+ const prefix = name.replace(/-/g, "_").toUpperCase();
61
+ for (const [k, v] of Object.entries(env)) {
62
+ combinedEnv[k] = v; // unprefixed for direct lookups
63
+ combinedEnv[`${prefix}_${k}`] = v; // prefixed mirrors compose .env
64
+ }
65
+ }
66
+ // Load all per-service templates + cluster-provider templates into one map.
67
+ const templates = await loadAllTemplates(repoDir, providersDir, repo);
68
+ const enginePeerTemplates = await loadEnginePeerTemplates();
69
+ // Build Keycloak realm import. The admin password (and the user-seeding env
70
+ // it lives in) comes from whichever service declares `provides.userSeed` —
71
+ // looked up by capability, not by hardcoded service name, so a recipe could
72
+ // ship a different OIDC server and still drive the seeding logic.
73
+ const seeder = findOne(states, "userSeed");
74
+ const seederName = seeder?.def.name;
75
+ const passwordEnvKey = seeder?.def.provides.userSeed?.passwordEnv;
76
+ const adminPassword = (seederName && passwordEnvKey)
77
+ ? envByService[seederName]?.[passwordEnvKey] ?? "admin"
78
+ : "admin";
79
+ const { seeded: seedUsers, updatedEnv: seederEnvWithUserPasswords } = await resolveSeedUsers(servicesDir, seederName ? enabled.get(seederName)?.users : undefined, seederName, seederName ? envByService[seederName] ?? {} : {});
80
+ if (seederName && envByService[seederName]) {
81
+ envByService[seederName] = seederEnvWithUserPasswords;
82
+ }
83
+ const realmImport = buildRealmImport(states, effectiveGlobal, combinedEnv, adminPassword, seedUsers);
84
+ // Compute shared-postgres init SQL once — reused by both docker and k8s targets.
85
+ const postgresInitSql = buildInitSql(states);
86
+ // Build bridge manifest only when the bridge launcher itself is in the
87
+ // enabled set — otherwise there's no consumer for the manifest. Bridge is
88
+ // identified by the bridgeReader capability so engine never depends on
89
+ // the service literally being named "bridge".
90
+ const bridgeEnabled = findOne(states, "bridgeReader") !== undefined;
91
+ const bridgeManifest = bridgeEnabled
92
+ ? buildBridgeManifest(states, effectiveGlobal)
93
+ : { apexDomain: effectiveGlobal.baseDomain, services: [], share: {} };
94
+ const bridgeManifestJson = (bridgeEnabled && bridgeManifest.services.length > 0)
95
+ ? JSON.stringify(bridgeManifest, null, 2)
96
+ : undefined;
97
+ // Read each bridge-providing service's icon SVG once. Docker copies these
98
+ // to disk; k8s bakes them into a `bridge-icons` ConfigMap. Missing icons
99
+ // are silently skipped so services aren't forced to ship one.
100
+ const bridgeIconsByService = {};
101
+ if (bridgeManifestJson) {
102
+ for (const s of states) {
103
+ if (!s.def.provides.bridge)
104
+ continue;
105
+ const src = path.join(repoDir, s.def.name, "assets", "icon.svg");
106
+ try {
107
+ bridgeIconsByService[s.def.name] = await fs.readFile(src, "utf8");
108
+ }
109
+ catch {
110
+ /* no icon shipped */
111
+ }
112
+ }
113
+ }
114
+ // Build dedicated-peer sidecar fragments (docker) and manifests (k8s) up
115
+ // front so both targets can consume them. Services that resolve to a shared
116
+ // peer contribute nothing here; only `mode === "dedicated"` produces output.
117
+ const dedicatedDockerFragments = [];
118
+ const dedicatedK8sManifests = {};
119
+ const DEFAULT_DB_STORAGE = "10Gi";
120
+ const DEFAULT_REDIS_STORAGE = "2Gi";
121
+ for (const s of states) {
122
+ if (s.db?.mode === "dedicated") {
123
+ const upper = s.def.name.replace(/-/g, "_").toUpperCase();
124
+ dedicatedDockerFragments.push(emitDedicatedPostgresDocker({
125
+ name: s.db.host,
126
+ dbName: s.db.name,
127
+ dbUser: s.db.user,
128
+ passwordRef: `${upper}_DB_PASSWORD`,
129
+ storage: s.def.database?.storage ?? DEFAULT_DB_STORAGE
130
+ }, enginePeerTemplates.postgresDocker));
131
+ dedicatedK8sManifests[`manifests/${s.db.host}.yaml`] = emitDedicatedPostgresK8s({
132
+ name: s.db.host,
133
+ consumerName: s.def.name,
134
+ dbName: s.db.name,
135
+ dbUser: s.db.user,
136
+ port: s.db.port,
137
+ storage: s.def.database?.storage ?? DEFAULT_DB_STORAGE
138
+ }, enginePeerTemplates.postgresK8s);
139
+ }
140
+ if (s.redis?.mode === "dedicated") {
141
+ dedicatedDockerFragments.push(emitDedicatedRedisDocker({ name: s.redis.host, storage: DEFAULT_REDIS_STORAGE }, enginePeerTemplates.redisDocker));
142
+ dedicatedK8sManifests[`manifests/${s.redis.host}.yaml`] = emitDedicatedRedisK8s({ name: s.redis.host, port: s.redis.port, storage: DEFAULT_REDIS_STORAGE }, enginePeerTemplates.redisK8s);
143
+ }
144
+ }
145
+ const outputFileList = [];
146
+ // Render docker target.
147
+ if (effectiveGlobal.target === "docker" || effectiveGlobal.target === "both") {
148
+ if (!opts.targets.docker) {
149
+ throw new Error(`global.target=${effectiveGlobal.target} requires opts.targets.docker; pass renderDockerTarget from @gezelligate/docker`);
150
+ }
151
+ const dockerFiles = opts.targets.docker(states, effectiveGlobal, templates, {}, dedicatedDockerFragments);
152
+ dockerFiles["realm-import.json"] = JSON.stringify(realmImport, null, 2);
153
+ if (postgresInitSql) {
154
+ dockerFiles["postgres-init.sql"] = postgresInitSql;
155
+ }
156
+ if (bridgeManifestJson) {
157
+ dockerFiles["bridge-manifest.json"] = bridgeManifestJson;
158
+ }
159
+ const dockerOut = path.join(outputDir, "docker");
160
+ await fs.rm(dockerOut, { recursive: true, force: true });
161
+ await fs.mkdir(dockerOut, { recursive: true });
162
+ for (const [name, content] of Object.entries(dockerFiles)) {
163
+ await fs.writeFile(path.join(dockerOut, name), content, "utf8");
164
+ outputFileList.push(path.join("docker", name));
165
+ }
166
+ // Bundle per-service icons for the bridge to serve at /icons/<id>.svg.
167
+ if (bridgeManifestJson && Object.keys(bridgeIconsByService).length > 0) {
168
+ const iconsDir = path.join(dockerOut, "bridge-icons");
169
+ await fs.mkdir(iconsDir, { recursive: true });
170
+ for (const [name, svg] of Object.entries(bridgeIconsByService)) {
171
+ const dst = path.join(iconsDir, `${name}.svg`);
172
+ await fs.writeFile(dst, svg, "utf8");
173
+ outputFileList.push(path.join("docker", "bridge-icons", `${name}.svg`));
174
+ }
175
+ }
176
+ }
177
+ // Render kubernetes target.
178
+ if (effectiveGlobal.target === "kubernetes" || effectiveGlobal.target === "both") {
179
+ // Load cluster + dispatch to the provider's lifecycle so the k8s target
180
+ // can emit provider-specific LB annotations into traefik-values.yaml
181
+ // (engine stays generic; the annotation contents live in the provider
182
+ // catalog).
183
+ const clusterForK8s = await loadClusterConfig(opts.projectDir);
184
+ let lbAnnotations = {};
185
+ if (clusterForK8s) {
186
+ const providers = await loadProviders(providersDir);
187
+ const manifest = providers.get(clusterForK8s.provider);
188
+ if (manifest) {
189
+ const provider = await loadLifecycle(path.join(providersDir, manifest.name), manifest);
190
+ lbAnnotations =
191
+ provider.lifecycle.kubernetesLbAnnotations?.(clusterForK8s, effectiveGlobal.baseDomain) ?? {};
192
+ }
193
+ }
194
+ if (!opts.targets.kubernetes) {
195
+ throw new Error(`global.target=${effectiveGlobal.target} requires opts.targets.kubernetes; pass renderKubernetesTarget from @gezelligate/k8s`);
196
+ }
197
+ const k8sFiles = opts.targets.kubernetes(states, effectiveGlobal, templates, {
198
+ realmImport: JSON.stringify(realmImport, null, 2),
199
+ postgresInitSql: postgresInitSql || undefined,
200
+ bridgeManifestJson,
201
+ bridgeIconsByService,
202
+ dedicatedPeerManifests: dedicatedK8sManifests
203
+ }, lbAnnotations);
204
+ const k8sOut = path.join(outputDir, "kubernetes");
205
+ // Preserve state-bearing files across re-renders. Wiping `terraform.tfstate`
206
+ // would orphan every cloud resource Terraform has created, forcing a
207
+ // painful re-import on the next deploy. Same deal for the kubeconfig we
208
+ // fetched post-deploy and the provider plugin cache.
209
+ const preservedRelPaths = [
210
+ "opentofu/terraform.tfstate",
211
+ "opentofu/terraform.tfstate.backup",
212
+ "opentofu/.terraform.lock.hcl",
213
+ "opentofu/.terraform",
214
+ // The null_resource.fetch_kubeconfig provisioner writes here; it only
215
+ // re-runs on resource-creation, so losing the file between applies
216
+ // would leave deploy.ts unable to read the cluster's kubeconfig.
217
+ "opentofu/kubeconfig.yaml",
218
+ "kubeconfig.yaml"
219
+ ];
220
+ const preserved = [];
221
+ const tmpRoot = path.join(outputDir, `.preserve-${Date.now()}`);
222
+ for (const rel of preservedRelPaths) {
223
+ const abs = path.join(k8sOut, rel);
224
+ try {
225
+ await fs.access(abs);
226
+ }
227
+ catch {
228
+ continue;
229
+ }
230
+ const tmp = path.join(tmpRoot, rel);
231
+ await fs.mkdir(path.dirname(tmp), { recursive: true });
232
+ await fs.rename(abs, tmp);
233
+ preserved.push({ rel, tmp });
234
+ }
235
+ await fs.rm(k8sOut, { recursive: true, force: true });
236
+ await fs.mkdir(k8sOut, { recursive: true });
237
+ for (const p of preserved) {
238
+ const abs = path.join(k8sOut, p.rel);
239
+ await fs.mkdir(path.dirname(abs), { recursive: true });
240
+ await fs.rename(p.tmp, abs);
241
+ }
242
+ await fs.rm(tmpRoot, { recursive: true, force: true });
243
+ for (const [name, content] of Object.entries(k8sFiles)) {
244
+ const full = path.join(k8sOut, name);
245
+ await fs.mkdir(path.dirname(full), { recursive: true });
246
+ await fs.writeFile(full, content, "utf8");
247
+ if (name === "install.sh") {
248
+ await fs.chmod(full, 0o755);
249
+ }
250
+ outputFileList.push(path.join("kubernetes", name));
251
+ }
252
+ const cluster = clusterForK8s;
253
+ if (cluster) {
254
+ const tfFiles = renderClusterModule(cluster, templates);
255
+ for (const [rel, contents] of Object.entries(tfFiles)) {
256
+ const abs = path.join(k8sOut, rel);
257
+ await fs.mkdir(path.dirname(abs), { recursive: true });
258
+ await fs.writeFile(abs, contents, "utf8");
259
+ outputFileList.push(path.join("kubernetes", rel));
260
+ }
261
+ }
262
+ }
263
+ // Secrets summary.
264
+ const hiddenServices = new Set([...repo.entries()].filter(([, def]) => def.hidden === true).map(([name]) => name));
265
+ await fs.writeFile(path.join(outputDir, "secrets-summary.md"), buildSecretsSummary(envByService, hiddenServices), "utf8");
266
+ outputFileList.push("secrets-summary.md");
267
+ return {
268
+ enabledServices: Array.from(enabled.keys()),
269
+ outputFiles: outputFileList
270
+ };
271
+ }
272
+ async function resolveSeedUsers(servicesDir, users, seederName, existingSeederEnv) {
273
+ if (!users || users.length === 0 || !seederName) {
274
+ return { seeded: [], updatedEnv: existingSeederEnv };
275
+ }
276
+ const envOut = { ...existingSeederEnv };
277
+ const seeded = [];
278
+ let dirty = false;
279
+ for (const u of users) {
280
+ const key = userTempPasswordKey(u.username);
281
+ let password = envOut[key];
282
+ if (password === undefined) {
283
+ password = generateSecret({ key, generator: "password", length: 20 });
284
+ envOut[key] = password;
285
+ dirty = true;
286
+ }
287
+ seeded.push({ ...u, tempPassword: password });
288
+ }
289
+ if (dirty) {
290
+ const { writeEnv } = await import("./services.js");
291
+ await writeEnv(servicesDir, seederName, envOut);
292
+ }
293
+ return { seeded, updatedEnv: envOut };
294
+ }
295
+ async function loadGlobalConfig(rootDir) {
296
+ const cfgPath = path.join(rootDir, "services", "global.yaml");
297
+ const raw = await fs.readFile(cfgPath, "utf8");
298
+ return GlobalConfigSchema.parse(yaml.load(raw));
299
+ }
300
+ async function loadEnginePeerTemplates() {
301
+ const here = path.dirname(fileURLToPath(import.meta.url));
302
+ const tmplDir = path.join(here, "templates");
303
+ const [postgresDocker, postgresK8s, redisDocker, redisK8s] = await Promise.all([
304
+ fs.readFile(path.join(tmplDir, "dedicated-postgres.docker.yaml.tmpl"), "utf8"),
305
+ fs.readFile(path.join(tmplDir, "dedicated-postgres.k8s.yaml.tmpl"), "utf8"),
306
+ fs.readFile(path.join(tmplDir, "dedicated-redis.docker.yaml.tmpl"), "utf8"),
307
+ fs.readFile(path.join(tmplDir, "dedicated-redis.k8s.yaml.tmpl"), "utf8")
308
+ ]);
309
+ return { postgresDocker, postgresK8s, redisDocker, redisK8s };
310
+ }
311
+ async function loadAllTemplates(repoDir, providersDir, repo) {
312
+ const out = new Map();
313
+ for (const [name, def] of repo) {
314
+ const dockerTmpl = def.targets.docker?.template;
315
+ if (dockerTmpl) {
316
+ const raw = await fs.readFile(path.join(repoDir, name, dockerTmpl), "utf8");
317
+ out.set(`${name}/${dockerTmpl}`, raw);
318
+ }
319
+ const k8sTmpl = def.targets.kubernetes?.valuesTemplate;
320
+ if (k8sTmpl) {
321
+ const raw = await fs.readFile(path.join(repoDir, name, k8sTmpl), "utf8");
322
+ out.set(`${name}/${k8sTmpl}`, raw);
323
+ }
324
+ }
325
+ // Load cluster provider templates from /providers/<name>/templates/*.tmpl.
326
+ // Keys are provider-relative paths matching what renderClusterModule looks up.
327
+ try {
328
+ const providers = await fs.readdir(providersDir, { withFileTypes: true });
329
+ for (const entry of providers) {
330
+ if (!entry.isDirectory())
331
+ continue;
332
+ const tmplDir = path.join(providersDir, entry.name, "templates");
333
+ let files;
334
+ try {
335
+ files = await fs.readdir(tmplDir);
336
+ }
337
+ catch {
338
+ continue; // no templates/ subdir — skip
339
+ }
340
+ for (const file of files) {
341
+ const abs = path.join(tmplDir, file);
342
+ const raw = await fs.readFile(abs, "utf8");
343
+ // Key must match PROVIDER_TEMPLATE_DIR in cluster.ts:
344
+ // "providers/<name>/templates/<file>"
345
+ out.set(`providers/${entry.name}/templates/${file}`, raw);
346
+ }
347
+ }
348
+ }
349
+ catch {
350
+ // No providers/ directory — tolerate gracefully.
351
+ }
352
+ return out;
353
+ }
354
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ServiceYaml } from "./schema/serviceYaml.js";
2
+ export type Repository = Map<string, ServiceYaml>;
3
+ export declare function loadRepository(rootDir: string): Promise<Repository>;
4
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE9E,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAElD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BzE"}