@numa-tech/numa 1.14.51 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -21
- package/dist/ai-registry/commands.js.map +1 -1
- package/dist/ai-registry/mcp-installer.d.ts +1 -1
- package/dist/ai-registry/mcp-installer.js +9 -0
- package/dist/ai-registry/mcp-installer.js.map +1 -1
- package/dist/cli.js +21 -3
- package/dist/cli.js.map +1 -1
- package/dist/cloud/accounts.d.ts +20 -0
- package/dist/cloud/accounts.js +87 -0
- package/dist/cloud/accounts.js.map +1 -0
- package/dist/cloud/bootstrap.d.ts +182 -0
- package/dist/cloud/bootstrap.js +277 -0
- package/dist/cloud/bootstrap.js.map +1 -0
- package/dist/cloud/business-bootstrap.d.ts +62 -0
- package/dist/cloud/business-bootstrap.js +51 -0
- package/dist/cloud/business-bootstrap.js.map +1 -0
- package/dist/cloud/commands.d.ts +2 -0
- package/dist/cloud/commands.js +39 -0
- package/dist/cloud/commands.js.map +1 -0
- package/dist/cloud/maintenance.d.ts +78 -0
- package/dist/cloud/maintenance.js +210 -0
- package/dist/cloud/maintenance.js.map +1 -0
- package/dist/cloud/oss-bootstrap.d.ts +11 -0
- package/dist/cloud/oss-bootstrap.js +36 -0
- package/dist/cloud/oss-bootstrap.js.map +1 -0
- package/dist/cloud/wizard.d.ts +25 -0
- package/dist/cloud/wizard.js +239 -0
- package/dist/cloud/wizard.js.map +1 -0
- package/dist/command-catalog.js +34 -1
- package/dist/command-catalog.js.map +1 -1
- package/dist/mcp/commands.d.ts +7 -0
- package/dist/mcp/commands.js +54 -0
- package/dist/mcp/commands.js.map +1 -0
- package/dist/mcp/install.d.ts +48 -0
- package/dist/mcp/install.js +138 -0
- package/dist/mcp/install.js.map +1 -0
- package/dist/mcp/modules.d.ts +4 -0
- package/dist/mcp/modules.js +11 -0
- package/dist/mcp/modules.js.map +1 -0
- package/dist/oss/commands.d.ts +3 -0
- package/dist/oss/commands.js +75 -8
- package/dist/oss/commands.js.map +1 -1
- package/dist/oss/search.d.ts +70 -0
- package/dist/oss/search.js +172 -0
- package/dist/oss/search.js.map +1 -0
- package/dist/oss/tools.d.ts +8 -0
- package/dist/oss/tools.js +69 -0
- package/dist/oss/tools.js.map +1 -0
- package/dist/oss/transfers.d.ts +17 -2
- package/dist/oss/transfers.js +29 -7
- package/dist/oss/transfers.js.map +1 -1
- package/dist/server.d.ts +4 -0
- package/dist/server.js +175 -164
- package/dist/server.js.map +1 -1
- package/dist/wecom/tools.js +15 -4
- package/dist/wecom/tools.js.map +1 -1
- package/examples/cloud-bootstrap/README.md +58 -0
- package/package.json +4 -4
- package/skills/numa-cli/SKILL.md +3 -2
- package/skills/numa-cli/agents/openai.yaml +1 -1
- package/skills/numa-cli/evals/evals.json +19 -1
- package/skills/numa-cli/numa-skill.json +1 -1
- package/skills/numa-cli/references/cli-mcp.md +74 -0
- package/skills/numa-oss-access/SKILL.md +7 -3
- package/skills/numa-oss-access/agents/openai.yaml +1 -1
- package/skills/numa-oss-access/evals/evals.json +18 -0
- package/skills/numa-oss-access/numa-skill.json +2 -2
- package/skills/numa-oss-access/references/cli-bootstrap.md +2 -2
- package/skills/numa-oss-access/references/search-and-mcp.md +63 -0
- package/skills/numa-wecom/SKILL.md +7 -3
- package/skills/numa-wecom/numa-skill.json +2 -2
- package/skills/numa-wecom/references/cli-bootstrap.md +2 -2
- package/skills/numa-wecom/references/mcp.md +12 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { access } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { appConfigPath } from "../app-config.js";
|
|
4
|
+
import { bootstrapApi, viewSchema, record, canonical, policyDocument, optional, trust, validateCloudMetadata, withOAuth, createEncryptedKey, saveReceipt, readReceipt, CloudCommandError, PlatformBootstrapApiError } from "./bootstrap.js";
|
|
5
|
+
export async function inspectMaintenance(plan, keyId, call) {
|
|
6
|
+
validateCloudMetadata(plan);
|
|
7
|
+
const identity = await call("sts", "GetCallerIdentity");
|
|
8
|
+
if (identity.AccountId !== plan.accountUid)
|
|
9
|
+
throw new Error("阿里云登录账号与计划 UID 不一致。");
|
|
10
|
+
const differences = [], actions = [];
|
|
11
|
+
const diff = (code, resource, actual, expected, blocked = false) => differences.push({ code, resource, actual: typeof actual === "string" ? actual : JSON.stringify(actual ?? null), expected: typeof expected === "string" ? expected : JSON.stringify(expected ?? null), blocked });
|
|
12
|
+
const add = (stage, action, args) => actions.push({ stage, action, args });
|
|
13
|
+
const user = await optional(call, "GetUser", { UserName: plan.username }, "User");
|
|
14
|
+
const role = await optional(call, "GetRole", { RoleName: plan.managementRoleName }, "Role");
|
|
15
|
+
if (!user) {
|
|
16
|
+
diff("USER_MISSING", plan.username, "不存在", "补建系统入口用户");
|
|
17
|
+
add("USER", "CreateUser", { UserName: plan.username, DisplayName: plan.userDisplayName ?? "DevOps platform entry", Comments: plan.userComments ?? plan.ownershipMarker });
|
|
18
|
+
}
|
|
19
|
+
else if (user.Comments !== (plan.userComments ?? plan.ownershipMarker) && !String(user.Comments ?? "").includes(plan.ownershipMarker)) {
|
|
20
|
+
diff("OWNERSHIP_CONFLICT", plan.username, "同名用户的归属标记已改变", "请人工核对归属", true);
|
|
21
|
+
}
|
|
22
|
+
else if (user.Comments !== (plan.userComments ?? plan.ownershipMarker) || user.DisplayName !== (plan.userDisplayName ?? "DevOps platform entry")) {
|
|
23
|
+
diff("USER_METADATA", plan.username, { Comments: user.Comments, DisplayName: user.DisplayName }, { Comments: plan.userComments ?? plan.ownershipMarker, DisplayName: plan.userDisplayName ?? "DevOps platform entry" });
|
|
24
|
+
add("USER", "UpdateUser", { UserName: plan.username, NewDisplayName: plan.userDisplayName ?? "DevOps platform entry", NewComments: plan.userComments ?? plan.ownershipMarker });
|
|
25
|
+
}
|
|
26
|
+
if (!role) {
|
|
27
|
+
diff("ROLE_MISSING", plan.managementRoleName, "不存在", "补建管理 Role");
|
|
28
|
+
add("MANAGEMENT_ROLE", "CreateRole", { RoleName: plan.managementRoleName, Description: plan.managementRoleDescription ?? plan.ownershipMarker, AssumeRolePolicyDocument: JSON.stringify(trust(plan)) });
|
|
29
|
+
}
|
|
30
|
+
else if (role.Description !== (plan.managementRoleDescription ?? plan.ownershipMarker) && !String(role.Description ?? "").includes(plan.ownershipMarker)) {
|
|
31
|
+
diff("OWNERSHIP_CONFLICT", plan.managementRoleName, "同名 Role 的归属标记已改变", "请人工核对归属", true);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
if (role.Description !== (plan.managementRoleDescription ?? plan.ownershipMarker)) {
|
|
35
|
+
diff("ROLE_METADATA", plan.managementRoleName, role.Description ?? "", plan.managementRoleDescription ?? plan.ownershipMarker);
|
|
36
|
+
add("MANAGEMENT_ROLE", "UpdateRole", { RoleName: plan.managementRoleName, NewDescription: plan.managementRoleDescription ?? plan.ownershipMarker });
|
|
37
|
+
}
|
|
38
|
+
const observed = policyDocument(role.AssumeRolePolicyDocument);
|
|
39
|
+
if (canonical(observed) !== canonical(trust(plan))) {
|
|
40
|
+
diff("TRUST_DRIFT", plan.managementRoleName, observed, trust(plan));
|
|
41
|
+
add("MANAGEMENT_ROLE", "UpdateRole", { RoleName: plan.managementRoleName, NewAssumeRolePolicyDocument: JSON.stringify(trust(plan)) });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
for (const [name, expected, stage] of [[plan.managementPolicyName, plan.managementPolicy, "MANAGEMENT_POLICY"], [plan.entryPolicyName, plan.entryPolicy, "ENTRY_POLICY"]]) {
|
|
45
|
+
const policy = await optional(call, "GetPolicy", { PolicyName: name, PolicyType: "Custom" }, "Policy");
|
|
46
|
+
if (!policy) {
|
|
47
|
+
diff("POLICY_MISSING", name, "不存在", expected);
|
|
48
|
+
add(stage, "CreatePolicy", { PolicyName: name, Description: plan.ownershipMarker, PolicyDocument: JSON.stringify(expected) });
|
|
49
|
+
}
|
|
50
|
+
else if (policy.Description !== plan.ownershipMarker)
|
|
51
|
+
diff("OWNERSHIP_CONFLICT", name, "策略归属标记已改变", "请人工核对归属", true);
|
|
52
|
+
else {
|
|
53
|
+
if (typeof policy.DefaultVersion !== "string")
|
|
54
|
+
throw new Error("云端策略版本响应不完整。");
|
|
55
|
+
const version = record((await call("ram", "GetPolicyVersion", { PolicyType: "Custom", PolicyName: name, VersionId: policy.DefaultVersion })).PolicyVersion);
|
|
56
|
+
const observed = policyDocument(version.PolicyDocument);
|
|
57
|
+
if (canonical(observed) !== canonical(expected)) {
|
|
58
|
+
diff("POLICY_DRIFT", name, observed, expected);
|
|
59
|
+
add(stage, "CreatePolicyVersion", { PolicyName: name, PolicyDocument: JSON.stringify(expected), SetAsDefault: "true", RotateStrategy: "None" });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
for (const [exists, target, targetField, policy, stage, kind] of [[!!user, plan.username, "UserName", plan.entryPolicyName, "ENTRY_POLICY", "User"], [!!role, plan.managementRoleName, "RoleName", plan.managementPolicyName, "MANAGEMENT_POLICY", "Role"]]) {
|
|
64
|
+
const response = exists ? await call("ram", "ListPoliciesFor" + kind, { [targetField]: target }) : { Policies: { Policy: [] } };
|
|
65
|
+
const policies = record(response.Policies).Policy;
|
|
66
|
+
if (!Array.isArray(policies) || response.IsTruncated === true)
|
|
67
|
+
throw new Error("策略绑定结果不完整,停止检查。");
|
|
68
|
+
let attached = false;
|
|
69
|
+
for (const value of policies) {
|
|
70
|
+
const binding = record(value);
|
|
71
|
+
if (typeof binding.PolicyName !== "string" || !["Custom", "System"].includes(String(binding.PolicyType)))
|
|
72
|
+
throw new Error("策略绑定字段无效。");
|
|
73
|
+
if (binding.PolicyName === policy && binding.PolicyType === "Custom")
|
|
74
|
+
attached = true;
|
|
75
|
+
else {
|
|
76
|
+
diff("EXTRA_BINDING", target + ":" + binding.PolicyName, binding.PolicyType + "/" + binding.PolicyName, "移除不在初始化配置中的直接策略绑定");
|
|
77
|
+
add(stage, "DetachPolicyFrom" + kind, { [targetField]: target, PolicyType: String(binding.PolicyType), PolicyName: binding.PolicyName });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!attached) {
|
|
81
|
+
diff("BINDING_MISSING", target, "未绑定 " + policy, "绑定 Custom/" + policy);
|
|
82
|
+
add(stage, "AttachPolicyTo" + kind, { [targetField]: target, PolicyType: "Custom", PolicyName: policy });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const keys = user ? record((await call("ram", "ListAccessKeys", { UserName: plan.username })).AccessKeys).AccessKey : [];
|
|
86
|
+
if (!Array.isArray(keys))
|
|
87
|
+
throw new Error("AK 清单响应不完整。");
|
|
88
|
+
const active = keys.some(value => { const key = record(value); return key.AccessKeyId === keyId && String(key.Status).toLowerCase() === "active"; });
|
|
89
|
+
if (!active) {
|
|
90
|
+
diff("KEY_REPLACE", plan.username, "托管 AK 缺失或停用", "创建新 AK,验证后切换;不删除其他 AK");
|
|
91
|
+
if (keys.length >= 2)
|
|
92
|
+
diff("KEY_CAPACITY", plan.username, "已有两把 AK", "请先人工确认并清理不再使用的 AK", true);
|
|
93
|
+
}
|
|
94
|
+
return { report: { status: differences.length ? differences.some(d => d.blocked) ? "BLOCKED" : "DRIFT" : "HEALTHY", differences }, actions, replaceKey: !active };
|
|
95
|
+
}
|
|
96
|
+
export async function executeMaintenanceActions(plan, inspection, call, checkpoint, handoff) {
|
|
97
|
+
if (inspection.report.status === "BLOCKED")
|
|
98
|
+
throw new Error("存在需要人工核对的差异,未执行修复。");
|
|
99
|
+
for (const operation of inspection.actions) {
|
|
100
|
+
await checkpoint(operation.stage, "STARTED");
|
|
101
|
+
try {
|
|
102
|
+
await call("ram", operation.action, operation.args);
|
|
103
|
+
await checkpoint(operation.stage, "SUCCEEDED");
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
await checkpoint(operation.stage, "FAILED").catch(() => { });
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (inspection.replaceKey)
|
|
111
|
+
await createEncryptedKey(plan, call, checkpoint, handoff);
|
|
112
|
+
}
|
|
113
|
+
export async function executeMaintenance(current, options, deps = {}) {
|
|
114
|
+
const api = deps.api ?? bootstrapApi;
|
|
115
|
+
const id = current.plan.id;
|
|
116
|
+
let view = viewSchema.parse(await api(`/sessions/${id}/start`, {}));
|
|
117
|
+
const executionId = view.execution?.id;
|
|
118
|
+
if (!executionId)
|
|
119
|
+
throw new Error("维护执行租约不存在。");
|
|
120
|
+
const receiptPath = deps.receiptPath ?? join(dirname(appConfigPath()), "cloud-bootstrap", `${id}.json`);
|
|
121
|
+
let failure;
|
|
122
|
+
let heartbeat;
|
|
123
|
+
const timer = setInterval(() => { if (!heartbeat)
|
|
124
|
+
heartbeat = api(`/sessions/${id}/heartbeat`, { executionId }).catch(e => { failure = e; }).finally(() => { heartbeat = undefined; }); }, 30000);
|
|
125
|
+
const checkpoint = async (stage, status) => { if (failure)
|
|
126
|
+
throw failure; view = viewSchema.parse(await api(`/sessions/${id}/progress`, { executionId, stage, status })); options.display(stage, status); };
|
|
127
|
+
const persist = async (inspection) => { view = viewSchema.parse(await api(`/sessions/${id}/report`, { executionId, report: inspection.report })); };
|
|
128
|
+
const handoff = async (ciphertext) => { await saveReceipt(receiptPath, id, ciphertext); view = viewSchema.parse(await api(`/sessions/${id}/receipt`, { executionId, ciphertext })); };
|
|
129
|
+
const inspect = async (call) => {
|
|
130
|
+
await checkpoint("PREFLIGHT", "STARTED");
|
|
131
|
+
const result = await inspectMaintenance(view.plan, view.maintenance?.accessKeyId, call);
|
|
132
|
+
await persist(result);
|
|
133
|
+
await checkpoint("PREFLIGHT", "SUCCEEDED");
|
|
134
|
+
return result;
|
|
135
|
+
};
|
|
136
|
+
const guarded = (call) => async (...args) => { if (failure)
|
|
137
|
+
throw failure; return call(...args); };
|
|
138
|
+
try {
|
|
139
|
+
if (!view.receiptStored && await access(receiptPath).then(() => true, () => false))
|
|
140
|
+
view = viewSchema.parse(await api(`/sessions/${id}/receipt`, { executionId, ...await readReceipt(receiptPath, id) }));
|
|
141
|
+
{
|
|
142
|
+
if (!view.receiptStored && view.events.some(e => e.stage === "KEY" && e.status === "STARTED"))
|
|
143
|
+
throw new Error("AK 创建结果尚未确认,请恢复原机器回执;不会再次创建 AK。");
|
|
144
|
+
const platformCall = guarded(async (product, action, args = {}) => {
|
|
145
|
+
const result = record(await api(`/sessions/${id}/cloud-read`, { executionId, product, action, args }));
|
|
146
|
+
if (typeof result.errorCode === "string")
|
|
147
|
+
throw new CloudCommandError(action, result.errorCode);
|
|
148
|
+
return result;
|
|
149
|
+
});
|
|
150
|
+
let initial;
|
|
151
|
+
try {
|
|
152
|
+
initial = await inspect(platformCall);
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
if (!(e instanceof PlatformBootstrapApiError) || e.status !== 503)
|
|
156
|
+
throw e;
|
|
157
|
+
}
|
|
158
|
+
if (initial && (view.maintenance?.operation === "CHECK" || initial.report.status === "HEALTHY")) {
|
|
159
|
+
await checkpoint("IMPORT", "STARTED");
|
|
160
|
+
return viewSchema.parse(await api(`/sessions/${id}/maintenance-finish`, { executionId }));
|
|
161
|
+
}
|
|
162
|
+
if (initial?.report.status === "BLOCKED")
|
|
163
|
+
throw new Error("检查发现归属冲突或 AK 容量不足,请先核对页面差异。");
|
|
164
|
+
if (!await options.oauthFallback())
|
|
165
|
+
throw new Error("已暂停维护,检查结果已保留。");
|
|
166
|
+
await checkpoint("LOGIN", "STARTED");
|
|
167
|
+
await (deps.oauth ?? withOAuth)(options.binary, async (cli) => {
|
|
168
|
+
await checkpoint("LOGIN", "SUCCEEDED");
|
|
169
|
+
const call = guarded(cli.call);
|
|
170
|
+
let observed = await inspect(call);
|
|
171
|
+
if (view.maintenance?.operation === "CHECK" || observed.report.status === "HEALTHY")
|
|
172
|
+
return;
|
|
173
|
+
if (observed.report.status === "BLOCKED")
|
|
174
|
+
throw new Error("检查发现归属冲突或 AK 容量不足,请先核对页面差异。");
|
|
175
|
+
if (view.receiptStored && observed.replaceKey)
|
|
176
|
+
throw new Error("AK 创建结果已保存,但该 AK 又被删除或停用,请人工核对;不会再次创建 AK。");
|
|
177
|
+
if (!await options.approve(view))
|
|
178
|
+
throw new Error("已暂停修复,差异已保留。");
|
|
179
|
+
// Re-read after human approval. Any change requires another confirmation.
|
|
180
|
+
const rechecked = await inspectMaintenance(view.plan, view.maintenance?.accessKeyId, call);
|
|
181
|
+
if (canonical(rechecked.report) !== canonical(observed.report)) {
|
|
182
|
+
await persist(rechecked);
|
|
183
|
+
throw new Error("云端差异在确认期间发生变化,请重新确认后修复。");
|
|
184
|
+
}
|
|
185
|
+
view = viewSchema.parse(await api(`/sessions/${id}/approve-repair`, { executionId, reportHash: view.maintenance?.reportHash }));
|
|
186
|
+
observed = rechecked;
|
|
187
|
+
await executeMaintenanceActions(view.plan, observed, call, checkpoint, handoff);
|
|
188
|
+
await inspect(call);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
await checkpoint("IMPORT", "STARTED");
|
|
192
|
+
const done = viewSchema.parse(await api(`/sessions/${id}/maintenance-finish`, { executionId }));
|
|
193
|
+
options.display("IMPORT", "SUCCEEDED");
|
|
194
|
+
return done;
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
clearInterval(timer);
|
|
198
|
+
if (heartbeat)
|
|
199
|
+
await heartbeat;
|
|
200
|
+
const reasonCode = error instanceof CloudCommandError ? "ALIYUN_" + error.cloudCode : error instanceof Error && error.message.includes("AK 创建结果") ? "KEY_OUTCOME_UNKNOWN" : error instanceof Error && error.message.startsWith("已暂停") ? "USER_PAUSED" : "MAINTENANCE_INTERRUPTED";
|
|
201
|
+
await api(`/sessions/${id}/pause`, { executionId, reasonCode }).catch(() => { });
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
clearInterval(timer);
|
|
206
|
+
if (heartbeat)
|
|
207
|
+
await heartbeat;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=maintenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintenance.js","sourceRoot":"","sources":["../../src/cloud/maintenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OssClient } from "../oss/client.js";
|
|
2
|
+
import type { OssBootstrapPlan } from "../oss/schemas.js";
|
|
3
|
+
type BootstrapClient = Pick<OssClient, "bootstrapStatus" | "bootstrapPreview" | "bootstrapApply">;
|
|
4
|
+
declare function approvePlan(plan: OssBootstrapPlan): Promise<boolean>;
|
|
5
|
+
/** Uses the same read/preview/approved-plan contract as `oss bootstrap`. No automatic write retries. */
|
|
6
|
+
export declare function runOssBootstrap(accountId: number, json?: boolean, dependencies?: {
|
|
7
|
+
client?: BootstrapClient;
|
|
8
|
+
approve?: typeof approvePlan;
|
|
9
|
+
display?: (message: string) => void;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { confirm, isCancel, note, outro } from "@clack/prompts";
|
|
2
|
+
import { loadConfig } from "../config.js";
|
|
3
|
+
import { OssClient } from "../oss/client.js";
|
|
4
|
+
import { sanitizeOssOutput } from "../oss/errors.js";
|
|
5
|
+
async function approvePlan(plan) {
|
|
6
|
+
note(`平台账号 ID:${plan.state.accountId}\n默认 Role:${plan.state.roleName}\n操作:${plan.roleAction}\n${plan.purpose}\n信任策略:${plan.trustPolicy}\n\n执行会将本账号 OSS 代理扮演清单固定为默认 Role;不会发布 Policy 或创建 Grant。`, "默认 OSS Role 初始化范围", { output: process.stderr });
|
|
7
|
+
const answer = await confirm({ message: "按以上计划初始化默认 OSS Role?", initialValue: false, output: process.stderr });
|
|
8
|
+
return !isCancel(answer) && answer;
|
|
9
|
+
}
|
|
10
|
+
/** Uses the same read/preview/approved-plan contract as `oss bootstrap`. No automatic write retries. */
|
|
11
|
+
export async function runOssBootstrap(accountId, json = false, dependencies = {}) {
|
|
12
|
+
const client = dependencies.client ?? new OssClient(loadConfig("platform"));
|
|
13
|
+
const display = dependencies.display ?? (message => outro(message, { output: process.stderr }));
|
|
14
|
+
let state = await client.bootstrapStatus(accountId);
|
|
15
|
+
if (!state.ready) {
|
|
16
|
+
if (state.state === "RUNNING") {
|
|
17
|
+
display("OSS 初始化仍在执行;请稍后查询状态,不会重复提交。");
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const plan = await client.bootstrapPreview(accountId);
|
|
21
|
+
if (!await (dependencies.approve ?? approvePlan)(plan)) {
|
|
22
|
+
display(`已保留 OSS 计划 ${plan.state.planId};尚未执行,可按同一 UID 继续。`);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (!plan.state.planId)
|
|
26
|
+
throw new Error("OSS 初始化预览缺少计划 ID,未执行。");
|
|
27
|
+
state = await client.bootstrapApply(accountId, plan.state.planId);
|
|
28
|
+
}
|
|
29
|
+
if (!state.ready)
|
|
30
|
+
throw new Error("OSS 初始化尚未就绪,请核对任务状态。");
|
|
31
|
+
display(`默认 OSS Role ${state.roleName} 已就绪。请在策略绑定与授权中配置业务访问。`);
|
|
32
|
+
if (json)
|
|
33
|
+
process.stdout.write(JSON.stringify(sanitizeOssOutput({ ok: true, oss: state })) + "\n");
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=oss-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oss-bootstrap.js","sourceRoot":"","sources":["../../src/cloud/oss-bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAIrD,KAAK,UAAU,WAAW,CAAC,IAAsB;IAC/C,IAAI,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,SAAS,aAAa,IAAI,CAAC,KAAK,CAAC,QAAQ,QAAQ,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,OAAO,UAAU,IAAI,CAAC,WAAW,yDAAyD,EAAE,mBAAmB,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClP,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/G,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;AACrC,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,EAAE,IAAI,GAAG,KAAK,EAAE,YAAY,GAE/E,EAAE;IACJ,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,IAAI,IAAI,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChG,IAAI,KAAK,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,6BAA6B,CAAC,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,cAAc,IAAI,CAAC,KAAK,CAAC,MAAM,oBAAoB,CAAC,CAAC;YAC7D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACjE,KAAK,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1D,OAAO,CAAC,eAAe,KAAK,CAAC,QAAQ,wBAAwB,CAAC,CAAC;IAC/D,IAAI,IAAI;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACnG,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { resolveBootstrapAccount } from "./accounts.js";
|
|
2
|
+
import { bootstrapApi, type BootstrapView, type CloudCall } from "./bootstrap.js";
|
|
3
|
+
export declare function progressSummary(view: BootstrapView): string;
|
|
4
|
+
export declare function findWizardSession(options: {
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
accountUid?: string;
|
|
7
|
+
}, api?: typeof bootstrapApi, resolveAccount?: typeof resolveBootstrapAccount): Promise<BootstrapView>;
|
|
8
|
+
/** All recovery decisions use server state. Only the encrypted handoff journal is also kept locally. */
|
|
9
|
+
export declare function executeWizardSession(current: BootstrapView, options: {
|
|
10
|
+
binary: string;
|
|
11
|
+
approve: (view: BootstrapView) => Promise<boolean>;
|
|
12
|
+
display: (stage: string, status: string) => void;
|
|
13
|
+
}, dependencies?: {
|
|
14
|
+
api?: typeof bootstrapApi;
|
|
15
|
+
oauth?: <T>(binary: string, run: (cli: {
|
|
16
|
+
call: CloudCall;
|
|
17
|
+
}) => Promise<T>) => Promise<T>;
|
|
18
|
+
receiptPath?: string;
|
|
19
|
+
}): Promise<BootstrapView>;
|
|
20
|
+
export declare function runBootstrapWizard(options: {
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
accountUid?: string;
|
|
23
|
+
aliyunBin?: string;
|
|
24
|
+
confirmAccount?: string;
|
|
25
|
+
}, json?: boolean): Promise<void>;
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { runOssBootstrap } from "./oss-bootstrap.js";
|
|
2
|
+
import { intro, outro, note, select, text, confirm, isCancel } from "@clack/prompts";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { runBusinessBootstrap, businessStatusSchema } from "./business-bootstrap.js";
|
|
6
|
+
import { executeMaintenance } from "./maintenance.js";
|
|
7
|
+
import { appConfigPath } from "../app-config.js";
|
|
8
|
+
import { resolveBootstrapAccount } from "./accounts.js";
|
|
9
|
+
import { bootstrapApi, viewSchema, withOAuth, preflight, validateCloudMetadata, executePlan, saveReceipt, readReceipt, PlatformBootstrapApiError, CloudCommandError } from "./bootstrap.js";
|
|
10
|
+
const labels = { LOGIN: "阿里云登录", IDENTITY: "核对云账号", PREFLIGHT: "核对云端现状", USER: "系统 RAM 用户", MANAGEMENT_ROLE: "管理 Role", MANAGEMENT_POLICY: "管理权限策略", ENTRY_POLICY: "角色扮演权限", KEY: "创建并保存加密凭据", IMPORT: "验证并切换平台凭据" };
|
|
11
|
+
const statuses = { STARTED: "处理中 / 待核对", SUCCEEDED: "已完成", FAILED: "未完成,等待恢复" };
|
|
12
|
+
export function progressSummary(view) {
|
|
13
|
+
const latest = new Map(view.events.map(event => [event.stage, event.status]));
|
|
14
|
+
return Object.entries(labels).map(([stage, label]) => `${label}:${latest.has(stage) ? statuses[latest.get(stage)] ?? latest.get(stage) : "待执行"}`).join("\n");
|
|
15
|
+
}
|
|
16
|
+
export async function findWizardSession(options, api = bootstrapApi, resolveAccount = resolveBootstrapAccount) {
|
|
17
|
+
if (options.sessionId && options.accountUid)
|
|
18
|
+
throw new Error("会话 ID 与 --account-uid 只能选择一个。");
|
|
19
|
+
if (options.sessionId)
|
|
20
|
+
return viewSchema.parse(await api(`/sessions/${options.sessionId}`));
|
|
21
|
+
const accountId = await resolveAccount(undefined, options.accountUid);
|
|
22
|
+
const status = await api(`/accounts/${accountId}/status`);
|
|
23
|
+
const latest = status.latest;
|
|
24
|
+
if (latest) {
|
|
25
|
+
const existing = viewSchema.parse(latest);
|
|
26
|
+
if (status.initialization && existing.state === "CANCELLED")
|
|
27
|
+
return viewSchema.parse(status.initialization);
|
|
28
|
+
if (["PLANNED", "RUNNING", "PAUSED", "COMPLETE", "CHECKED"].includes(existing.state)) {
|
|
29
|
+
if (!["COMPLETE", "CHECKED"].includes(existing.state) && !status.canResume)
|
|
30
|
+
throw new Error("该云账号已有其他管理员发起的初始化;可在云账号管理页面查看进度,请原发起人继续。");
|
|
31
|
+
return existing;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (status.managementConfigured) {
|
|
35
|
+
return viewSchema.parse(await api(`/accounts/${accountId}/maintenance`, { operation: "CHECK" }));
|
|
36
|
+
}
|
|
37
|
+
return viewSchema.parse(await api(`/accounts/${accountId}`, {}));
|
|
38
|
+
}
|
|
39
|
+
/** All recovery decisions use server state. Only the encrypted handoff journal is also kept locally. */
|
|
40
|
+
export async function executeWizardSession(current, options, dependencies = {}) {
|
|
41
|
+
const api = dependencies.api ?? bootstrapApi;
|
|
42
|
+
const id = current.plan.id;
|
|
43
|
+
let view = viewSchema.parse(await api(`/sessions/${id}/start`, {}));
|
|
44
|
+
if (view.state === "COMPLETE")
|
|
45
|
+
return view;
|
|
46
|
+
const executionId = view.execution?.id;
|
|
47
|
+
if (!executionId)
|
|
48
|
+
throw new Error("服务端未提供执行租约,请升级平台后再使用恢复向导。");
|
|
49
|
+
const receiptPath = dependencies.receiptPath ?? join(dirname(appConfigPath()), "cloud-bootstrap", `${id}.json`);
|
|
50
|
+
let heartbeatFailure;
|
|
51
|
+
let heartbeat;
|
|
52
|
+
const timer = setInterval(() => {
|
|
53
|
+
if (!heartbeat) {
|
|
54
|
+
heartbeat = api(`/sessions/${id}/heartbeat`, { executionId }).catch(error => { heartbeatFailure = error; }).finally(() => { heartbeat = undefined; });
|
|
55
|
+
}
|
|
56
|
+
}, 30_000);
|
|
57
|
+
const checkpoint = async (stage, status) => {
|
|
58
|
+
if (heartbeatFailure)
|
|
59
|
+
throw heartbeatFailure;
|
|
60
|
+
view = viewSchema.parse(await api(`/sessions/${id}/progress`, { executionId, stage, status }));
|
|
61
|
+
options.display(stage, status);
|
|
62
|
+
};
|
|
63
|
+
try {
|
|
64
|
+
const localReceipt = await access(receiptPath).then(() => true, () => false);
|
|
65
|
+
if (!view.receiptStored && localReceipt) {
|
|
66
|
+
view = viewSchema.parse(await api(`/sessions/${id}/receipt`, { executionId, ...await readReceipt(receiptPath, id) }));
|
|
67
|
+
}
|
|
68
|
+
if (!view.receiptStored) {
|
|
69
|
+
validateCloudMetadata(view.plan);
|
|
70
|
+
if (view.events.some(event => event.stage === "KEY" && event.status === "STARTED"))
|
|
71
|
+
throw new Error("上次 AK 创建结果尚未确认,服务端和本机均没有加密回执。请核对该 RAM 用户的 AK 或在原执行机器恢复回执;不会再次创建 AK。");
|
|
72
|
+
await checkpoint("LOGIN", "STARTED");
|
|
73
|
+
await (dependencies.oauth ?? withOAuth)(options.binary, async (cli) => {
|
|
74
|
+
await checkpoint("LOGIN", "SUCCEEDED");
|
|
75
|
+
const guardedCall = async (product, action, args) => { if (heartbeatFailure)
|
|
76
|
+
throw heartbeatFailure; return cli.call(product, action, args); };
|
|
77
|
+
await checkpoint("IDENTITY", "STARTED");
|
|
78
|
+
await checkpoint("PREFLIGHT", "STARTED");
|
|
79
|
+
await preflight(view.plan, guardedCall, true);
|
|
80
|
+
await checkpoint("IDENTITY", "SUCCEEDED");
|
|
81
|
+
await checkpoint("PREFLIGHT", "SUCCEEDED");
|
|
82
|
+
if (!await options.approve(view))
|
|
83
|
+
throw new Error("已暂停初始化,服务端进度已保留。再次运行同一 UID 的向导继续。");
|
|
84
|
+
await executePlan(view.plan, guardedCall, checkpoint, async (ciphertext) => {
|
|
85
|
+
// Local fsync is the first handoff; upload follows before another cloud mutation or success event.
|
|
86
|
+
await saveReceipt(receiptPath, id, ciphertext);
|
|
87
|
+
view = viewSchema.parse(await api(`/sessions/${id}/receipt`, { executionId, ciphertext }));
|
|
88
|
+
}, { resume: true });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
options.display("KEY", "SUCCEEDED");
|
|
93
|
+
if (!await options.approve(view))
|
|
94
|
+
throw new Error("已暂停凭据导入,服务端加密回执已保留。");
|
|
95
|
+
}
|
|
96
|
+
await checkpoint("IMPORT", "STARTED");
|
|
97
|
+
const completed = viewSchema.parse(await api(`/sessions/${id}/finish`, { executionId }));
|
|
98
|
+
options.display("IMPORT", "SUCCEEDED");
|
|
99
|
+
return completed;
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
clearInterval(timer);
|
|
103
|
+
if (heartbeat)
|
|
104
|
+
await heartbeat;
|
|
105
|
+
const reasonCode = error instanceof CloudCommandError ? "ALIYUN_" + error.cloudCode
|
|
106
|
+
: error instanceof PlatformBootstrapApiError ? "PLATFORM_HTTP_" + error.status
|
|
107
|
+
: error instanceof Error && error.message.includes("AK 创建结果") ? "KEY_OUTCOME_UNKNOWN"
|
|
108
|
+
: error instanceof Error && error.message.startsWith("已暂停") ? "USER_PAUSED" : "EXECUTION_INTERRUPTED";
|
|
109
|
+
await api(`/sessions/${id}/pause`, { executionId, reasonCode }).catch(() => undefined);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
clearInterval(timer);
|
|
114
|
+
if (heartbeat)
|
|
115
|
+
await heartbeat;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export async function runBootstrapWizard(options, json = false) {
|
|
119
|
+
if (!process.stdin.isTTY)
|
|
120
|
+
throw new Error("初始化向导需要交互式终端。预先审阅可使用 cloud bootstrap plan --account-uid UID。");
|
|
121
|
+
intro("阿里云系统身份初始化", { output: process.stderr });
|
|
122
|
+
if (!options.sessionId && !options.accountUid) {
|
|
123
|
+
const uid = await text({ message: "阿里云主账号 UID", output: process.stderr, validate: value => !/^\d{8,32}$/u.test(value ?? "") ? "请输入 8–32 位数字 UID。" : undefined });
|
|
124
|
+
if (isCancel(uid)) {
|
|
125
|
+
outro("已退出。", { output: process.stderr });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
options = { ...options, accountUid: uid };
|
|
129
|
+
}
|
|
130
|
+
let current = await findWizardSession(options);
|
|
131
|
+
note(`云账号:${current.plan.accountCode} (${current.plan.accountUid})\n系统用户:${current.plan.username}\n管理 Role:${current.plan.managementRoleName}\n会话:${current.plan.id}`, "初始化对象", { output: process.stderr });
|
|
132
|
+
note(progressSummary(current), "服务端保存的进度", { output: process.stderr });
|
|
133
|
+
if (["COMPLETE", "CHECKED"].includes(current.state)) {
|
|
134
|
+
const business = businessStatusSchema.parse(await bootstrapApi(`/accounts/${current.plan.accountId}/business`));
|
|
135
|
+
const maintenanceChoice = await select({ message: "系统身份维护", output: process.stderr, options: [
|
|
136
|
+
{ value: "CHECK", label: "检查云端状态", hint: "只读检查,保存最近检查结果" },
|
|
137
|
+
{ value: "REPAIR", label: "检查并修复系统身份差异", hint: "先展示差异,再确认修复" },
|
|
138
|
+
{ value: "BUSINESS", label: business.configured ? "检查/维护共享业务身份" : "补齐共享业务身份", hint: business.latest?.canResume ? "继续服务端保存的业务身份任务" : "云账号共用,不依赖 OSS Role" },
|
|
139
|
+
{ value: "OSS", label: "初始化/检查默认 OSS Role", hint: "共享业务身份就绪后,预览并确认 OSS 初始化" },
|
|
140
|
+
{ value: "exit", label: "退出" }
|
|
141
|
+
] });
|
|
142
|
+
if (isCancel(maintenanceChoice) || maintenanceChoice === "exit") {
|
|
143
|
+
outro("已退出。", { output: process.stderr });
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (maintenanceChoice === "OSS") {
|
|
147
|
+
await runOssBootstrap(current.plan.accountId, json);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (maintenanceChoice === "BUSINESS") {
|
|
151
|
+
if (await runBusinessBootstrap(current.plan.accountId, json))
|
|
152
|
+
await runOssBootstrap(current.plan.accountId, json);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
current = viewSchema.parse(await bootstrapApi(`/accounts/${current.plan.accountId}/maintenance`, { operation: maintenanceChoice }));
|
|
156
|
+
note(`维护会话:${current.plan.id}\n再次按 UID 运行可继续本次维护。`, "维护任务已保存", { output: process.stderr });
|
|
157
|
+
}
|
|
158
|
+
if (current.state === "CANCELLED") {
|
|
159
|
+
outro("本次初始化已终止。如需新计划,请使用 --account-uid 重新进入向导。", { output: process.stderr });
|
|
160
|
+
if (json)
|
|
161
|
+
process.stdout.write(JSON.stringify({ ok: true, ...current }) + "\n");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
while (true) {
|
|
165
|
+
const choice = await select({ message: current.events.length ? "发现未完成的初始化" : "准备初始化", output: process.stderr, options: [
|
|
166
|
+
{ value: "continue", label: current.events.length ? "从未完成步骤继续" : "开始向导", hint: "核对云端状态,保留已完成资源" },
|
|
167
|
+
{ value: "exit", label: "稍后继续", hint: "保留服务端计划和进度" },
|
|
168
|
+
{ value: "cancel", label: "终止本次初始化", hint: "结束当前计划,不能恢复执行" }
|
|
169
|
+
] });
|
|
170
|
+
if (isCancel(choice) || choice === "exit") {
|
|
171
|
+
outro("进度已保留,再次运行同一 UID 的向导继续。", { output: process.stderr });
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (choice !== "cancel")
|
|
175
|
+
break;
|
|
176
|
+
note(`云账号:${current.plan.accountCode} (${current.plan.accountUid})\n会话:${current.plan.id}\n\n终止后,本次计划无法恢复执行或导入凭据,服务端加密回执及其解密密钥会被清除。已创建的云资源不会自动删除。`, "确认终止影响", { output: process.stderr });
|
|
177
|
+
const answer = await confirm({ message: "确认终止本次初始化?", initialValue: false, output: process.stderr });
|
|
178
|
+
if (isCancel(answer) || !answer)
|
|
179
|
+
continue;
|
|
180
|
+
const cancelled = viewSchema.parse(await bootstrapApi(`/sessions/${current.plan.id}/cancel`, {}));
|
|
181
|
+
if (cancelled.plan.id !== current.plan.id || cancelled.state !== "CANCELLED")
|
|
182
|
+
throw new Error("服务端未确认终止,请查询初始化状态后重试。");
|
|
183
|
+
outro(`本次初始化已终止。如需新计划,请运行:numa cloud bootstrap run --account-uid ${current.plan.accountUid}`, { output: process.stderr });
|
|
184
|
+
if (json)
|
|
185
|
+
process.stdout.write(JSON.stringify({ ok: true, ...cancelled }) + "\n");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (options.confirmAccount && options.confirmAccount !== current.plan.accountUid)
|
|
189
|
+
throw new Error("--confirm-account 与计划 UID 不一致。");
|
|
190
|
+
const localBinary = "./tmp/aliyun-cli-3.5.0/aliyun";
|
|
191
|
+
const binary = options.aliyunBin ?? (await access(localBinary).then(() => localBinary, () => "aliyun"));
|
|
192
|
+
try {
|
|
193
|
+
if (current.maintenance) {
|
|
194
|
+
current = await executeMaintenance(current, { binary,
|
|
195
|
+
display: (stage, status) => process.stderr.write(` ${status === "SUCCEEDED" ? "✓" : "›"} ${stage === "IMPORT" ? (current.maintenance?.operation === "CHECK" ? "保存检查结果" : "验证系统身份") : labels[stage] ?? stage} · ${statuses[status] ?? status}\n`),
|
|
196
|
+
oauthFallback: async () => {
|
|
197
|
+
const answer = await confirm({ message: "使用本地阿里云管理员 OAuth 登录,以完成检查或执行修复?", initialValue: false, output: process.stderr });
|
|
198
|
+
return !isCancel(answer) && answer;
|
|
199
|
+
},
|
|
200
|
+
approve: async (view) => {
|
|
201
|
+
note(view.receiptStored && view.maintenance?.report?.status === "HEALTHY" ? "新凭据的加密回执已保存;验证成功后切换默认管理凭据。" : (view.maintenance?.report?.differences ?? []).map(d => `${d.resource} · ${d.code}\n当前:${d.actual}\n恢复为:${d.expected}`).join("\n\n"), "修复范围", { output: process.stderr });
|
|
202
|
+
const answer = await confirm({ message: view.receiptStored ? "继续验证并导入已保存的新凭据?" : "确认按以上差异修复系统身份?", initialValue: false, output: process.stderr });
|
|
203
|
+
return !isCancel(answer) && answer;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
const report = current.maintenance?.report;
|
|
207
|
+
if (report)
|
|
208
|
+
note(report.differences.length ? report.differences.map(d => `${d.resource} · ${d.code}\n${d.actual} → ${d.expected}`).join("\n\n") : "检查范围内的系统用户、Role、策略、直接绑定及托管 AK 均符合保存的配置。", "最近检查结果", { output: process.stderr });
|
|
209
|
+
outro(current.state === "CHECKED" ? "云端检查完成,结果已保存。" : "系统身份修复及凭据验证完成。", { output: process.stderr });
|
|
210
|
+
if (json)
|
|
211
|
+
process.stdout.write(JSON.stringify({ ok: true, ...current }) + "\n");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
current = await executeWizardSession(current, { binary,
|
|
215
|
+
display: (stage, status) => process.stderr.write(` ${status === "SUCCEEDED" ? "✓" : status === "FAILED" ? "!" : "›"} ${labels[stage] ?? stage} · ${statuses[status] ?? status}\n`),
|
|
216
|
+
approve: async (view) => {
|
|
217
|
+
note(`${view.plan.userComments ?? view.plan.ownershipMarker}\n\n管理权限:\n${JSON.stringify(view.plan.managementPolicy, null, 2)}\n\n完成后切换平台默认管理凭据,业务代理保持不变。`, view.receiptStored ? "恢复凭据验证与导入" : "确认初始化范围", { output: process.stderr });
|
|
218
|
+
if (options.confirmAccount)
|
|
219
|
+
return true;
|
|
220
|
+
const answer = await confirm({ message: view.receiptStored ? "验证已保存的凭据并完成初始化?" : "按以上范围继续初始化?", initialValue: false, output: process.stderr });
|
|
221
|
+
return !isCancel(answer) && answer;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
const businessReady = await runBusinessBootstrap(current.plan.accountId, json);
|
|
225
|
+
const ossReady = businessReady && await runOssBootstrap(current.plan.accountId, json);
|
|
226
|
+
outro(ossReady ? "系统身份、共享业务身份及默认 OSS Role 已就绪。访问策略发布与用户/Client 授权仍需单独配置。" : "系统管理阶段已完成;业务或 OSS 阶段尚未完成,可按相同 UID 继续。", { output: process.stderr });
|
|
227
|
+
if (json)
|
|
228
|
+
process.stdout.write(JSON.stringify({ ok: true, ...current }) + "\n");
|
|
229
|
+
}
|
|
230
|
+
catch (error) {
|
|
231
|
+
if (current.state === "COMPLETE") {
|
|
232
|
+
note(`系统身份已完成。再次按 UID 运行并选择共享业务身份或默认 OSS Role,可继续对应任务。`, "共享业务身份待继续", { output: process.stderr });
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
note(`再次运行:numa cloud bootstrap run --account-uid ${current.plan.accountUid}\n会话:${current.plan.id}\n意外退出后,执行租约最多 3 分钟到期;服务端进度和加密回执会保留。`, "恢复初始化", { output: process.stderr });
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/cloud/wizard.ts"],"names":[],"mappings":"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"}
|