@volc-emr/emr-cli 0.1.0-beta.0 → 0.1.2
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 +13 -325
- package/bin/emr-cli +3 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +116 -0
- package/dist/client/index.d.ts +17 -0
- package/dist/client/index.js +129 -0
- package/dist/cluster/index.d.ts +13 -0
- package/dist/cluster/index.js +174 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +15 -176
- package/dist/utils/auth.d.ts +7 -0
- package/dist/utils/auth.js +18 -0
- package/dist/utils/client-state.d.ts +12 -0
- package/dist/utils/client-state.js +80 -0
- package/dist/utils/config.d.ts +17 -0
- package/dist/utils/config.js +103 -0
- package/dist/utils/http.d.ts +13 -0
- package/dist/utils/http.js +76 -0
- package/dist/utils/volc/emr.d.ts +30 -0
- package/dist/utils/volc/emr.js +50 -0
- package/dist/utils/volc/openapi.d.ts +19 -0
- package/dist/utils/volc/openapi.js +122 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +6 -0
- package/package.json +13 -40
- package/LICENSE +0 -21
- package/dist/agent/agent.js +0 -19
- package/dist/agent/executor.js +0 -25
- package/dist/agent/llmPlanner.js +0 -131
- package/dist/agent/planner.js +0 -12
- package/dist/agent/types.js +0 -2
- package/dist/runtime/config.js +0 -73
- package/dist/runtime/confirm.js +0 -92
- package/dist/runtime/createClusterMemory.js +0 -56
- package/dist/runtime/llm.js +0 -64
- package/dist/runtime/logger.js +0 -8
- package/dist/runtime/memory.js +0 -4
- package/dist/services/emrApi.js +0 -181
- package/dist/services/volcApi.js +0 -53
- package/dist/tools/base.js +0 -2
- package/dist/tools/emr/createCluster.js +0 -335
- package/dist/tools/emr/deleteCluster.js +0 -15
- package/dist/tools/emr/findClustersToCleanup.js +0 -18
- package/dist/tools/emr/index.js +0 -15
- package/dist/tools/emr/listClusters.js +0 -68
- package/dist/tools/registry.js +0 -11
- package/dist/utils/prompt.js +0 -9
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.syncClusterConfig = syncClusterConfig;
|
|
40
|
+
exports.registerClusterCommands = registerClusterCommands;
|
|
41
|
+
const fs = __importStar(require("node:fs"));
|
|
42
|
+
const path = __importStar(require("node:path"));
|
|
43
|
+
const ora_1 = __importDefault(require("ora"));
|
|
44
|
+
const auth_1 = require("../utils/auth");
|
|
45
|
+
const client_state_1 = require("../utils/client-state");
|
|
46
|
+
const emr_1 = require("../utils/volc/emr");
|
|
47
|
+
async function syncClusterConfig(options) {
|
|
48
|
+
const clientDir = (0, client_state_1.resolveClientDir)(options.dir);
|
|
49
|
+
if (!(0, client_state_1.isClientInstalled)(clientDir)) {
|
|
50
|
+
throw new Error('本地尚未安装客户端,请先执行 emr-cli client install');
|
|
51
|
+
}
|
|
52
|
+
const auth = (0, auth_1.resolveAuthConfig)({ clusterId: options.clusterId });
|
|
53
|
+
const clusterId = auth.clusterId;
|
|
54
|
+
if (!clusterId) {
|
|
55
|
+
throw new Error('未提供 ClusterId,请在命令行传入 --cluster-id 或先执行 emr-cli auth init 配置默认集群');
|
|
56
|
+
}
|
|
57
|
+
// Use OpenAPI GetCluster to validate cluster existence and permission.
|
|
58
|
+
const { resp: clusterResp, debug } = await (0, emr_1.volcEmrGetCluster)({
|
|
59
|
+
region: auth.region,
|
|
60
|
+
ak: auth.ak,
|
|
61
|
+
sk: auth.sk,
|
|
62
|
+
clusterId,
|
|
63
|
+
}, { debug: Boolean(options.debug) });
|
|
64
|
+
const requestId = clusterResp?.ResponseMetadata?.RequestId;
|
|
65
|
+
const apiErr = (0, emr_1.formatVolcOpenApiError)(clusterResp);
|
|
66
|
+
if (apiErr) {
|
|
67
|
+
if (apiErr.startsWith('InvalidClusterId')) {
|
|
68
|
+
throw new Error('目标集群不存在,请确认 ClusterId 是否正确');
|
|
69
|
+
}
|
|
70
|
+
if (apiErr.toLowerCase().includes('access denied')) {
|
|
71
|
+
throw new Error('对该集群没有权限(Access Denied)');
|
|
72
|
+
}
|
|
73
|
+
throw new Error(`GetCluster 调用失败:${apiErr}`);
|
|
74
|
+
}
|
|
75
|
+
const confDir = path.join(clientDir, 'conf');
|
|
76
|
+
fs.mkdirSync(confDir, { recursive: true });
|
|
77
|
+
const payload = {
|
|
78
|
+
clusterId,
|
|
79
|
+
region: auth.region,
|
|
80
|
+
// Persist a few useful fields for troubleshooting and later extensions.
|
|
81
|
+
clusterName: clusterResp?.Result?.ClusterName,
|
|
82
|
+
clusterType: clusterResp?.Result?.ClusterType,
|
|
83
|
+
releaseVersion: clusterResp?.Result?.ReleaseVersion,
|
|
84
|
+
securityMode: clusterResp?.Result?.SecurityMode,
|
|
85
|
+
syncedAt: new Date().toISOString(),
|
|
86
|
+
};
|
|
87
|
+
fs.writeFileSync(path.join(confDir, 'cluster.json'), JSON.stringify(payload, null, 2));
|
|
88
|
+
fs.writeFileSync(path.join(confDir, 'core-site.xml'), `<configuration><property><name>emr.cluster.id</name><value>${clusterId}</value></property></configuration>`);
|
|
89
|
+
return {
|
|
90
|
+
clusterId,
|
|
91
|
+
outputDir: confDir,
|
|
92
|
+
requestId,
|
|
93
|
+
canonicalRequest: debug?.canonicalRequest,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function registerClusterCommands(program) {
|
|
97
|
+
const clusterCmd = program.command('cluster').description('集群配置同步');
|
|
98
|
+
clusterCmd
|
|
99
|
+
.command('get')
|
|
100
|
+
.description('调用 OpenAPI GetCluster 获取集群详情')
|
|
101
|
+
.option('--cluster-id <clusterId>', '目标 ClusterId(不传则使用本地默认 ClusterId)')
|
|
102
|
+
.option('--pretty', '美化输出 JSON', false)
|
|
103
|
+
.option('--debug', '输出 requestId 和 canonical request 便于排查鉴权/权限问题', false)
|
|
104
|
+
.action(async (options) => {
|
|
105
|
+
const auth = (0, auth_1.resolveAuthConfig)({ clusterId: options.clusterId });
|
|
106
|
+
const clusterId = auth.clusterId;
|
|
107
|
+
if (!clusterId) {
|
|
108
|
+
throw new Error('未提供 ClusterId,请在命令行传入 --cluster-id 或先执行 emr-cli auth init 配置默认集群');
|
|
109
|
+
}
|
|
110
|
+
const spinner = (0, ora_1.default)('正在获取集群信息...').start();
|
|
111
|
+
try {
|
|
112
|
+
const { resp, debug } = await (0, emr_1.volcEmrGetCluster)({
|
|
113
|
+
region: auth.region,
|
|
114
|
+
ak: auth.ak,
|
|
115
|
+
sk: auth.sk,
|
|
116
|
+
clusterId,
|
|
117
|
+
}, { debug: Boolean(options.debug) });
|
|
118
|
+
const requestId = resp?.ResponseMetadata?.RequestId;
|
|
119
|
+
if (options.debug) {
|
|
120
|
+
console.info('');
|
|
121
|
+
console.info(`RequestId: ${requestId || 'unknown'}`);
|
|
122
|
+
console.info('CanonicalRequest:');
|
|
123
|
+
console.info(debug?.canonicalRequest || '(empty)');
|
|
124
|
+
console.info('');
|
|
125
|
+
}
|
|
126
|
+
const apiErr = (0, emr_1.formatVolcOpenApiError)(resp);
|
|
127
|
+
if (apiErr) {
|
|
128
|
+
if (apiErr.startsWith('InvalidClusterId')) {
|
|
129
|
+
throw new Error('目标集群不存在,请确认 ClusterId 是否正确');
|
|
130
|
+
}
|
|
131
|
+
if (apiErr.toLowerCase().includes('access denied')) {
|
|
132
|
+
console.error(apiErr);
|
|
133
|
+
throw new Error('对该集群没有权限(Access Denied)');
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`GetCluster 调用失败:${apiErr}`);
|
|
136
|
+
}
|
|
137
|
+
spinner.succeed(`获取成功: ${clusterId}`);
|
|
138
|
+
const json = options.pretty
|
|
139
|
+
? JSON.stringify(resp, null, 2)
|
|
140
|
+
: JSON.stringify(resp);
|
|
141
|
+
console.info(json);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
spinner.fail('获取集群信息失败');
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
clusterCmd
|
|
149
|
+
.command('sync')
|
|
150
|
+
.description('同步目标集群配置到本地客户端目录')
|
|
151
|
+
.option('--cluster-id <clusterId>', '目标 ClusterId')
|
|
152
|
+
.option('--dir <dir>', '客户端安装目录')
|
|
153
|
+
.option('--debug', '输出 requestId 和 canonical request 便于排查鉴权/权限问题', false)
|
|
154
|
+
.action(async (options) => {
|
|
155
|
+
const spinner = (0, ora_1.default)('开始同步集群配置...').start();
|
|
156
|
+
try {
|
|
157
|
+
const result = await syncClusterConfig(options);
|
|
158
|
+
if (options.debug) {
|
|
159
|
+
console.info('');
|
|
160
|
+
console.info(`RequestId: ${result.requestId || 'unknown'}`);
|
|
161
|
+
console.info('CanonicalRequest:');
|
|
162
|
+
console.info(result.canonicalRequest || '(empty)');
|
|
163
|
+
console.info('');
|
|
164
|
+
}
|
|
165
|
+
spinner.succeed(`集群配置同步完成: ${result.clusterId}`);
|
|
166
|
+
console.info(`配置目录: ${result.outputDir}`);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
spinner.fail('集群配置同步失败');
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -2,181 +2,20 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const confirm_1 = require("./runtime/confirm");
|
|
5
|
+
const auth_1 = require("./auth");
|
|
6
|
+
const client_1 = require("./client");
|
|
7
|
+
const cluster_1 = require("./cluster");
|
|
8
|
+
const version_1 = require("./version");
|
|
10
9
|
const program = new commander_1.Command();
|
|
11
10
|
program
|
|
12
|
-
.name(
|
|
13
|
-
.description(
|
|
14
|
-
.version(
|
|
15
|
-
program
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
process.env.VOLC_ACCESSKEY = opts.accessKey;
|
|
24
|
-
if (opts.secretKey)
|
|
25
|
-
process.env.VOLC_SECRETKEY = opts.secretKey;
|
|
26
|
-
if (opts.region)
|
|
27
|
-
process.env.VOLC_REGION = opts.region;
|
|
28
|
-
(0, config_1.resolveCredentials)();
|
|
29
|
-
const agent = new agent_1.Agent({
|
|
30
|
-
api: registry_1.apiRegistry,
|
|
31
|
-
memory: memory_1.memory
|
|
32
|
-
});
|
|
33
|
-
await agent.run(task, {
|
|
34
|
-
dryRun: opts.dryRun,
|
|
35
|
-
autoApprove: opts.yes
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
program
|
|
39
|
-
.command("init")
|
|
40
|
-
.description("Interactive wizard to initialize local credentials")
|
|
41
|
-
.option("--access-key <ak>", "Non-interactive access key")
|
|
42
|
-
.option("--secret-key <sk>", "Non-interactive secret key")
|
|
43
|
-
.option("--region <region>", "Default region", "cn-beijing")
|
|
44
|
-
.option("--llm-endpoint <url>", "Optional LLM endpoint (OpenAI compatible)")
|
|
45
|
-
.option("--llm-api-key <key>", "Optional LLM API key")
|
|
46
|
-
.option("--llm-model <model>", "Optional LLM model name")
|
|
47
|
-
.option("-f, --force", "Overwrite existing config without asking")
|
|
48
|
-
.action(async (opts) => {
|
|
49
|
-
const existing = (0, config_1.readLocalConfig)();
|
|
50
|
-
const hasExisting = !!(existing.accessKey || existing.secretKey);
|
|
51
|
-
if (hasExisting && !opts.force) {
|
|
52
|
-
console.log(`Detected existing config: ${(0, config_1.configFilePath)()}`);
|
|
53
|
-
const ok = await (0, confirm_1.confirm)("Overwrite existing credentials?");
|
|
54
|
-
if (!ok) {
|
|
55
|
-
console.log("Cancelled. No changes made.");
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const needInteractive = !opts.accessKey || !opts.secretKey;
|
|
60
|
-
const session = needInteractive ? (0, confirm_1.createPromptSession)() : null;
|
|
61
|
-
try {
|
|
62
|
-
const accessKey = opts.accessKey ||
|
|
63
|
-
(await session.ask("VOLC Access Key", {
|
|
64
|
-
defaultValue: existing.accessKey
|
|
65
|
-
}));
|
|
66
|
-
if (!accessKey) {
|
|
67
|
-
console.error("Access key is required.");
|
|
68
|
-
process.exitCode = 1;
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const secretKey = opts.secretKey ||
|
|
72
|
-
(await session.ask("VOLC Secret Key", { silent: true }));
|
|
73
|
-
if (!secretKey) {
|
|
74
|
-
console.error("Secret key is required.");
|
|
75
|
-
process.exitCode = 1;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const region = opts.region ||
|
|
79
|
-
(session
|
|
80
|
-
? await session.ask("Region", {
|
|
81
|
-
defaultValue: existing.region || "cn-beijing"
|
|
82
|
-
})
|
|
83
|
-
: existing.region || "cn-beijing") ||
|
|
84
|
-
"cn-beijing";
|
|
85
|
-
const llmEndpoint = opts.llmEndpoint ??
|
|
86
|
-
(session
|
|
87
|
-
? await session.ask("LLM endpoint (empty to skip)", {
|
|
88
|
-
defaultValue: existing.llm?.endpoint || ""
|
|
89
|
-
})
|
|
90
|
-
: existing.llm?.endpoint || "");
|
|
91
|
-
let llmApiKey = opts.llmApiKey;
|
|
92
|
-
let llmModel = opts.llmModel;
|
|
93
|
-
if (llmEndpoint && session) {
|
|
94
|
-
llmApiKey =
|
|
95
|
-
llmApiKey ??
|
|
96
|
-
(await session.ask("LLM API key", { silent: true }));
|
|
97
|
-
llmModel =
|
|
98
|
-
llmModel ??
|
|
99
|
-
(await session.ask("LLM model", {
|
|
100
|
-
defaultValue: existing.llm?.model || ""
|
|
101
|
-
}));
|
|
102
|
-
}
|
|
103
|
-
const payload = { accessKey, secretKey, region };
|
|
104
|
-
if (llmEndpoint) {
|
|
105
|
-
payload.llm = {
|
|
106
|
-
endpoint: llmEndpoint,
|
|
107
|
-
apiKey: llmApiKey || existing.llm?.apiKey,
|
|
108
|
-
model: llmModel || existing.llm?.model
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
const file = (0, config_1.writeLocalConfig)(payload);
|
|
112
|
-
console.log(`\n✓ Saved to ${file}`);
|
|
113
|
-
console.log({
|
|
114
|
-
accessKey: `${accessKey.slice(0, 4)}****`,
|
|
115
|
-
secretKey: "********",
|
|
116
|
-
region,
|
|
117
|
-
llm: llmEndpoint
|
|
118
|
-
? {
|
|
119
|
-
endpoint: llmEndpoint,
|
|
120
|
-
apiKey: payload.llm.apiKey ? "********" : undefined,
|
|
121
|
-
model: payload.llm.model || undefined
|
|
122
|
-
}
|
|
123
|
-
: "(not configured)"
|
|
124
|
-
});
|
|
125
|
-
console.log("\nTip: run `volc-emr-agent run \"列出集群\"` to verify.");
|
|
126
|
-
}
|
|
127
|
-
finally {
|
|
128
|
-
session?.close();
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
const config = program.command("config").description("Manage local credentials");
|
|
132
|
-
config
|
|
133
|
-
.command("set-credentials")
|
|
134
|
-
.description("Save AK/SK/region to local config (~/.volc-emr/config.json)")
|
|
135
|
-
.requiredOption("--access-key <ak>")
|
|
136
|
-
.requiredOption("--secret-key <sk>")
|
|
137
|
-
.option("--region <region>", "default cn-beijing", "cn-beijing")
|
|
138
|
-
.action((opts) => {
|
|
139
|
-
const file = (0, config_1.writeLocalConfig)({
|
|
140
|
-
accessKey: opts.accessKey,
|
|
141
|
-
secretKey: opts.secretKey,
|
|
142
|
-
region: opts.region
|
|
143
|
-
});
|
|
144
|
-
console.log(`Saved: ${file}`);
|
|
145
|
-
});
|
|
146
|
-
config
|
|
147
|
-
.command("set-llm")
|
|
148
|
-
.description("Save LLM endpoint config to local config")
|
|
149
|
-
.requiredOption("--endpoint <url>", "OpenAI-compatible Chat Completions URL")
|
|
150
|
-
.option("--api-key <key>")
|
|
151
|
-
.option("--model <model>")
|
|
152
|
-
.action((opts) => {
|
|
153
|
-
const file = (0, config_1.writeLocalConfig)({
|
|
154
|
-
llm: {
|
|
155
|
-
endpoint: opts.endpoint,
|
|
156
|
-
apiKey: opts.apiKey,
|
|
157
|
-
model: opts.model
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
console.log(`Saved LLM config: ${file}`);
|
|
161
|
-
});
|
|
162
|
-
config
|
|
163
|
-
.command("show")
|
|
164
|
-
.description("Show current local config (secrets are masked)")
|
|
165
|
-
.action(() => {
|
|
166
|
-
const cfg = (0, config_1.readLocalConfig)();
|
|
167
|
-
const masked = {
|
|
168
|
-
...cfg,
|
|
169
|
-
accessKey: cfg.accessKey ? `${cfg.accessKey.slice(0, 4)}****` : undefined,
|
|
170
|
-
secretKey: cfg.secretKey ? "********" : undefined,
|
|
171
|
-
llm: cfg.llm
|
|
172
|
-
? {
|
|
173
|
-
endpoint: cfg.llm.endpoint,
|
|
174
|
-
apiKey: cfg.llm.apiKey ? "********" : undefined,
|
|
175
|
-
model: cfg.llm.model
|
|
176
|
-
}
|
|
177
|
-
: undefined
|
|
178
|
-
};
|
|
179
|
-
console.log("file:", (0, config_1.configFilePath)());
|
|
180
|
-
console.log(masked);
|
|
181
|
-
});
|
|
182
|
-
program.parse();
|
|
11
|
+
.name('emr-cli')
|
|
12
|
+
.description('EMR 命令行工具 - 提交机认证、客户端部署与集群配置同步工具')
|
|
13
|
+
.version(version_1.VERSION);
|
|
14
|
+
(0, auth_1.registerAuthCommands)(program);
|
|
15
|
+
(0, client_1.registerClientCommands)(program);
|
|
16
|
+
(0, cluster_1.registerClusterCommands)(program);
|
|
17
|
+
program.parse(process.argv);
|
|
18
|
+
if (!process.argv.slice(2).length) {
|
|
19
|
+
program.outputHelp();
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveAuthConfig = resolveAuthConfig;
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
function resolveAuthConfig(overrides = {}) {
|
|
6
|
+
const config = (0, config_1.tryLoadConfig)();
|
|
7
|
+
const result = {
|
|
8
|
+
ak: overrides.ak || config.ak || '',
|
|
9
|
+
sk: overrides.sk || config.sk || '',
|
|
10
|
+
region: overrides.region || config.region || '',
|
|
11
|
+
clusterId: overrides.clusterId || config.clusterId,
|
|
12
|
+
};
|
|
13
|
+
if (!result.ak || !result.sk || !result.region) {
|
|
14
|
+
throw new Error('认证配置缺失,请先执行 emr-cli auth init 完成 AccessKey、SecretKey 和 Region 配置');
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ClientInstallState {
|
|
2
|
+
version: string;
|
|
3
|
+
installedAt: string;
|
|
4
|
+
packageUrl?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getDefaultClientDir(): string;
|
|
7
|
+
export declare function resolveClientDir(dir?: string): string;
|
|
8
|
+
export declare function getClientStatePath(dir?: string): string;
|
|
9
|
+
export declare function ensureClientDir(dir?: string): string;
|
|
10
|
+
export declare function readClientState(dir?: string): ClientInstallState | undefined;
|
|
11
|
+
export declare function writeClientState(state: ClientInstallState, dir?: string): void;
|
|
12
|
+
export declare function isClientInstalled(dir?: string): boolean;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getDefaultClientDir = getDefaultClientDir;
|
|
37
|
+
exports.resolveClientDir = resolveClientDir;
|
|
38
|
+
exports.getClientStatePath = getClientStatePath;
|
|
39
|
+
exports.ensureClientDir = ensureClientDir;
|
|
40
|
+
exports.readClientState = readClientState;
|
|
41
|
+
exports.writeClientState = writeClientState;
|
|
42
|
+
exports.isClientInstalled = isClientInstalled;
|
|
43
|
+
const fs = __importStar(require("node:fs"));
|
|
44
|
+
const node_os_1 = require("node:os");
|
|
45
|
+
const path = __importStar(require("node:path"));
|
|
46
|
+
const config_1 = require("./config");
|
|
47
|
+
function getDefaultClientDir() {
|
|
48
|
+
return path.join((0, node_os_1.homedir)(), '.emr-cli', 'client');
|
|
49
|
+
}
|
|
50
|
+
function resolveClientDir(dir) {
|
|
51
|
+
return dir || (0, config_1.tryLoadConfig)().clientInstallDir || getDefaultClientDir();
|
|
52
|
+
}
|
|
53
|
+
function getClientStatePath(dir) {
|
|
54
|
+
return path.join(resolveClientDir(dir), '.emr-cli-client.json');
|
|
55
|
+
}
|
|
56
|
+
function ensureClientDir(dir) {
|
|
57
|
+
const clientDir = resolveClientDir(dir);
|
|
58
|
+
fs.mkdirSync(clientDir, { recursive: true });
|
|
59
|
+
fs.mkdirSync(path.join(clientDir, 'conf'), { recursive: true });
|
|
60
|
+
return clientDir;
|
|
61
|
+
}
|
|
62
|
+
function readClientState(dir) {
|
|
63
|
+
const file = getClientStatePath(dir);
|
|
64
|
+
if (!fs.existsSync(file)) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
68
|
+
}
|
|
69
|
+
function writeClientState(state, dir) {
|
|
70
|
+
const clientDir = ensureClientDir(dir);
|
|
71
|
+
fs.writeFileSync(path.join(clientDir, '.emr-cli-client.json'), JSON.stringify(state, null, 2));
|
|
72
|
+
(0, config_1.updateConfig)({
|
|
73
|
+
clientInstallDir: clientDir,
|
|
74
|
+
installedClientVersion: state.version,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function isClientInstalled(dir) {
|
|
78
|
+
return Boolean(readClientState(dir));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=client-state.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface EmrCliConfig {
|
|
2
|
+
ak?: string;
|
|
3
|
+
sk?: string;
|
|
4
|
+
region?: string;
|
|
5
|
+
clusterId?: string;
|
|
6
|
+
clientInstallDir?: string;
|
|
7
|
+
installedClientVersion?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function getConfigDir(): string;
|
|
10
|
+
export declare function getConfigPath(): string;
|
|
11
|
+
export declare function ensureConfigDir(): void;
|
|
12
|
+
export declare function loadConfig(): EmrCliConfig;
|
|
13
|
+
export declare function tryLoadConfig(): EmrCliConfig;
|
|
14
|
+
export declare function saveConfig(config: EmrCliConfig): void;
|
|
15
|
+
export declare function updateConfig(patch: Partial<EmrCliConfig>): EmrCliConfig;
|
|
16
|
+
export declare function clearConfig(): void;
|
|
17
|
+
export declare function maskSecret(value?: string): string;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getConfigDir = getConfigDir;
|
|
37
|
+
exports.getConfigPath = getConfigPath;
|
|
38
|
+
exports.ensureConfigDir = ensureConfigDir;
|
|
39
|
+
exports.loadConfig = loadConfig;
|
|
40
|
+
exports.tryLoadConfig = tryLoadConfig;
|
|
41
|
+
exports.saveConfig = saveConfig;
|
|
42
|
+
exports.updateConfig = updateConfig;
|
|
43
|
+
exports.clearConfig = clearConfig;
|
|
44
|
+
exports.maskSecret = maskSecret;
|
|
45
|
+
const fs = __importStar(require("node:fs"));
|
|
46
|
+
const node_os_1 = require("node:os");
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
function getConfigDir() {
|
|
49
|
+
return path.join((0, node_os_1.homedir)(), '.emr-cli');
|
|
50
|
+
}
|
|
51
|
+
function getConfigPath() {
|
|
52
|
+
return path.join(getConfigDir(), 'config.json');
|
|
53
|
+
}
|
|
54
|
+
function ensureConfigDir() {
|
|
55
|
+
const dir = getConfigDir();
|
|
56
|
+
if (!fs.existsSync(dir)) {
|
|
57
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function loadConfig() {
|
|
61
|
+
ensureConfigDir();
|
|
62
|
+
const file = getConfigPath();
|
|
63
|
+
if (!fs.existsSync(file)) {
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
67
|
+
const parsed = JSON.parse(content);
|
|
68
|
+
if (parsed && typeof parsed === 'object') {
|
|
69
|
+
return parsed;
|
|
70
|
+
}
|
|
71
|
+
throw new Error('配置文件格式不正确,请重新执行 emr-cli auth init 初始化配置');
|
|
72
|
+
}
|
|
73
|
+
function tryLoadConfig() {
|
|
74
|
+
try {
|
|
75
|
+
return loadConfig();
|
|
76
|
+
}
|
|
77
|
+
catch (_error) {
|
|
78
|
+
throw new Error('配置文件损坏或无法解析,请重新执行 emr-cli auth init 初始化配置');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function saveConfig(config) {
|
|
82
|
+
ensureConfigDir();
|
|
83
|
+
fs.writeFileSync(getConfigPath(), JSON.stringify(config, null, 2), {
|
|
84
|
+
mode: 0o600,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
function updateConfig(patch) {
|
|
88
|
+
const config = tryLoadConfig();
|
|
89
|
+
const next = { ...config, ...patch };
|
|
90
|
+
saveConfig(next);
|
|
91
|
+
return next;
|
|
92
|
+
}
|
|
93
|
+
function clearConfig() {
|
|
94
|
+
saveConfig({});
|
|
95
|
+
}
|
|
96
|
+
function maskSecret(value) {
|
|
97
|
+
if (!value)
|
|
98
|
+
return '未设置';
|
|
99
|
+
if (value.length <= 8)
|
|
100
|
+
return '****';
|
|
101
|
+
return `${value.slice(0, 4)}...${value.slice(-4)}`;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface HttpResponse<T> {
|
|
2
|
+
statusCode: number;
|
|
3
|
+
headers: Record<string, string | string[] | undefined>;
|
|
4
|
+
data: T;
|
|
5
|
+
raw: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function httpsJsonRequest<T>(params: {
|
|
8
|
+
url: string;
|
|
9
|
+
method: 'POST' | 'GET';
|
|
10
|
+
headers?: Record<string, string>;
|
|
11
|
+
body?: string;
|
|
12
|
+
timeoutMs?: number;
|
|
13
|
+
}): Promise<HttpResponse<T>>;
|