@varius.io/framework 13.11.4 → 13.12.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.
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from "child_process";
4
+ import fsp from "node:fs/promises";
5
+ import { format } from "node:util";
6
+
7
+ const vaultApiBase = process.env.VAULT_ENV_VAULT_API_BASE;
8
+
9
+ async function getKubernetesServiceAccountToken() {
10
+ const buffer = await fsp.readFile("/var/run/secrets/kubernetes.io/serviceaccount/token");
11
+ return buffer.toString("utf8");
12
+ }
13
+
14
+ async function fetchVaultTokenViaKubernetesAuth(role) {
15
+ const jwt = await getKubernetesServiceAccountToken();
16
+
17
+ const res = await fetch(`${vaultApiBase}/v1/auth/kubernetes/login`, {
18
+ method: "POST",
19
+ headers: { "content-type": "application/json" },
20
+ body: JSON.stringify({ role, jwt }),
21
+ });
22
+
23
+ if (!res.ok) {
24
+ throw new Error(
25
+ format(
26
+ `Error fetching vault token via kubernetes auth, role=%j, httpStatusCode=%j`,
27
+ role,
28
+ res.status
29
+ )
30
+ );
31
+ }
32
+
33
+ const resBody = await res.json();
34
+ return resBody.auth.client_token;
35
+ }
36
+
37
+ async function getVaultToken() {
38
+ const envToken = process.env.VAULT_ENV_VAULT_TOKEN;
39
+ const envRole = process.env.VAULT_ENV_ROLE;
40
+
41
+ if (envToken) {
42
+ return envToken;
43
+ } else if (envRole) {
44
+ return await fetchVaultTokenViaKubernetesAuth(envRole);
45
+ } else {
46
+ throw new Error("No available vault auth mechanism.");
47
+ }
48
+ }
49
+
50
+ async function fetchSecret(secretPath) {
51
+ const res = await fetch(`${vaultApiBase}/v1/${secretPath}`, {
52
+ headers: { "X-Vault-Token": await getVaultToken() },
53
+ });
54
+
55
+ if (!res.ok) {
56
+ throw new Error(
57
+ format(`Failed to fetch secret, secretPath=%j, httpStatusCode=%j`, secretPath, res.status)
58
+ );
59
+ }
60
+
61
+ const resBody = await res.json();
62
+ return resBody.data;
63
+ }
64
+
65
+ const resolvedSecrets = new Map();
66
+
67
+ export async function resolveEnv() {
68
+ const newEnv = {};
69
+ const secretEnvVars = [];
70
+
71
+ for (const [envKey, envValue] of Object.entries(process.env)) {
72
+ if (envValue.startsWith("vault:")) {
73
+ const [secretPath, secretPropertyName] = envValue.split("vault:")[1].split("#");
74
+ secretEnvVars.push({ envKey, secretPath, secretPropertyName });
75
+ }
76
+ }
77
+
78
+ async function getSecret(secretPath) {
79
+ resolvedSecrets.set(secretPath, await fetchSecret(secretPath));
80
+ }
81
+
82
+ const secretPaths = Array.from(new Set(secretEnvVars.map(envVar => envVar.secretPath)));
83
+ await Promise.all(secretPaths.map(getSecret));
84
+
85
+ for (const envVar of secretEnvVars) {
86
+ const secret = resolvedSecrets.get(envVar.secretPath);
87
+ const secretPropertyValue = secret.data[envVar.secretPropertyName];
88
+ newEnv[envVar.envKey] = secretPropertyValue;
89
+ }
90
+
91
+ return newEnv;
92
+ }
93
+
94
+ function spawnChildProcess() {
95
+ // remove this script's args (before "--" separator)
96
+ while (process.argv[0] !== "--") {
97
+ process.argv.shift();
98
+ }
99
+
100
+ // remove "--" separator
101
+ process.argv.shift();
102
+
103
+ const childCommand = process.argv.shift();
104
+
105
+ const child = spawn(childCommand, process.argv, {
106
+ cwd: process.cwd(),
107
+ env: process.env,
108
+ stdio: "inherit",
109
+ });
110
+
111
+ child.on("error", function(e) {
112
+ console.error(e);
113
+ });
114
+ }
115
+
116
+ async function main() {
117
+ // need to temporarily allow self-signed certs
118
+ const oldRejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
119
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
120
+
121
+ const newEnv = await setupEnv();
122
+
123
+ // reset self-signed cert permission, for the child process
124
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = oldRejectUnauthorized;
125
+
126
+ process.env = { ...process.env, ...newEnv };
127
+
128
+ for (const key of Object.keys(process.env)) {
129
+ if (key.startsWith("VAULT_ENV")) {
130
+ delete process.env[key];
131
+ }
132
+ }
133
+
134
+ spawnChildProcess();
135
+ }
136
+
137
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varius.io/framework",
3
- "version": "13.11.4",
3
+ "version": "13.12.0",
4
4
  "main": "./build/index.js",
5
5
  "type": "./build/index.d.ts",
6
6
  "scripts": {
@@ -79,6 +79,10 @@
79
79
  },
80
80
  "homepage": "https://github.com/VariusIO/framework#readme",
81
81
  "files": [
82
- "build"
83
- ]
82
+ "build",
83
+ "bin"
84
+ ],
85
+ "bin": {
86
+ "vatom-vault-env": "bin/vatom-vault-env.mjs"
87
+ }
84
88
  }