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/dist/main.cjs
CHANGED
|
@@ -5542,6 +5542,40 @@ function normalizeDatabaseType(type) {
|
|
|
5542
5542
|
return resolved;
|
|
5543
5543
|
}
|
|
5544
5544
|
__name(normalizeDatabaseType, "normalizeDatabaseType");
|
|
5545
|
+
function getDatabaseConnectScheme(type) {
|
|
5546
|
+
const databaseType = normalizeDatabaseType(type);
|
|
5547
|
+
const schemes = {
|
|
5548
|
+
postgresql: "postgresql",
|
|
5549
|
+
mongodb: "mongodb",
|
|
5550
|
+
"apecloud-mysql": "mysql",
|
|
5551
|
+
mysql: "mysql",
|
|
5552
|
+
redis: "redis",
|
|
5553
|
+
kafka: "kafka",
|
|
5554
|
+
qdrant: "qdrant",
|
|
5555
|
+
nebula: "nebula",
|
|
5556
|
+
weaviate: "weaviate",
|
|
5557
|
+
milvus: "milvus",
|
|
5558
|
+
pulsar: "pulsar",
|
|
5559
|
+
clickhouse: "clickhouse"
|
|
5560
|
+
};
|
|
5561
|
+
return schemes[databaseType];
|
|
5562
|
+
}
|
|
5563
|
+
__name(getDatabaseConnectScheme, "getDatabaseConnectScheme");
|
|
5564
|
+
function buildConsolePublicConnection(options) {
|
|
5565
|
+
if (!options.domain || !options.nodePort) return null;
|
|
5566
|
+
const scheme = getDatabaseConnectScheme(options.dbType);
|
|
5567
|
+
const port = String(options.nodePort);
|
|
5568
|
+
if (scheme === "kafka" || scheme === "milvus") {
|
|
5569
|
+
return `${options.domain}:${port}`;
|
|
5570
|
+
}
|
|
5571
|
+
if (!options.username || !options.password) return null;
|
|
5572
|
+
let connection = `${scheme}://${options.username}:${options.password}@${options.domain}:${port}`;
|
|
5573
|
+
if (scheme === "mongodb" || scheme === "postgresql") {
|
|
5574
|
+
connection += "/?directConnection=true";
|
|
5575
|
+
}
|
|
5576
|
+
return connection;
|
|
5577
|
+
}
|
|
5578
|
+
__name(buildConsolePublicConnection, "buildConsolePublicConnection");
|
|
5545
5579
|
function normalizeLogDbType(type) {
|
|
5546
5580
|
const normalized = normalizeDatabaseType(type);
|
|
5547
5581
|
if (!SUPPORTED_LOG_DB_TYPES.includes(normalized)) {
|
|
@@ -5710,6 +5744,86 @@ function printConnectionDetail(connection) {
|
|
|
5710
5744
|
outputTable(rows);
|
|
5711
5745
|
}
|
|
5712
5746
|
__name(printConnectionDetail, "printConnectionDetail");
|
|
5747
|
+
function buildPublicAccessResult(action, name, connection) {
|
|
5748
|
+
return {
|
|
5749
|
+
success: true,
|
|
5750
|
+
action,
|
|
5751
|
+
resource: "database",
|
|
5752
|
+
name,
|
|
5753
|
+
status: action === "enable-public" ? "enabled" : "disabled",
|
|
5754
|
+
publicConnection: connection?.publicConnection ?? null,
|
|
5755
|
+
connection: connection ?? null
|
|
5756
|
+
};
|
|
5757
|
+
}
|
|
5758
|
+
__name(buildPublicAccessResult, "buildPublicAccessResult");
|
|
5759
|
+
function getDatabaseProviderHost() {
|
|
5760
|
+
const override = process.env.SEALOS_DATABASE_HOST?.trim();
|
|
5761
|
+
if (override) {
|
|
5762
|
+
return override.replace(/\/+$/, "");
|
|
5763
|
+
}
|
|
5764
|
+
let authRegion;
|
|
5765
|
+
try {
|
|
5766
|
+
authRegion = loadAuth().region;
|
|
5767
|
+
} catch {
|
|
5768
|
+
authRegion = void 0;
|
|
5769
|
+
}
|
|
5770
|
+
return resolveDbproviderHost(process.env.SEALOS_REGION || authRegion || DEFAULT_SEALOS_REGION);
|
|
5771
|
+
}
|
|
5772
|
+
__name(getDatabaseProviderHost, "getDatabaseProviderHost");
|
|
5773
|
+
async function getLegacyApiData(path, headers) {
|
|
5774
|
+
const url = new URL(path, getDatabaseProviderHost());
|
|
5775
|
+
const response = await fetch(url, {
|
|
5776
|
+
headers: {
|
|
5777
|
+
Authorization: headers.Authorization
|
|
5778
|
+
}
|
|
5779
|
+
});
|
|
5780
|
+
const body = await response.json();
|
|
5781
|
+
if (!response.ok || body.code !== 200) {
|
|
5782
|
+
throw new Error(body.message || `Request failed: ${url.pathname}`);
|
|
5783
|
+
}
|
|
5784
|
+
return body.data;
|
|
5785
|
+
}
|
|
5786
|
+
__name(getLegacyApiData, "getLegacyApiData");
|
|
5787
|
+
async function fetchConsoleConnectionDetails(name, dbType, fallbackConnection, headers) {
|
|
5788
|
+
const [secret, service, config] = await Promise.all([
|
|
5789
|
+
getLegacyApiData(`/api/getSecretByName?dbName=${encodeURIComponent(name)}&dbType=${encodeURIComponent(dbType)}&mock=false`, headers),
|
|
5790
|
+
getLegacyApiData(`/api/getServiceByName?name=${encodeURIComponent(`${name}-export`)}`, headers).catch(() => null),
|
|
5791
|
+
getLegacyApiData("/api/platform/getClientAppConfig", headers).catch(() => null)
|
|
5792
|
+
]);
|
|
5793
|
+
const nodePort = service?.spec?.ports?.find((port) => port.nodePort)?.nodePort;
|
|
5794
|
+
const publicConnection = buildConsolePublicConnection({
|
|
5795
|
+
dbType,
|
|
5796
|
+
username: secret.username,
|
|
5797
|
+
password: secret.password,
|
|
5798
|
+
domain: config?.domain,
|
|
5799
|
+
nodePort
|
|
5800
|
+
}) ?? fallbackConnection?.publicConnection ?? null;
|
|
5801
|
+
return {
|
|
5802
|
+
privateConnection: {
|
|
5803
|
+
endpoint: `${secret.host}:${secret.port}`,
|
|
5804
|
+
host: secret.host,
|
|
5805
|
+
port: secret.port,
|
|
5806
|
+
username: secret.username,
|
|
5807
|
+
password: secret.password,
|
|
5808
|
+
connectionString: secret.connection
|
|
5809
|
+
},
|
|
5810
|
+
publicConnection
|
|
5811
|
+
};
|
|
5812
|
+
}
|
|
5813
|
+
__name(fetchConsoleConnectionDetails, "fetchConsoleConnectionDetails");
|
|
5814
|
+
async function loadDatabaseConnectionDetails(name, headers) {
|
|
5815
|
+
const client = createDatabaseClient();
|
|
5816
|
+
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5817
|
+
headers,
|
|
5818
|
+
params: {
|
|
5819
|
+
path: { databaseName: name }
|
|
5820
|
+
}
|
|
5821
|
+
});
|
|
5822
|
+
if (error2) throw mapApiError(response.status, error2);
|
|
5823
|
+
if (!data.type) return data.connection ?? null;
|
|
5824
|
+
return await fetchConsoleConnectionDetails(name, data.type, data.connection, headers);
|
|
5825
|
+
}
|
|
5826
|
+
__name(loadDatabaseConnectionDetails, "loadDatabaseConnectionDetails");
|
|
5713
5827
|
function createDatabaseCommand() {
|
|
5714
5828
|
const dbCmd = new import_commander7.Command("database").alias("db").description("Manage databases");
|
|
5715
5829
|
dbCmd.command("list").description("List databases").option("-o, --output <format>", "Output format (json|table)", "json").action(withAuth({ spinnerText: "Loading databases..." }, async (ctx, options) => {
|
|
@@ -5839,20 +5953,13 @@ function createDatabaseCommand() {
|
|
|
5839
5953
|
printDatabaseDetail(data);
|
|
5840
5954
|
}));
|
|
5841
5955
|
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) => {
|
|
5842
|
-
const
|
|
5843
|
-
const { data, error: error2, response } = await client.GET("/databases/{databaseName}", {
|
|
5844
|
-
headers: ctx.auth,
|
|
5845
|
-
params: {
|
|
5846
|
-
path: { databaseName: name }
|
|
5847
|
-
}
|
|
5848
|
-
});
|
|
5849
|
-
if (error2) throw mapApiError(response.status, error2);
|
|
5956
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
5850
5957
|
ctx.spinner.stop();
|
|
5851
5958
|
if (options.output === "json") {
|
|
5852
|
-
outputJson(
|
|
5959
|
+
outputJson(connection);
|
|
5853
5960
|
return;
|
|
5854
5961
|
}
|
|
5855
|
-
printConnectionDetail(
|
|
5962
|
+
printConnectionDetail(connection);
|
|
5856
5963
|
}));
|
|
5857
5964
|
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({
|
|
5858
5965
|
spinnerText: "Updating database..."
|
|
@@ -6089,7 +6196,7 @@ function createDatabaseCommand() {
|
|
|
6089
6196
|
}
|
|
6090
6197
|
ctx.spinner.succeed(`Restore requested from backup "${options.from}"`);
|
|
6091
6198
|
}));
|
|
6092
|
-
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) => {
|
|
6199
|
+
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) => {
|
|
6093
6200
|
const client = createDatabaseClient();
|
|
6094
6201
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/enable-public", {
|
|
6095
6202
|
headers: ctx.auth,
|
|
@@ -6098,20 +6205,16 @@ function createDatabaseCommand() {
|
|
|
6098
6205
|
}
|
|
6099
6206
|
});
|
|
6100
6207
|
if (error2) throw mapApiError(response.status, error2);
|
|
6208
|
+
const connection = await loadDatabaseConnectionDetails(name, ctx.auth);
|
|
6101
6209
|
if (options.output === "json") {
|
|
6102
6210
|
ctx.spinner.stop();
|
|
6103
|
-
outputJson(
|
|
6104
|
-
success: true,
|
|
6105
|
-
action: "enable-public",
|
|
6106
|
-
resource: "database",
|
|
6107
|
-
name,
|
|
6108
|
-
status: "enabled"
|
|
6109
|
-
});
|
|
6211
|
+
outputJson(buildPublicAccessResult("enable-public", name, connection));
|
|
6110
6212
|
return;
|
|
6111
6213
|
}
|
|
6112
6214
|
ctx.spinner.succeed(`Public access enabled for "${name}"`);
|
|
6215
|
+
printConnectionDetail(connection);
|
|
6113
6216
|
}));
|
|
6114
|
-
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) => {
|
|
6217
|
+
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) => {
|
|
6115
6218
|
const client = createDatabaseClient();
|
|
6116
6219
|
const { error: error2, response } = await client.POST("/databases/{databaseName}/disable-public", {
|
|
6117
6220
|
headers: ctx.auth,
|
|
@@ -6122,13 +6225,7 @@ function createDatabaseCommand() {
|
|
|
6122
6225
|
if (error2) throw mapApiError(response.status, error2);
|
|
6123
6226
|
if (options.output === "json") {
|
|
6124
6227
|
ctx.spinner.stop();
|
|
6125
|
-
outputJson(
|
|
6126
|
-
success: true,
|
|
6127
|
-
action: "disable-public",
|
|
6128
|
-
resource: "database",
|
|
6129
|
-
name,
|
|
6130
|
-
status: "disabled"
|
|
6131
|
-
});
|
|
6228
|
+
outputJson(buildPublicAccessResult("disable-public", name));
|
|
6132
6229
|
return;
|
|
6133
6230
|
}
|
|
6134
6231
|
ctx.spinner.succeed(`Public access disabled for "${name}"`);
|
|
@@ -6214,6 +6311,22 @@ page=${data.data.metadata.page} total=${data.data.metadata.total} hasMore=${Stri
|
|
|
6214
6311
|
}
|
|
6215
6312
|
outputTable(rows);
|
|
6216
6313
|
}));
|
|
6314
|
+
dbCmd.command("* [args...]", { hidden: true }).option("-o, --output <format>", "Output format (json|table)", "json").allowUnknownOption().action(async (args, options) => {
|
|
6315
|
+
const [name, operation, ...rest] = args;
|
|
6316
|
+
const aliases = {
|
|
6317
|
+
connection: "connection",
|
|
6318
|
+
connect: "connection",
|
|
6319
|
+
"enable-public": "enable-public",
|
|
6320
|
+
expose: "expose",
|
|
6321
|
+
"disable-public": "disable-public",
|
|
6322
|
+
unexpose: "unexpose"
|
|
6323
|
+
};
|
|
6324
|
+
const command = operation ? aliases[operation] : void 0;
|
|
6325
|
+
if (!name || !command) {
|
|
6326
|
+
throw new Error('Unknown database command. Use "sealos-cli database --help" to list supported commands.');
|
|
6327
|
+
}
|
|
6328
|
+
await dbCmd.parseAsync([command, name, ...rest, "--output", options.output], { from: "user" });
|
|
6329
|
+
});
|
|
6217
6330
|
return dbCmd;
|
|
6218
6331
|
}
|
|
6219
6332
|
__name(createDatabaseCommand, "createDatabaseCommand");
|
|
@@ -6260,17 +6373,15 @@ async function resolveYaml(options, spinner2) {
|
|
|
6260
6373
|
}
|
|
6261
6374
|
__name(resolveYaml, "resolveYaml");
|
|
6262
6375
|
function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin.isTTY) {
|
|
6263
|
-
const
|
|
6264
|
-
|
|
6265
|
-
|
|
6376
|
+
const hasExplicitRawInput = !!(options.file || options.yaml);
|
|
6377
|
+
const isRaw = hasExplicitRawInput || !template && !stdinIsTTY;
|
|
6378
|
+
if (template && hasExplicitRawInput) {
|
|
6379
|
+
throw new Error("Cannot specify both a template name and --file/--yaml. Use one or the other.");
|
|
6266
6380
|
}
|
|
6267
6381
|
if (!template && !isRaw) {
|
|
6268
6382
|
throw new Error("Provide a template name or use --file/--yaml/stdin to supply raw YAML.");
|
|
6269
6383
|
}
|
|
6270
6384
|
if (template) {
|
|
6271
|
-
if (!options.name) {
|
|
6272
|
-
throw new Error("--name is required when deploying from the template catalog.");
|
|
6273
|
-
}
|
|
6274
6385
|
if (options.dryRun) {
|
|
6275
6386
|
throw new Error("--dry-run is only supported for raw template deploys (--file, --yaml, or stdin).");
|
|
6276
6387
|
}
|
|
@@ -6281,7 +6392,7 @@ function resolveTemplateDeployMode(template, options, stdinIsTTY = process.stdin
|
|
|
6281
6392
|
__name(resolveTemplateDeployMode, "resolveTemplateDeployMode");
|
|
6282
6393
|
function buildCatalogTemplateDeployBody(template, options) {
|
|
6283
6394
|
const body = {
|
|
6284
|
-
name: options.name,
|
|
6395
|
+
name: options.name ?? template,
|
|
6285
6396
|
template
|
|
6286
6397
|
};
|
|
6287
6398
|
if (options.set.length > 0) {
|
|
@@ -6491,9 +6602,10 @@ function createTemplateCommand() {
|
|
|
6491
6602
|
}
|
|
6492
6603
|
ctx.spinner.succeed(`Instance "${instance}" deleted`);
|
|
6493
6604
|
}));
|
|
6494
|
-
tplCmd.command("deploy [template]").description("Deploy a template (from catalog or raw YAML)").option("--name <name>", "Instance name (
|
|
6605
|
+
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", `
|
|
6495
6606
|
Examples:
|
|
6496
6607
|
Catalog:
|
|
6608
|
+
sealos-cli template deploy rybbit
|
|
6497
6609
|
sealos-cli template deploy perplexica --name my-app --set OPENAI_API_KEY=xxx
|
|
6498
6610
|
|
|
6499
6611
|
Raw:
|
|
@@ -6503,8 +6615,12 @@ kind: Template
|
|
|
6503
6615
|
...'
|
|
6504
6616
|
cat template.yaml | sealos-cli template deploy --dry-run
|
|
6505
6617
|
`).action(async (template, options) => {
|
|
6506
|
-
|
|
6507
|
-
|
|
6618
|
+
try {
|
|
6619
|
+
const mode = resolveTemplateDeployMode(template, options);
|
|
6620
|
+
await deployTemplate(template, options, mode);
|
|
6621
|
+
} catch (error2) {
|
|
6622
|
+
handleError(error2);
|
|
6623
|
+
}
|
|
6508
6624
|
});
|
|
6509
6625
|
return tplCmd;
|
|
6510
6626
|
}
|
|
@@ -6513,7 +6629,7 @@ __name(createTemplateCommand, "createTemplateCommand");
|
|
|
6513
6629
|
// package.json
|
|
6514
6630
|
var package_default = {
|
|
6515
6631
|
name: "sealos-cli",
|
|
6516
|
-
version: "1.1.
|
|
6632
|
+
version: "1.1.3",
|
|
6517
6633
|
description: "Official CLI tool for Sealos Cloud - Manage auth, workspaces, devboxes, databases, and templates",
|
|
6518
6634
|
types: "dist/main.d.ts",
|
|
6519
6635
|
type: "module",
|
package/dist/main.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",
|