sealos-cli 1.1.2 → 1.1.3
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/README.md +3 -0
- package/dist/bin/cli.cjs +153 -37
- package/dist/bin/cli.mjs +153 -37
- package/dist/main.cjs +153 -37
- package/dist/main.mjs +153 -37
- package/package.json +1 -1
- package/src/commands/database/index.ts +217 -26
- package/src/commands/template/index.ts +14 -11
package/README.md
CHANGED
|
@@ -117,6 +117,7 @@ sealos-cli logout
|
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
119
|
# Deploy from the catalog
|
|
120
|
+
sealos-cli template deploy rybbit
|
|
120
121
|
sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
|
|
121
122
|
|
|
122
123
|
# Validate raw template YAML without creating resources
|
|
@@ -202,6 +203,8 @@ sealos-cli database restart my-db
|
|
|
202
203
|
sealos-cli database backup my-db --name manual-backup
|
|
203
204
|
sealos-cli database backups my-db
|
|
204
205
|
sealos-cli database restore my-db --from manual-backup --name restored-db
|
|
206
|
+
sealos-cli database expose my-db
|
|
207
|
+
sealos-cli database unexpose my-db
|
|
205
208
|
sealos-cli database enable-public my-db
|
|
206
209
|
sealos-cli database disable-public my-db
|
|
207
210
|
sealos-cli database log-files <pod-name> --db-type postgresql --log-type runtimeLog
|
package/dist/bin/cli.cjs
CHANGED
|
@@ -5535,6 +5535,40 @@ function normalizeDatabaseType(type) {
|
|
|
5535
5535
|
return resolved;
|
|
5536
5536
|
}
|
|
5537
5537
|
__name(normalizeDatabaseType, "normalizeDatabaseType");
|
|
5538
|
+
function getDatabaseConnectScheme(type) {
|
|
5539
|
+
const databaseType = normalizeDatabaseType(type);
|
|
5540
|
+
const schemes = {
|
|
5541
|
+
postgresql: "postgresql",
|
|
5542
|
+
mongodb: "mongodb",
|
|
5543
|
+
"apecloud-mysql": "mysql",
|
|
5544
|
+
mysql: "mysql",
|
|
5545
|
+
redis: "redis",
|
|
5546
|
+
kafka: "kafka",
|
|
5547
|
+
qdrant: "qdrant",
|
|
5548
|
+
nebula: "nebula",
|
|
5549
|
+
weaviate: "weaviate",
|
|
5550
|
+
milvus: "milvus",
|
|
5551
|
+
pulsar: "pulsar",
|
|
5552
|
+
clickhouse: "clickhouse"
|
|
5553
|
+
};
|
|
5554
|
+
return schemes[databaseType];
|
|
5555
|
+
}
|
|
5556
|
+
__name(getDatabaseConnectScheme, "getDatabaseConnectScheme");
|
|
5557
|
+
function buildConsolePublicConnection(options) {
|
|
5558
|
+
if (!options.domain || !options.nodePort) return null;
|
|
5559
|
+
const scheme = getDatabaseConnectScheme(options.dbType);
|
|
5560
|
+
const port = String(options.nodePort);
|
|
5561
|
+
if (scheme === "kafka" || scheme === "milvus") {
|
|
5562
|
+
return `${options.domain}:${port}`;
|
|
5563
|
+
}
|
|
5564
|
+
if (!options.username || !options.password) return null;
|
|
5565
|
+
let connection = `${scheme}://${options.username}:${options.password}@${options.domain}:${port}`;
|
|
5566
|
+
if (scheme === "mongodb" || scheme === "postgresql") {
|
|
5567
|
+
connection += "/?directConnection=true";
|
|
5568
|
+
}
|
|
5569
|
+
return connection;
|
|
5570
|
+
}
|
|
5571
|
+
__name(buildConsolePublicConnection, "buildConsolePublicConnection");
|
|
5538
5572
|
function normalizeLogDbType(type) {
|
|
5539
5573
|
const normalized = normalizeDatabaseType(type);
|
|
5540
5574
|
if (!SUPPORTED_LOG_DB_TYPES.includes(normalized)) {
|
|
@@ -5703,6 +5737,86 @@ function printConnectionDetail(connection) {
|
|
|
5703
5737
|
outputTable(rows);
|
|
5704
5738
|
}
|
|
5705
5739
|
__name(printConnectionDetail, "printConnectionDetail");
|
|
5740
|
+
function buildPublicAccessResult(action, name, connection) {
|
|
5741
|
+
return {
|
|
5742
|
+
success: true,
|
|
5743
|
+
action,
|
|
5744
|
+
resource: "database",
|
|
5745
|
+
name,
|
|
5746
|
+
status: action === "enable-public" ? "enabled" : "disabled",
|
|
5747
|
+
publicConnection: connection?.publicConnection ?? null,
|
|
5748
|
+
connection: connection ?? null
|
|
5749
|
+
};
|
|
5750
|
+
}
|
|
5751
|
+
__name(buildPublicAccessResult, "buildPublicAccessResult");
|
|
5752
|
+
function getDatabaseProviderHost() {
|
|
5753
|
+
const override = process.env.SEALOS_DATABASE_HOST?.trim();
|
|
5754
|
+
if (override) {
|
|
5755
|
+
return override.replace(/\/+$/, "");
|
|
5756
|
+
}
|
|
5757
|
+
let authRegion;
|
|
5758
|
+
try {
|
|
5759
|
+
authRegion = loadAuth().region;
|
|
5760
|
+
} catch {
|
|
5761
|
+
authRegion = void 0;
|
|
5762
|
+
}
|
|
5763
|
+
return resolveDbproviderHost(process.env.SEALOS_REGION || authRegion || DEFAULT_SEALOS_REGION);
|
|
5764
|
+
}
|
|
5765
|
+
__name(getDatabaseProviderHost, "getDatabaseProviderHost");
|
|
5766
|
+
async function getLegacyApiData(path, headers) {
|
|
5767
|
+
const url = new URL(path, getDatabaseProviderHost());
|
|
5768
|
+
const response = await fetch(url, {
|
|
5769
|
+
headers: {
|
|
5770
|
+
Authorization: headers.Authorization
|
|
5771
|
+
}
|
|
5772
|
+
});
|
|
5773
|
+
const body = await response.json();
|
|
5774
|
+
if (!response.ok || body.code !== 200) {
|
|
5775
|
+
throw new Error(body.message || `Request failed: ${url.pathname}`);
|
|
5776
|
+
}
|
|
5777
|
+
return body.data;
|
|
5778
|
+
}
|
|
5779
|
+
__name(getLegacyApiData, "getLegacyApiData");
|
|
5780
|
+
async function fetchConsoleConnectionDetails(name, dbType, fallbackConnection, headers) {
|
|
5781
|
+
const [secret, service, config] = await Promise.all([
|
|
5782
|
+
getLegacyApiData(`/api/getSecretByName?dbName=${encodeURIComponent(name)}&dbType=${encodeURIComponent(dbType)}&mock=false`, headers),
|
|
5783
|
+
getLegacyApiData(`/api/getServiceByName?name=${encodeURIComponent(`${name}-export`)}`, headers).catch(() => null),
|
|
5784
|
+
getLegacyApiData("/api/platform/getClientAppConfig", headers).catch(() => null)
|
|
5785
|
+
]);
|
|
5786
|
+
const nodePort = service?.spec?.ports?.find((port) => port.nodePort)?.nodePort;
|
|
5787
|
+
const publicConnection = buildConsolePublicConnection({
|
|
5788
|
+
dbType,
|
|
5789
|
+
username: secret.username,
|
|
5790
|
+
password: secret.password,
|
|
5791
|
+
domain: config?.domain,
|
|
5792
|
+
nodePort
|
|
5793
|
+
}) ?? fallbackConnection?.publicConnection ?? null;
|
|
5794
|
+
return {
|
|
5795
|
+
privateConnection: {
|
|
5796
|
+
endpoint: `${secret.host}:${secret.port}`,
|
|
5797
|
+
host: secret.host,
|
|
5798
|
+
port: secret.port,
|
|
5799
|
+
username: secret.username,
|
|
5800
|
+
password: secret.password,
|
|
5801
|
+
connectionString: secret.connection
|
|
5802
|
+
},
|
|
5803
|
+
publicConnection
|
|
5804
|
+
};
|
|
5805
|
+
}
|
|
5806
|
+
__name(fetchConsoleConnectionDetails, "fetchConsoleConnectionDetails");
|
|
5807
|
+
async function loadDatabaseConnectionDetails(name, headers) {
|
|
5808
|
+
const client = createDatabaseClient();
|
|
5809
|
+
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5810
|
+
headers,
|
|
5811
|
+
params: {
|
|
5812
|
+
path: { databaseName: name }
|
|
5813
|
+
}
|
|
5814
|
+
});
|
|
5815
|
+
if (error2) throw mapApiError(response.status, error2);
|
|
5816
|
+
if (!data.type) return data.connection ?? null;
|
|
5817
|
+
return await fetchConsoleConnectionDetails(name, data.type, data.connection, headers);
|
|
5818
|
+
}
|
|
5819
|
+
__name(loadDatabaseConnectionDetails, "loadDatabaseConnectionDetails");
|
|
5706
5820
|
function createDatabaseCommand() {
|
|
5707
5821
|
const dbCmd = new import_commander7.Command("database").alias("db").description("Manage databases");
|
|
5708
5822
|
dbCmd.command("list").description("List databases").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading databases..." }, async (ctx, options) => {
|
|
@@ -5832,20 +5946,13 @@ function createDatabaseCommand() {
|
|
|
5832
5946
|
printDatabaseDetail(data);
|
|
5833
5947
|
}));
|
|
5834
5948
|
dbCmd.command("connection <name>").description("Show database connection details").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading connection details..." }, async (ctx, name, options) => {
|
|
5835
|
-
const
|
|
5836
|
-
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5837
|
-
headers: ctx.auth,
|
|
5838
|
-
params: {
|
|
5839
|
-
path: { databaseName: name }
|
|
5840
|
-
}
|
|
5841
|
-
});
|
|
5842
|
-
if (error2) throw mapApiError(response.status, error2);
|
|
5949
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
5843
5950
|
ctx.spinner.stop();
|
|
5844
5951
|
if (options.output === "json") {
|
|
5845
|
-
outputJson(
|
|
5952
|
+
outputJson(connection);
|
|
5846
5953
|
return;
|
|
5847
5954
|
}
|
|
5848
|
-
printConnectionDetail(
|
|
5955
|
+
printConnectionDetail(connection);
|
|
5849
5956
|
}));
|
|
5850
5957
|
dbCmd.command("update <name>").description("Update database resources").option("--cpu <cpu>", "CPU cores per replica").option("--memory <memory>", "Memory in GB per replica").option("--storage <storage>", "Storage in GB per replica").option("--replicas <replicas>", "Replica count").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({
|
|
5851
5958
|
spinnerText: "Updating database..."
|
|
@@ -6082,7 +6189,7 @@ function createDatabaseCommand() {
|
|
|
6082
6189
|
}
|
|
6083
6190
|
ctx.spinner.succeed(`Restore requested from backup "${options.from}"`);
|
|
6084
6191
|
}));
|
|
6085
|
-
dbCmd.command("enable-public <name>").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
|
|
6192
|
+
dbCmd.command("enable-public <name>").alias("expose").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
|
|
6086
6193
|
const client = createDatabaseClient();
|
|
6087
6194
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/enable-public", {
|
|
6088
6195
|
headers: ctx.auth,
|
|
@@ -6091,20 +6198,16 @@ function createDatabaseCommand() {
|
|
|
6091
6198
|
}
|
|
6092
6199
|
});
|
|
6093
6200
|
if (error2) throw mapApiError(response.status, error2);
|
|
6201
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
6094
6202
|
if (options.output === "json") {
|
|
6095
6203
|
ctx.spinner.stop();
|
|
6096
|
-
outputJson(
|
|
6097
|
-
success: true,
|
|
6098
|
-
action: "enable-public",
|
|
6099
|
-
resource: "database",
|
|
6100
|
-
name,
|
|
6101
|
-
status: "enabled"
|
|
6102
|
-
});
|
|
6204
|
+
outputJson(buildPublicAccessResult("enable-public", name, connection));
|
|
6103
6205
|
return;
|
|
6104
6206
|
}
|
|
6105
6207
|
ctx.spinner.succeed(`Public access enabled for "${name}"`);
|
|
6208
|
+
printConnectionDetail(connection);
|
|
6106
6209
|
}));
|
|
6107
|
-
dbCmd.command("disable-public <name>").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
|
|
6210
|
+
dbCmd.command("disable-public <name>").alias("unexpose").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
|
|
6108
6211
|
const client = createDatabaseClient();
|
|
6109
6212
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/disable-public", {
|
|
6110
6213
|
headers: ctx.auth,
|
|
@@ -6115,13 +6218,7 @@ function createDatabaseCommand() {
|
|
|
6115
6218
|
if (error2) throw mapApiError(response.status, error2);
|
|
6116
6219
|
if (options.output === "json") {
|
|
6117
6220
|
ctx.spinner.stop();
|
|
6118
|
-
outputJson(
|
|
6119
|
-
success: true,
|
|
6120
|
-
action: "disable-public",
|
|
6121
|
-
resource: "database",
|
|
6122
|
-
name,
|
|
6123
|
-
status: "disabled"
|
|
6124
|
-
});
|
|
6221
|
+
outputJson(buildPublicAccessResult("disable-public", name));
|
|
6125
6222
|
return;
|
|
6126
6223
|
}
|
|
6127
6224
|
ctx.spinner.succeed(`Public access disabled for "${name}"`);
|
|
@@ -6207,6 +6304,22 @@ page=${data.data.metadata.page} total=${data.data.metadata.total} hasMore=${Stri
|
|
|
6207
6304
|
}
|
|
6208
6305
|
outputTable(rows);
|
|
6209
6306
|
}));
|
|
6307
|
+
dbCmd.command("* [args...]", { hidden: true }).option("-o, --output <format>", "Output format (json|table)", "json").allowUnknownOption().action(async (args, options) => {
|
|
6308
|
+
const [name, operation, ...rest] = args;
|
|
6309
|
+
const aliases = {
|
|
6310
|
+
connection: "connection",
|
|
6311
|
+
connect: "connection",
|
|
6312
|
+
"enable-public": "enable-public",
|
|
6313
|
+
expose: "expose",
|
|
6314
|
+
"disable-public": "disable-public",
|
|
6315
|
+
unexpose: "unexpose"
|
|
6316
|
+
};
|
|
6317
|
+
const command = operation ? aliases[operation] : void 0;
|
|
6318
|
+
if (!name || !command) {
|
|
6319
|
+
throw new Error('Unknown database command. Use "sealos-cli database --help" to list supported commands.');
|
|
6320
|
+
}
|
|
6321
|
+
await dbCmd.parseAsync([command, name, ...rest, "--output", options.output], { from: "user" });
|
|
6322
|
+
});
|
|
6210
6323
|
return dbCmd;
|
|
6211
6324
|
}
|
|
6212
6325
|
__name(createDatabaseCommand, "createDatabaseCommand");
|
|
@@ -6253,17 +6366,15 @@ async function resolveYaml(options, spinner2) {
|
|
|
6253
6366
|
}
|
|
6254
6367
|
__name(resolveYaml, "resolveYaml");
|
|
6255
6368
|
function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin.isTTY) {
|
|
6256
|
-
const
|
|
6257
|
-
|
|
6258
|
-
|
|
6369
|
+
const hasExplicitRawInput = !!(options.file || options.yaml);
|
|
6370
|
+
const isRaw = hasExplicitRawInput || !template && !stdinIsTTY;
|
|
6371
|
+
if (template && hasExplicitRawInput) {
|
|
6372
|
+
throw new Error("Cannot specify both a template name and --file/--yaml. Use one or the other.");
|
|
6259
6373
|
}
|
|
6260
6374
|
if (!template && !isRaw) {
|
|
6261
6375
|
throw new Error("Provide a template name or use --file/--yaml/stdin to supply raw YAML.");
|
|
6262
6376
|
}
|
|
6263
6377
|
if (template) {
|
|
6264
|
-
if (!options.name) {
|
|
6265
|
-
throw new Error("--name is required when deploying from the template catalog.");
|
|
6266
|
-
}
|
|
6267
6378
|
if (options.dryRun) {
|
|
6268
6379
|
throw new Error("--dry-run is only supported for raw template deploys (--file, --yaml, or stdin).");
|
|
6269
6380
|
}
|
|
@@ -6274,7 +6385,7 @@ function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin
|
|
|
6274
6385
|
__name(resolveTemplateDeployMode, "resolveTemplateDeployMode");
|
|
6275
6386
|
function buildCatalogTemplateDeployBody(template, options) {
|
|
6276
6387
|
const body = {
|
|
6277
|
-
name: options.name,
|
|
6388
|
+
name: options.name ?? template,
|
|
6278
6389
|
template
|
|
6279
6390
|
};
|
|
6280
6391
|
if (options.set.length > 0) {
|
|
@@ -6484,9 +6595,10 @@ function createTemplateCommand() {
|
|
|
6484
6595
|
}
|
|
6485
6596
|
ctx.spinner.succeed(`Instance "${instance}" deleted`);
|
|
6486
6597
|
}));
|
|
6487
|
-
tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (
|
|
6598
|
+
tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (defaults to the catalog template name)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
|
|
6488
6599
|
Examples:
|
|
6489
6600
|
Catalog:
|
|
6601
|
+
sealos-cli template deploy rybbit
|
|
6490
6602
|
sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
|
|
6491
6603
|
|
|
6492
6604
|
Raw:
|
|
@@ -6496,8 +6608,12 @@ kind: Template
|
|
|
6496
6608
|
...'
|
|
6497
6609
|
cat template.yaml | sealos-cli template deploy --dry-run
|
|
6498
6610
|
`).action(async (template, options) => {
|
|
6499
|
-
|
|
6500
|
-
|
|
6611
|
+
try {
|
|
6612
|
+
const mode = resolveTemplateDeployMode(template, options);
|
|
6613
|
+
await deployTemplate(template, options, mode);
|
|
6614
|
+
} catch (error2) {
|
|
6615
|
+
handleError(error2);
|
|
6616
|
+
}
|
|
6501
6617
|
});
|
|
6502
6618
|
return tplCmd;
|
|
6503
6619
|
}
|
|
@@ -6506,7 +6622,7 @@ __name(createTemplateCommand, "createTemplateCommand");
|
|
|
6506
6622
|
// package.json
|
|
6507
6623
|
var package_default = {
|
|
6508
6624
|
name: "sealos-cli",
|
|
6509
|
-
version: "1.1.
|
|
6625
|
+
version: "1.1.3",
|
|
6510
6626
|
description: "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
|
|
6511
6627
|
types: "dist/main.d.ts",
|
|
6512
6628
|
type: "module",
|
package/dist/bin/cli.mjs
CHANGED
|
@@ -5513,6 +5513,40 @@ function normalizeDatabaseType(type) {
|
|
|
5513
5513
|
return resolved;
|
|
5514
5514
|
}
|
|
5515
5515
|
__name(normalizeDatabaseType, "normalizeDatabaseType");
|
|
5516
|
+
function getDatabaseConnectScheme(type) {
|
|
5517
|
+
const databaseType = normalizeDatabaseType(type);
|
|
5518
|
+
const schemes = {
|
|
5519
|
+
postgresql: "postgresql",
|
|
5520
|
+
mongodb: "mongodb",
|
|
5521
|
+
"apecloud-mysql": "mysql",
|
|
5522
|
+
mysql: "mysql",
|
|
5523
|
+
redis: "redis",
|
|
5524
|
+
kafka: "kafka",
|
|
5525
|
+
qdrant: "qdrant",
|
|
5526
|
+
nebula: "nebula",
|
|
5527
|
+
weaviate: "weaviate",
|
|
5528
|
+
milvus: "milvus",
|
|
5529
|
+
pulsar: "pulsar",
|
|
5530
|
+
clickhouse: "clickhouse"
|
|
5531
|
+
};
|
|
5532
|
+
return schemes[databaseType];
|
|
5533
|
+
}
|
|
5534
|
+
__name(getDatabaseConnectScheme, "getDatabaseConnectScheme");
|
|
5535
|
+
function buildConsolePublicConnection(options) {
|
|
5536
|
+
if (!options.domain || !options.nodePort) return null;
|
|
5537
|
+
const scheme = getDatabaseConnectScheme(options.dbType);
|
|
5538
|
+
const port = String(options.nodePort);
|
|
5539
|
+
if (scheme === "kafka" || scheme === "milvus") {
|
|
5540
|
+
return `${options.domain}:${port}`;
|
|
5541
|
+
}
|
|
5542
|
+
if (!options.username || !options.password) return null;
|
|
5543
|
+
let connection = `${scheme}://${options.username}:${options.password}@${options.domain}:${port}`;
|
|
5544
|
+
if (scheme === "mongodb" || scheme === "postgresql") {
|
|
5545
|
+
connection += "/?directConnection=true";
|
|
5546
|
+
}
|
|
5547
|
+
return connection;
|
|
5548
|
+
}
|
|
5549
|
+
__name(buildConsolePublicConnection, "buildConsolePublicConnection");
|
|
5516
5550
|
function normalizeLogDbType(type) {
|
|
5517
5551
|
const normalized = normalizeDatabaseType(type);
|
|
5518
5552
|
if (!SUPPORTED_LOG_DB_TYPES.includes(normalized)) {
|
|
@@ -5681,6 +5715,86 @@ function printConnectionDetail(connection) {
|
|
|
5681
5715
|
outputTable(rows);
|
|
5682
5716
|
}
|
|
5683
5717
|
__name(printConnectionDetail, "printConnectionDetail");
|
|
5718
|
+
function buildPublicAccessResult(action, name, connection) {
|
|
5719
|
+
return {
|
|
5720
|
+
success: true,
|
|
5721
|
+
action,
|
|
5722
|
+
resource: "database",
|
|
5723
|
+
name,
|
|
5724
|
+
status: action === "enable-public" ? "enabled" : "disabled",
|
|
5725
|
+
publicConnection: connection?.publicConnection ?? null,
|
|
5726
|
+
connection: connection ?? null
|
|
5727
|
+
};
|
|
5728
|
+
}
|
|
5729
|
+
__name(buildPublicAccessResult, "buildPublicAccessResult");
|
|
5730
|
+
function getDatabaseProviderHost() {
|
|
5731
|
+
const override = process.env.SEALOS_DATABASE_HOST?.trim();
|
|
5732
|
+
if (override) {
|
|
5733
|
+
return override.replace(/\/+$/, "");
|
|
5734
|
+
}
|
|
5735
|
+
let authRegion;
|
|
5736
|
+
try {
|
|
5737
|
+
authRegion = loadAuth().region;
|
|
5738
|
+
} catch {
|
|
5739
|
+
authRegion = void 0;
|
|
5740
|
+
}
|
|
5741
|
+
return resolveDbproviderHost(process.env.SEALOS_REGION || authRegion || DEFAULT_SEALOS_REGION);
|
|
5742
|
+
}
|
|
5743
|
+
__name(getDatabaseProviderHost, "getDatabaseProviderHost");
|
|
5744
|
+
async function getLegacyApiData(path, headers) {
|
|
5745
|
+
const url = new URL(path, getDatabaseProviderHost());
|
|
5746
|
+
const response = await fetch(url, {
|
|
5747
|
+
headers: {
|
|
5748
|
+
Authorization: headers.Authorization
|
|
5749
|
+
}
|
|
5750
|
+
});
|
|
5751
|
+
const body = await response.json();
|
|
5752
|
+
if (!response.ok || body.code !== 200) {
|
|
5753
|
+
throw new Error(body.message || `Request failed: ${url.pathname}`);
|
|
5754
|
+
}
|
|
5755
|
+
return body.data;
|
|
5756
|
+
}
|
|
5757
|
+
__name(getLegacyApiData, "getLegacyApiData");
|
|
5758
|
+
async function fetchConsoleConnectionDetails(name, dbType, fallbackConnection, headers) {
|
|
5759
|
+
const [secret, service, config] = await Promise.all([
|
|
5760
|
+
getLegacyApiData(`/api/getSecretByName?dbName=${encodeURIComponent(name)}&dbType=${encodeURIComponent(dbType)}&mock=false`, headers),
|
|
5761
|
+
getLegacyApiData(`/api/getServiceByName?name=${encodeURIComponent(`${name}-export`)}`, headers).catch(() => null),
|
|
5762
|
+
getLegacyApiData("/api/platform/getClientAppConfig", headers).catch(() => null)
|
|
5763
|
+
]);
|
|
5764
|
+
const nodePort = service?.spec?.ports?.find((port) => port.nodePort)?.nodePort;
|
|
5765
|
+
const publicConnection = buildConsolePublicConnection({
|
|
5766
|
+
dbType,
|
|
5767
|
+
username: secret.username,
|
|
5768
|
+
password: secret.password,
|
|
5769
|
+
domain: config?.domain,
|
|
5770
|
+
nodePort
|
|
5771
|
+
}) ?? fallbackConnection?.publicConnection ?? null;
|
|
5772
|
+
return {
|
|
5773
|
+
privateConnection: {
|
|
5774
|
+
endpoint: `${secret.host}:${secret.port}`,
|
|
5775
|
+
host: secret.host,
|
|
5776
|
+
port: secret.port,
|
|
5777
|
+
username: secret.username,
|
|
5778
|
+
password: secret.password,
|
|
5779
|
+
connectionString: secret.connection
|
|
5780
|
+
},
|
|
5781
|
+
publicConnection
|
|
5782
|
+
};
|
|
5783
|
+
}
|
|
5784
|
+
__name(fetchConsoleConnectionDetails, "fetchConsoleConnectionDetails");
|
|
5785
|
+
async function loadDatabaseConnectionDetails(name, headers) {
|
|
5786
|
+
const client = createDatabaseClient();
|
|
5787
|
+
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5788
|
+
headers,
|
|
5789
|
+
params: {
|
|
5790
|
+
path: { databaseName: name }
|
|
5791
|
+
}
|
|
5792
|
+
});
|
|
5793
|
+
if (error2) throw mapApiError(response.status, error2);
|
|
5794
|
+
if (!data.type) return data.connection ?? null;
|
|
5795
|
+
return await fetchConsoleConnectionDetails(name, data.type, data.connection, headers);
|
|
5796
|
+
}
|
|
5797
|
+
__name(loadDatabaseConnectionDetails, "loadDatabaseConnectionDetails");
|
|
5684
5798
|
function createDatabaseCommand() {
|
|
5685
5799
|
const dbCmd = new Command7("database").alias("db").description("Manage databases");
|
|
5686
5800
|
dbCmd.command("list").description("List databases").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading databases..." }, async (ctx, options) => {
|
|
@@ -5810,20 +5924,13 @@ function createDatabaseCommand() {
|
|
|
5810
5924
|
printDatabaseDetail(data);
|
|
5811
5925
|
}));
|
|
5812
5926
|
dbCmd.command("connection <name>").description("Show database connection details").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading connection details..." }, async (ctx, name, options) => {
|
|
5813
|
-
const
|
|
5814
|
-
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5815
|
-
headers: ctx.auth,
|
|
5816
|
-
params: {
|
|
5817
|
-
path: { databaseName: name }
|
|
5818
|
-
}
|
|
5819
|
-
});
|
|
5820
|
-
if (error2) throw mapApiError(response.status, error2);
|
|
5927
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
5821
5928
|
ctx.spinner.stop();
|
|
5822
5929
|
if (options.output === "json") {
|
|
5823
|
-
outputJson(
|
|
5930
|
+
outputJson(connection);
|
|
5824
5931
|
return;
|
|
5825
5932
|
}
|
|
5826
|
-
printConnectionDetail(
|
|
5933
|
+
printConnectionDetail(connection);
|
|
5827
5934
|
}));
|
|
5828
5935
|
dbCmd.command("update <name>").description("Update database resources").option("--cpu <cpu>", "CPU cores per replica").option("--memory <memory>", "Memory in GB per replica").option("--storage <storage>", "Storage in GB per replica").option("--replicas <replicas>", "Replica count").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({
|
|
5829
5936
|
spinnerText: "Updating database..."
|
|
@@ -6060,7 +6167,7 @@ function createDatabaseCommand() {
|
|
|
6060
6167
|
}
|
|
6061
6168
|
ctx.spinner.succeed(`Restore requested from backup "${options.from}"`);
|
|
6062
6169
|
}));
|
|
6063
|
-
dbCmd.command("enable-public <name>").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
|
|
6170
|
+
dbCmd.command("enable-public <name>").alias("expose").description("Enable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Enabling public access..." }, async (ctx, name, options) => {
|
|
6064
6171
|
const client = createDatabaseClient();
|
|
6065
6172
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/enable-public", {
|
|
6066
6173
|
headers: ctx.auth,
|
|
@@ -6069,20 +6176,16 @@ function createDatabaseCommand() {
|
|
|
6069
6176
|
}
|
|
6070
6177
|
});
|
|
6071
6178
|
if (error2) throw mapApiError(response.status, error2);
|
|
6179
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
6072
6180
|
if (options.output === "json") {
|
|
6073
6181
|
ctx.spinner.stop();
|
|
6074
|
-
outputJson(
|
|
6075
|
-
success: true,
|
|
6076
|
-
action: "enable-public",
|
|
6077
|
-
resource: "database",
|
|
6078
|
-
name,
|
|
6079
|
-
status: "enabled"
|
|
6080
|
-
});
|
|
6182
|
+
outputJson(buildPublicAccessResult("enable-public", name, connection));
|
|
6081
6183
|
return;
|
|
6082
6184
|
}
|
|
6083
6185
|
ctx.spinner.succeed(`Public access enabled for "${name}"`);
|
|
6186
|
+
printConnectionDetail(connection);
|
|
6084
6187
|
}));
|
|
6085
|
-
dbCmd.command("disable-public <name>").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
|
|
6188
|
+
dbCmd.command("disable-public <name>").alias("unexpose").description("Disable public access for a database").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Disabling public access..." }, async (ctx, name, options) => {
|
|
6086
6189
|
const client = createDatabaseClient();
|
|
6087
6190
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/disable-public", {
|
|
6088
6191
|
headers: ctx.auth,
|
|
@@ -6093,13 +6196,7 @@ function createDatabaseCommand() {
|
|
|
6093
6196
|
if (error2) throw mapApiError(response.status, error2);
|
|
6094
6197
|
if (options.output === "json") {
|
|
6095
6198
|
ctx.spinner.stop();
|
|
6096
|
-
outputJson(
|
|
6097
|
-
success: true,
|
|
6098
|
-
action: "disable-public",
|
|
6099
|
-
resource: "database",
|
|
6100
|
-
name,
|
|
6101
|
-
status: "disabled"
|
|
6102
|
-
});
|
|
6199
|
+
outputJson(buildPublicAccessResult("disable-public", name));
|
|
6103
6200
|
return;
|
|
6104
6201
|
}
|
|
6105
6202
|
ctx.spinner.succeed(`Public access disabled for "${name}"`);
|
|
@@ -6185,6 +6282,22 @@ page=${data.data.metadata.page} total=${data.data.metadata.total} hasMore=${Stri
|
|
|
6185
6282
|
}
|
|
6186
6283
|
outputTable(rows);
|
|
6187
6284
|
}));
|
|
6285
|
+
dbCmd.command("* [args...]", { hidden: true }).option("-o, --output <format>", "Output format (json|table)", "json").allowUnknownOption().action(async (args, options) => {
|
|
6286
|
+
const [name, operation, ...rest] = args;
|
|
6287
|
+
const aliases = {
|
|
6288
|
+
connection: "connection",
|
|
6289
|
+
connect: "connection",
|
|
6290
|
+
"enable-public": "enable-public",
|
|
6291
|
+
expose: "expose",
|
|
6292
|
+
"disable-public": "disable-public",
|
|
6293
|
+
unexpose: "unexpose"
|
|
6294
|
+
};
|
|
6295
|
+
const command = operation ? aliases[operation] : void 0;
|
|
6296
|
+
if (!name || !command) {
|
|
6297
|
+
throw new Error('Unknown database command. Use "sealos-cli database --help" to list supported commands.');
|
|
6298
|
+
}
|
|
6299
|
+
await dbCmd.parseAsync([command, name, ...rest, "--output", options.output], { from: "user" });
|
|
6300
|
+
});
|
|
6188
6301
|
return dbCmd;
|
|
6189
6302
|
}
|
|
6190
6303
|
__name(createDatabaseCommand, "createDatabaseCommand");
|
|
@@ -6231,17 +6344,15 @@ async function resolveYaml(options, spinner2) {
|
|
|
6231
6344
|
}
|
|
6232
6345
|
__name(resolveYaml, "resolveYaml");
|
|
6233
6346
|
function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin.isTTY) {
|
|
6234
|
-
const
|
|
6235
|
-
|
|
6236
|
-
|
|
6347
|
+
const hasExplicitRawInput = !!(options.file || options.yaml);
|
|
6348
|
+
const isRaw = hasExplicitRawInput || !template && !stdinIsTTY;
|
|
6349
|
+
if (template && hasExplicitRawInput) {
|
|
6350
|
+
throw new Error("Cannot specify both a template name and --file/--yaml. Use one or the other.");
|
|
6237
6351
|
}
|
|
6238
6352
|
if (!template && !isRaw) {
|
|
6239
6353
|
throw new Error("Provide a template name or use --file/--yaml/stdin to supply raw YAML.");
|
|
6240
6354
|
}
|
|
6241
6355
|
if (template) {
|
|
6242
|
-
if (!options.name) {
|
|
6243
|
-
throw new Error("--name is required when deploying from the template catalog.");
|
|
6244
|
-
}
|
|
6245
6356
|
if (options.dryRun) {
|
|
6246
6357
|
throw new Error("--dry-run is only supported for raw template deploys (--file, --yaml, or stdin).");
|
|
6247
6358
|
}
|
|
@@ -6252,7 +6363,7 @@ function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin
|
|
|
6252
6363
|
__name(resolveTemplateDeployMode, "resolveTemplateDeployMode");
|
|
6253
6364
|
function buildCatalogTemplateDeployBody(template, options) {
|
|
6254
6365
|
const body = {
|
|
6255
|
-
name: options.name,
|
|
6366
|
+
name: options.name ?? template,
|
|
6256
6367
|
template
|
|
6257
6368
|
};
|
|
6258
6369
|
if (options.set.length > 0) {
|
|
@@ -6462,9 +6573,10 @@ function createTemplateCommand() {
|
|
|
6462
6573
|
}
|
|
6463
6574
|
ctx.spinner.succeed(`Instance "${instance}" deleted`);
|
|
6464
6575
|
}));
|
|
6465
|
-
tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (
|
|
6576
|
+
tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (defaults to the catalog template name)").option("--file <path>", "Path to template YAML file").option("--yaml <yaml>", "Template YAML string").option("--set <KEY=VALUE...>", "Set template arguments", (val, prev) => [...prev, val], []).option("--dry-run", "Validate raw template YAML without creating resources").option("-o, --output <format>", "Output format (json|table)", "json").addHelpText("after", `
|
|
6466
6577
|
Examples:
|
|
6467
6578
|
Catalog:
|
|
6579
|
+
sealos-cli template deploy rybbit
|
|
6468
6580
|
sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
|
|
6469
6581
|
|
|
6470
6582
|
Raw:
|
|
@@ -6474,8 +6586,12 @@ kind: Template
|
|
|
6474
6586
|
...'
|
|
6475
6587
|
cat template.yaml | sealos-cli template deploy --dry-run
|
|
6476
6588
|
`).action(async (template, options) => {
|
|
6477
|
-
|
|
6478
|
-
|
|
6589
|
+
try {
|
|
6590
|
+
const mode = resolveTemplateDeployMode(template, options);
|
|
6591
|
+
await deployTemplate(template, options, mode);
|
|
6592
|
+
} catch (error2) {
|
|
6593
|
+
handleError(error2);
|
|
6594
|
+
}
|
|
6479
6595
|
});
|
|
6480
6596
|
return tplCmd;
|
|
6481
6597
|
}
|
|
@@ -6484,7 +6600,7 @@ __name(createTemplateCommand, "createTemplateCommand");
|
|
|
6484
6600
|
// package.json
|
|
6485
6601
|
var package_default = {
|
|
6486
6602
|
name: "sealos-cli",
|
|
6487
|
-
version: "1.1.
|
|
6603
|
+
version: "1.1.3",
|
|
6488
6604
|
description: "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
|
|
6489
6605
|
types: "dist/main.d.ts",
|
|
6490
6606
|
type: "module",
|