@mesh-tech/mesh-cli 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.
- package/dist/bin/mesh.d.ts +16 -0
- package/dist/bin/mesh.d.ts.map +1 -0
- package/dist/bin/mesh.js +40 -0
- package/dist/bin/mesh.js.map +1 -0
- package/dist/src/commands/create-app.d.ts +10 -0
- package/dist/src/commands/create-app.d.ts.map +1 -0
- package/dist/src/commands/create-app.js +176 -0
- package/dist/src/commands/create-app.js.map +1 -0
- package/dist/src/commands/db/connect.d.ts +13 -0
- package/dist/src/commands/db/connect.d.ts.map +1 -0
- package/dist/src/commands/db/connect.js +68 -0
- package/dist/src/commands/db/connect.js.map +1 -0
- package/dist/src/commands/db/credentials.d.ts +16 -0
- package/dist/src/commands/db/credentials.d.ts.map +1 -0
- package/dist/src/commands/db/credentials.js +56 -0
- package/dist/src/commands/db/credentials.js.map +1 -0
- package/dist/src/commands/db/env.d.ts +15 -0
- package/dist/src/commands/db/env.d.ts.map +1 -0
- package/dist/src/commands/db/env.js +50 -0
- package/dist/src/commands/db/env.js.map +1 -0
- package/dist/src/commands/db/exec.d.ts +54 -0
- package/dist/src/commands/db/exec.d.ts.map +1 -0
- package/dist/src/commands/db/exec.js +331 -0
- package/dist/src/commands/db/exec.js.map +1 -0
- package/dist/src/commands/db/index.d.ts +12 -0
- package/dist/src/commands/db/index.d.ts.map +1 -0
- package/dist/src/commands/db/index.js +62 -0
- package/dist/src/commands/db/index.js.map +1 -0
- package/dist/src/commands/db/psql.d.ts +16 -0
- package/dist/src/commands/db/psql.d.ts.map +1 -0
- package/dist/src/commands/db/psql.js +133 -0
- package/dist/src/commands/db/psql.js.map +1 -0
- package/dist/src/commands/deploy.d.ts +24 -0
- package/dist/src/commands/deploy.d.ts.map +1 -0
- package/dist/src/commands/deploy.js +228 -0
- package/dist/src/commands/deploy.js.map +1 -0
- package/dist/src/commands/dev.d.ts +17 -0
- package/dist/src/commands/dev.d.ts.map +1 -0
- package/dist/src/commands/dev.js +1248 -0
- package/dist/src/commands/dev.js.map +1 -0
- package/dist/src/commands/devbox.d.ts +22 -0
- package/dist/src/commands/devbox.d.ts.map +1 -0
- package/dist/src/commands/devbox.js +463 -0
- package/dist/src/commands/devbox.js.map +1 -0
- package/dist/src/commands/login.d.ts +47 -0
- package/dist/src/commands/login.d.ts.map +1 -0
- package/dist/src/commands/login.js +344 -0
- package/dist/src/commands/login.js.map +1 -0
- package/dist/src/commands/registry.d.ts +20 -0
- package/dist/src/commands/registry.d.ts.map +1 -0
- package/dist/src/commands/registry.js +336 -0
- package/dist/src/commands/registry.js.map +1 -0
- package/dist/src/commands/secrets/exec.d.ts +17 -0
- package/dist/src/commands/secrets/exec.d.ts.map +1 -0
- package/dist/src/commands/secrets/exec.js +132 -0
- package/dist/src/commands/secrets/exec.js.map +1 -0
- package/dist/src/commands/secrets/index.d.ts +10 -0
- package/dist/src/commands/secrets/index.d.ts.map +1 -0
- package/dist/src/commands/secrets/index.js +35 -0
- package/dist/src/commands/secrets/index.js.map +1 -0
- package/dist/src/commands/secrets/set.d.ts +22 -0
- package/dist/src/commands/secrets/set.d.ts.map +1 -0
- package/dist/src/commands/secrets/set.js +234 -0
- package/dist/src/commands/secrets/set.js.map +1 -0
- package/dist/src/commands/stack.d.ts +17 -0
- package/dist/src/commands/stack.d.ts.map +1 -0
- package/dist/src/commands/stack.js +175 -0
- package/dist/src/commands/stack.js.map +1 -0
- package/dist/src/commands/tunnel/index.d.ts +14 -0
- package/dist/src/commands/tunnel/index.d.ts.map +1 -0
- package/dist/src/commands/tunnel/index.js +217 -0
- package/dist/src/commands/tunnel/index.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/utils/bastion.d.ts +43 -0
- package/dist/src/utils/bastion.d.ts.map +1 -0
- package/dist/src/utils/bastion.js +77 -0
- package/dist/src/utils/bastion.js.map +1 -0
- package/dist/src/utils/context.d.ts +29 -0
- package/dist/src/utils/context.d.ts.map +1 -0
- package/dist/src/utils/context.js +132 -0
- package/dist/src/utils/context.js.map +1 -0
- package/dist/src/utils/credentials.d.ts +61 -0
- package/dist/src/utils/credentials.d.ts.map +1 -0
- package/dist/src/utils/credentials.js +145 -0
- package/dist/src/utils/credentials.js.map +1 -0
- package/dist/src/utils/index.d.ts +9 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +9 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/log.d.ts +8 -0
- package/dist/src/utils/log.d.ts.map +1 -0
- package/dist/src/utils/log.js +17 -0
- package/dist/src/utils/log.js.map +1 -0
- package/dist/src/utils/pulumi.d.ts +24 -0
- package/dist/src/utils/pulumi.d.ts.map +1 -0
- package/dist/src/utils/pulumi.js +63 -0
- package/dist/src/utils/pulumi.js.map +1 -0
- package/package.json +50 -0
- package/templates/api-web-db/api/.dockerignore +2 -0
- package/templates/api-web-db/api/Dockerfile +16 -0
- package/templates/api-web-db/api/package.json.hbs +21 -0
- package/templates/api-web-db/api/src/index.ts.hbs +123 -0
- package/templates/api-web-db/api/tsconfig.json +13 -0
- package/templates/api-web-db/package.json.hbs +27 -0
- package/templates/api-web-db/sst.config.ts.hbs +151 -0
- package/templates/api-web-db/tsconfig.json +11 -0
- package/templates/api-web-db/web/.dockerignore +3 -0
- package/templates/api-web-db/web/Dockerfile +17 -0
- package/templates/api-web-db/web/app/lib/db.server.ts +36 -0
- package/templates/api-web-db/web/app/root.tsx +29 -0
- package/templates/api-web-db/web/app/routes/home.tsx.hbs +114 -0
- package/templates/api-web-db/web/app/routes.ts +3 -0
- package/templates/api-web-db/web/package.json.hbs +30 -0
- package/templates/api-web-db/web/prisma/schema.prisma +25 -0
- package/templates/api-web-db/web/prisma.config.ts +18 -0
- package/templates/api-web-db/web/react-router.config.ts +5 -0
- package/templates/api-web-db/web/tsconfig.json +19 -0
- package/templates/api-web-db/web/vite.config.ts +9 -0
- package/templates/temporal-api-worker/README.md.hbs +133 -0
- package/templates/temporal-api-worker/api/.dockerignore +4 -0
- package/templates/temporal-api-worker/api/Dockerfile +13 -0
- package/templates/temporal-api-worker/api/package.json.hbs +23 -0
- package/templates/temporal-api-worker/api/src/encryption-codec.ts +133 -0
- package/templates/temporal-api-worker/api/src/index.ts.hbs +145 -0
- package/templates/temporal-api-worker/api/tsconfig.json +14 -0
- package/templates/temporal-api-worker/package.json.hbs +29 -0
- package/templates/temporal-api-worker/sst.config.ts.hbs +161 -0
- package/templates/temporal-api-worker/tsconfig.json +10 -0
- package/templates/temporal-api-worker/worker/.dockerignore +4 -0
- package/templates/temporal-api-worker/worker/Dockerfile +11 -0
- package/templates/temporal-api-worker/worker/package.json.hbs +25 -0
- package/templates/temporal-api-worker/worker/src/activities.ts.hbs +49 -0
- package/templates/temporal-api-worker/worker/src/bundle-workflows.ts +38 -0
- package/templates/temporal-api-worker/worker/src/encryption-codec.ts +156 -0
- package/templates/temporal-api-worker/worker/src/worker.ts.hbs +93 -0
- package/templates/temporal-api-worker/worker/src/workflows.ts.hbs +60 -0
- package/templates/temporal-api-worker/worker/tsconfig.json +14 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh secrets set — Set credentials for an external service.
|
|
3
|
+
*
|
|
4
|
+
* Reads the credential field schema from SSM (written by ExternalService),
|
|
5
|
+
* prompts interactively for each field, and writes to Secrets Manager.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* mesh secrets set external/symitar # single-instance
|
|
9
|
+
* mesh secrets set external/symitar --key=12345 # multi-instance (specific key)
|
|
10
|
+
* mesh secrets set external/symitar --all # include optional fields
|
|
11
|
+
* mesh secrets set external/symitar --non-interactive --json='{"baseUrl":"..."}'
|
|
12
|
+
*
|
|
13
|
+
* The command detects tenant/stage from Pulumi config in the current directory.
|
|
14
|
+
*/
|
|
15
|
+
import { SSMClient, GetParametersByPathCommand, } from "@aws-sdk/client-ssm";
|
|
16
|
+
import { SecretsManagerClient, GetSecretValueCommand, PutSecretValueCommand, CreateSecretCommand, } from "@aws-sdk/client-secrets-manager";
|
|
17
|
+
import input from "@inquirer/input";
|
|
18
|
+
import password from "@inquirer/password";
|
|
19
|
+
import { detectContext } from "../../utils/context.js";
|
|
20
|
+
import { logInfo, logSuccess, logError } from "../../utils/log.js";
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// Interactive prompt (using @inquirer/input and @inquirer/password)
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// SSM discovery
|
|
26
|
+
// =============================================================================
|
|
27
|
+
async function discoverExternalServices(ssmClient, tenant, platformEnv) {
|
|
28
|
+
const services = new Map();
|
|
29
|
+
// Scan all apps for external-services
|
|
30
|
+
const basePath = `/mesh-platform/${tenant}/${platformEnv}`;
|
|
31
|
+
let nextToken;
|
|
32
|
+
do {
|
|
33
|
+
const response = await ssmClient.send(new GetParametersByPathCommand({
|
|
34
|
+
Path: basePath,
|
|
35
|
+
Recursive: true,
|
|
36
|
+
NextToken: nextToken,
|
|
37
|
+
}));
|
|
38
|
+
for (const param of response.Parameters ?? []) {
|
|
39
|
+
if (!param.Name || !param.Value)
|
|
40
|
+
continue;
|
|
41
|
+
// Match: .../apps/{app}/stacks/{stack}/external-services/{name}/meta
|
|
42
|
+
const metaMatch = param.Name.match(/\/external-services\/([^/]+)\/meta$/);
|
|
43
|
+
if (metaMatch?.[1]) {
|
|
44
|
+
const serviceName = metaMatch[1];
|
|
45
|
+
const meta = JSON.parse(param.Value);
|
|
46
|
+
const existing = services.get(serviceName);
|
|
47
|
+
services.set(serviceName, { ...existing, meta });
|
|
48
|
+
}
|
|
49
|
+
// Match: .../external-services/{name}/credentials
|
|
50
|
+
const credMatch = param.Name.match(/\/external-services\/([^/]+)\/credentials$/);
|
|
51
|
+
if (credMatch?.[1]) {
|
|
52
|
+
const serviceName = credMatch[1];
|
|
53
|
+
const schema = JSON.parse(param.Value);
|
|
54
|
+
const existing = services.get(serviceName);
|
|
55
|
+
if (existing) {
|
|
56
|
+
existing.schema = schema;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
services.set(serviceName, { meta: {}, schema });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
nextToken = response.NextToken;
|
|
64
|
+
} while (nextToken);
|
|
65
|
+
return services;
|
|
66
|
+
}
|
|
67
|
+
// =============================================================================
|
|
68
|
+
// Main command
|
|
69
|
+
// =============================================================================
|
|
70
|
+
export async function setCommand(servicePath, opts) {
|
|
71
|
+
const context = detectContext(opts.stage);
|
|
72
|
+
const region = opts.region ?? process.env.AWS_REGION ?? "us-east-2";
|
|
73
|
+
const ssmClient = new SSMClient({ region });
|
|
74
|
+
const smClient = new SecretsManagerClient({ region });
|
|
75
|
+
// Discover all external services
|
|
76
|
+
const services = await discoverExternalServices(ssmClient, context.tenant, context.platformEnv);
|
|
77
|
+
if (services.size === 0) {
|
|
78
|
+
logError("No external services found. Deploy an ExternalService first:\n" +
|
|
79
|
+
" new mesh.apps.ExternalService(\"symitar\", { env, credentials: { ... } })");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
// Parse service name from path (e.g., "external/symitar" → "symitar")
|
|
83
|
+
let serviceName;
|
|
84
|
+
if (servicePath) {
|
|
85
|
+
serviceName = servicePath.replace(/^external\//, "");
|
|
86
|
+
}
|
|
87
|
+
// If no service specified or not found, list available
|
|
88
|
+
if (!serviceName || !services.has(serviceName)) {
|
|
89
|
+
if (serviceName) {
|
|
90
|
+
logError(`External service "${serviceName}" not found.`);
|
|
91
|
+
}
|
|
92
|
+
console.error("\nAvailable external services:");
|
|
93
|
+
for (const [name, svc] of services) {
|
|
94
|
+
const desc = svc.meta?.description ? ` — ${svc.meta.description}` : "";
|
|
95
|
+
const type = svc.meta?.type ? ` (${svc.meta.type})` : "";
|
|
96
|
+
console.error(` ${name}${type}${desc}`);
|
|
97
|
+
}
|
|
98
|
+
console.error(`\nUsage: mesh secrets set external/<name>`);
|
|
99
|
+
process.exit(serviceName ? 1 : 0);
|
|
100
|
+
}
|
|
101
|
+
const svc = services.get(serviceName);
|
|
102
|
+
const schema = svc.schema;
|
|
103
|
+
if (!schema) {
|
|
104
|
+
logError(`No credential schema found for "${serviceName}".`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
// Determine secret path
|
|
108
|
+
const secretPrefix = svc.meta.secretPrefix;
|
|
109
|
+
const secretId = opts.key ? `${secretPrefix}/${opts.key}` : secretPrefix;
|
|
110
|
+
if (schema.keyedBy && !opts.key) {
|
|
111
|
+
logError(`"${serviceName}" is multi-instance (keyed by ${schema.keyedBy}). ` +
|
|
112
|
+
`Specify an instance:\n mesh secrets set external/${serviceName} --key=<${schema.keyedBy}>`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
// Read existing values (if any)
|
|
116
|
+
let existing = {};
|
|
117
|
+
try {
|
|
118
|
+
const response = await smClient.send(new GetSecretValueCommand({ SecretId: secretId }));
|
|
119
|
+
if (response.SecretString) {
|
|
120
|
+
existing = JSON.parse(response.SecretString);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
if (err.name !== "ResourceNotFoundException") {
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
// Secret doesn't exist yet (multi-instance key) — will create
|
|
128
|
+
}
|
|
129
|
+
// Non-interactive mode: JSON input
|
|
130
|
+
if (opts.json) {
|
|
131
|
+
const values = JSON.parse(opts.json);
|
|
132
|
+
const merged = { ...existing, ...values };
|
|
133
|
+
await writeSecret(smClient, secretId, merged, svc.meta);
|
|
134
|
+
logSuccess(`Credentials written to ${secretId}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
// Interactive mode
|
|
138
|
+
console.error("");
|
|
139
|
+
logInfo(`Setting credentials for: ${svc.meta.description || serviceName}`);
|
|
140
|
+
if (opts.key) {
|
|
141
|
+
logInfo(`Instance: ${opts.key}`);
|
|
142
|
+
}
|
|
143
|
+
logInfo(`Secret: ${secretId}`);
|
|
144
|
+
console.error("");
|
|
145
|
+
const values = {};
|
|
146
|
+
for (const [fieldKey, field] of Object.entries(schema.fields)) {
|
|
147
|
+
// Skip optional fields unless --all
|
|
148
|
+
if (field.optional && !opts.all) {
|
|
149
|
+
const existingVal = existing[fieldKey];
|
|
150
|
+
if (existingVal) {
|
|
151
|
+
values[fieldKey] = existingVal;
|
|
152
|
+
}
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const existingVal = existing[fieldKey];
|
|
156
|
+
const hasExisting = existingVal && existingVal !== "";
|
|
157
|
+
const message = field.description
|
|
158
|
+
? `${field.name} (${field.description})`
|
|
159
|
+
: field.name;
|
|
160
|
+
let value;
|
|
161
|
+
if (field.secret) {
|
|
162
|
+
// Masked input via @inquirer/password — shows * per character
|
|
163
|
+
value = await password({
|
|
164
|
+
message: field.optional ? `${message} [optional]` : message,
|
|
165
|
+
mask: "*",
|
|
166
|
+
});
|
|
167
|
+
// For secret fields, keep existing if user just pressed Enter
|
|
168
|
+
if (!value && hasExisting) {
|
|
169
|
+
value = existingVal;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// Normal input with optional default
|
|
174
|
+
value = await input({
|
|
175
|
+
message: field.optional ? `${message} [optional]` : message,
|
|
176
|
+
default: hasExisting ? existingVal : undefined,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
if (value) {
|
|
180
|
+
values[fieldKey] = value;
|
|
181
|
+
}
|
|
182
|
+
else if (hasExisting) {
|
|
183
|
+
values[fieldKey] = existingVal;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
values[fieldKey] = "";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
console.error("");
|
|
190
|
+
// Merge and write
|
|
191
|
+
const merged = { ...existing, ...values };
|
|
192
|
+
await writeSecret(smClient, secretId, merged, svc.meta);
|
|
193
|
+
logSuccess(`Credentials written to ${secretId}`);
|
|
194
|
+
// Show summary (mask secret fields)
|
|
195
|
+
console.error("\nStored fields:");
|
|
196
|
+
for (const [key, field] of Object.entries(schema.fields)) {
|
|
197
|
+
const val = merged[key];
|
|
198
|
+
if (!val)
|
|
199
|
+
continue;
|
|
200
|
+
const display = field.secret ? "********" : val;
|
|
201
|
+
console.error(` ${field.name}: ${display}`);
|
|
202
|
+
}
|
|
203
|
+
console.error("");
|
|
204
|
+
}
|
|
205
|
+
// =============================================================================
|
|
206
|
+
// Write to Secrets Manager
|
|
207
|
+
// =============================================================================
|
|
208
|
+
async function writeSecret(client, secretId, values, meta) {
|
|
209
|
+
const secretString = JSON.stringify(values);
|
|
210
|
+
try {
|
|
211
|
+
await client.send(new PutSecretValueCommand({
|
|
212
|
+
SecretId: secretId,
|
|
213
|
+
SecretString: secretString,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
if (err.name === "ResourceNotFoundException") {
|
|
218
|
+
// Multi-instance: create the per-key secret
|
|
219
|
+
await client.send(new CreateSecretCommand({
|
|
220
|
+
Name: secretId,
|
|
221
|
+
Description: `External service credentials for ${meta.name} (instance)`,
|
|
222
|
+
SecretString: secretString,
|
|
223
|
+
Tags: [
|
|
224
|
+
{ Key: "mesh:type", Value: "external-service" },
|
|
225
|
+
{ Key: "mesh:service", Value: meta.name },
|
|
226
|
+
],
|
|
227
|
+
}));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
throw err;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../../../src/commands/secrets/set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh stack — Manage personal Pulumi stacks.
|
|
3
|
+
*
|
|
4
|
+
* mesh stack init Create a personal dev stack (dev-{github-user})
|
|
5
|
+
* mesh stack init --from uat Base on a different stack
|
|
6
|
+
*
|
|
7
|
+
* Creates Pulumi.<stack>.yaml with:
|
|
8
|
+
* - mesh:deploy: false (skip K8s deployments — dev-only stack)
|
|
9
|
+
* - mesh:deployerRole copied from the base stack
|
|
10
|
+
* - aws:region copied from the base stack
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from "commander";
|
|
13
|
+
/**
|
|
14
|
+
* Find Pulumi.<stack>.yaml files in the app root.
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerStackCommand(program: Command): void;
|
|
17
|
+
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../../src/commands/stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyCpC;;GAEG;AAKH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4I3D"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh stack — Manage personal Pulumi stacks.
|
|
3
|
+
*
|
|
4
|
+
* mesh stack init Create a personal dev stack (dev-{github-user})
|
|
5
|
+
* mesh stack init --from uat Base on a different stack
|
|
6
|
+
*
|
|
7
|
+
* Creates Pulumi.<stack>.yaml with:
|
|
8
|
+
* - mesh:deploy: false (skip K8s deployments — dev-only stack)
|
|
9
|
+
* - mesh:deployerRole copied from the base stack
|
|
10
|
+
* - aws:region copied from the base stack
|
|
11
|
+
*/
|
|
12
|
+
import { execFileSync } from "child_process";
|
|
13
|
+
import * as path from "path";
|
|
14
|
+
import * as fs from "fs";
|
|
15
|
+
import { logError, logInfo, logSuccess, logWarn } from "../utils/log.js";
|
|
16
|
+
import { findAppRoot, findStackConfigs } from "../utils/pulumi.js";
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Helpers
|
|
19
|
+
// =============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Get GitHub username from gh CLI, falling back to git config.
|
|
22
|
+
*/
|
|
23
|
+
function getGitHubUsername() {
|
|
24
|
+
// Try gh CLI first
|
|
25
|
+
try {
|
|
26
|
+
const result = execFileSync("gh", ["api", "user", "--jq", ".login"], {
|
|
27
|
+
encoding: "utf-8",
|
|
28
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
29
|
+
});
|
|
30
|
+
const login = result.trim();
|
|
31
|
+
if (login)
|
|
32
|
+
return login;
|
|
33
|
+
}
|
|
34
|
+
catch { }
|
|
35
|
+
// Fallback: git config
|
|
36
|
+
try {
|
|
37
|
+
const result = execFileSync("git", ["config", "user.email"], {
|
|
38
|
+
encoding: "utf-8",
|
|
39
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
40
|
+
});
|
|
41
|
+
const email = result.trim();
|
|
42
|
+
// Extract username from GitHub email patterns
|
|
43
|
+
// e.g., user@users.noreply.github.com or user@example.com
|
|
44
|
+
const match = email.match(/^(\d+\+)?([^@]+)@/);
|
|
45
|
+
if (match)
|
|
46
|
+
return match[2];
|
|
47
|
+
}
|
|
48
|
+
catch { }
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Find Pulumi.<stack>.yaml files in the app root.
|
|
53
|
+
*/
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// Command
|
|
56
|
+
// =============================================================================
|
|
57
|
+
export function registerStackCommand(program) {
|
|
58
|
+
const stack = program
|
|
59
|
+
.command("stack")
|
|
60
|
+
.description("Manage personal Pulumi stacks");
|
|
61
|
+
stack
|
|
62
|
+
.command("init")
|
|
63
|
+
.description("Create a personal dev stack (dev-{github-username})")
|
|
64
|
+
.option("--from <stack>", "Base stack to copy config from")
|
|
65
|
+
.option("--name <name>", "Override stack name (default: dev-{username})")
|
|
66
|
+
.action((opts) => {
|
|
67
|
+
const appRoot = findAppRoot(process.cwd());
|
|
68
|
+
if (!appRoot) {
|
|
69
|
+
logError("No Pulumi.yaml found. Run from within a Pulumi app directory.");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
// Get GitHub username
|
|
73
|
+
const username = getGitHubUsername();
|
|
74
|
+
if (!username) {
|
|
75
|
+
logError("Could not determine GitHub username.\n" +
|
|
76
|
+
"Install gh CLI (https://cli.github.com) and run: gh auth login");
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
// Determine base stack
|
|
80
|
+
let baseStack = opts.from;
|
|
81
|
+
if (!baseStack) {
|
|
82
|
+
const stacks = findStackConfigs(appRoot);
|
|
83
|
+
if (stacks.includes("dev")) {
|
|
84
|
+
baseStack = "dev";
|
|
85
|
+
}
|
|
86
|
+
else if (stacks.length === 1) {
|
|
87
|
+
baseStack = stacks[0];
|
|
88
|
+
}
|
|
89
|
+
else if (stacks.length > 1) {
|
|
90
|
+
logError(`Multiple stacks found: ${stacks.join(", ")}\n` +
|
|
91
|
+
"Specify which to base on: mesh stack init --from <stack>");
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
logError("No stack configs found (Pulumi.<stack>.yaml).");
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Verify base config exists
|
|
100
|
+
const baseConfigPath = `${appRoot}/Pulumi.${baseStack}.yaml`;
|
|
101
|
+
if (!fs.existsSync(baseConfigPath)) {
|
|
102
|
+
logError(`Stack config not found: Pulumi.${baseStack}.yaml`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
// Determine new stack name
|
|
106
|
+
const newStack = opts.name ?? `dev-${username}`;
|
|
107
|
+
const newConfigPath = path.join(appRoot, `Pulumi.${newStack}.yaml`);
|
|
108
|
+
const configExists = fs.existsSync(newConfigPath);
|
|
109
|
+
// Initialize the Pulumi stack (creates encryptionsalt in the config file)
|
|
110
|
+
try {
|
|
111
|
+
execFileSync("pulumi", ["stack", "init", newStack], {
|
|
112
|
+
cwd: appRoot,
|
|
113
|
+
stdio: "inherit",
|
|
114
|
+
});
|
|
115
|
+
logSuccess(`Stack initialized: ${newStack}`);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (err.stderr?.includes("already exists")) {
|
|
119
|
+
logWarn(`Stack ${newStack} already exists.`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
process.exit(err.status ?? 1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Select the new stack
|
|
126
|
+
try {
|
|
127
|
+
execFileSync("pulumi", ["stack", "select", newStack], {
|
|
128
|
+
cwd: appRoot,
|
|
129
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
catch { }
|
|
133
|
+
// Copy config from base stack + add mesh:deploy false
|
|
134
|
+
if (!configExists) {
|
|
135
|
+
// Read base stack config as JSON
|
|
136
|
+
let baseConfig = {};
|
|
137
|
+
try {
|
|
138
|
+
const raw = execFileSync("pulumi", ["config", "--json", "--stack", baseStack], { cwd: appRoot, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
139
|
+
baseConfig = JSON.parse(raw);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
logWarn("Could not read base stack config as JSON; falling back to manual setup.");
|
|
143
|
+
}
|
|
144
|
+
// Copy all config keys except mesh:deploy (we'll set that explicitly)
|
|
145
|
+
for (const [key, entry] of Object.entries(baseConfig)) {
|
|
146
|
+
if (key === "mesh:deploy")
|
|
147
|
+
continue;
|
|
148
|
+
try {
|
|
149
|
+
if (entry.objectValue !== undefined) {
|
|
150
|
+
// Structured value — set as JSON (Pulumi parses it back to object)
|
|
151
|
+
execFileSync("pulumi", ["config", "set", key, JSON.stringify(entry.objectValue)], { cwd: appRoot, stdio: ["pipe", "pipe", "pipe"] });
|
|
152
|
+
}
|
|
153
|
+
else if (entry.value === "true" || entry.value === "false") {
|
|
154
|
+
execFileSync("pulumi", ["config", "set", "--type", "bool", key, entry.value], { cwd: appRoot, stdio: ["pipe", "pipe", "pipe"] });
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
execFileSync("pulumi", ["config", "set", key, entry.value], { cwd: appRoot, stdio: ["pipe", "pipe", "pipe"] });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch { }
|
|
161
|
+
}
|
|
162
|
+
// Set mesh:deploy to false — personal stacks skip K8s deployments
|
|
163
|
+
execFileSync("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
|
|
164
|
+
cwd: appRoot,
|
|
165
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
166
|
+
});
|
|
167
|
+
logSuccess(`Configured Pulumi.${newStack}.yaml (based on ${baseStack}, deploy: false)`);
|
|
168
|
+
}
|
|
169
|
+
console.log("");
|
|
170
|
+
logInfo(`Your personal stack is ready.`);
|
|
171
|
+
logInfo(`Run: mesh deploy up --yes`);
|
|
172
|
+
logInfo(`Then: mesh dev`);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/commands/stack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mesh tunnel - SSM tunneling to platform services
|
|
3
|
+
*
|
|
4
|
+
* Commands:
|
|
5
|
+
* mesh tunnel dev Start all dev tunnels (temporal + db)
|
|
6
|
+
* mesh tunnel --services Start specific services
|
|
7
|
+
* mesh tunnel --list List available services
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from "commander";
|
|
10
|
+
/**
|
|
11
|
+
* Register tunnel commands with the CLI
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerTunnelCommands(program: Command): void;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/tunnel/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8OpC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoC7D"}
|