huaweicloud-devkit 1.1.9-next.6 → 1.1.10-next.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 +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/plugins/huaweicloud-core/.claude-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.codex-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.cursor-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.hermes-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/.workbuddy-plugin/plugin.json +1 -1
- package/plugins/huaweicloud-core/openclaw.plugin.json +1 -1
- package/plugins/huaweicloud-core/safety/rules/cloud-risk-rules.json +1 -7
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/create-instance.md +26 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/hc-activity.md +16 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/troubleshooting.md +51 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/windows-ssh.md +24 -0
- package/plugins/huaweicloud-core/skills/huawei-iac/SKILL.md +38 -36
- package/plugins/huaweicloud-core/skills/huawei-iam/SKILL.md +35 -16
- package/plugins/huaweicloud-core/skills/huawei-iam/references/quick-ref.md +35 -0
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +40 -32
- package/plugins/huaweicloud-core/src/account-type.mjs +135 -0
- package/plugins/huaweicloud-core/src/auth/credentials.mjs +0 -43
- package/plugins/huaweicloud-core/src/hcloud-cli.mjs +19 -44
- package/plugins/huaweicloud-core/src/mcp-config-merge.mjs +1 -1
- package/plugins/huaweicloud-core/src/risk-rule-engine.mjs +1 -1
- package/plugins/huaweicloud-core/src/safety-policy.mjs +37 -6
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +281 -47
- package/plugins/huaweicloud-core/src/setup-cli.mjs +4 -62
- package/plugins/huaweicloud-core/src/tools.mjs +55 -5
- package/integrations/opencode/package-lock.json +0 -24
- package/integrations/opencode/package.json +0 -10
- package/integrations/opencode/plugins/huaweicloud-devkit.js +0 -194
- package/plugins/huaweicloud-core/src/auth/token-exchange.mjs +0 -100
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://github.com/huaweicloud/huaweicloud-devkit/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/huaweicloud-devkit)
|
|
7
|
-
[](https://github.com/huaweicloud/huaweicloud-devkit)
|
|
8
8
|
|
|
9
9
|
**[中文](README.zh-CN.md) | English**
|
|
10
10
|
|
package/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://github.com/huaweicloud/huaweicloud-devkit/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/huaweicloud-devkit)
|
|
7
|
-
[](https://github.com/huaweicloud/huaweicloud-devkit)
|
|
8
8
|
|
|
9
9
|
**中文 | [English](README.md)**
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
3
|
"mcpName": "io.github.huaweicloud/huaweicloud-devkit",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.10-next.0",
|
|
5
5
|
"kooCliVersion": "7.3.12",
|
|
6
6
|
"description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
|
|
7
7
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"mcpServers": "./.mcp.json",
|
|
18
18
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
19
19
|
"skills": "./skills/",
|
|
20
|
-
"version": "1.1.
|
|
20
|
+
"version": "1.1.10-next.0",
|
|
21
21
|
"author": {
|
|
22
22
|
"name": "HuaweiCloud Mate",
|
|
23
23
|
"url": "https://github.com/huaweicloud"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"mcpServers": "./.mcp.json",
|
|
21
21
|
"description": "Agent toolkit that helps coding agents use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities safely and accurately.",
|
|
22
22
|
"skills": "./skills/",
|
|
23
|
-
"version": "1.1.
|
|
23
|
+
"version": "1.1.10-next.0",
|
|
24
24
|
"author": {
|
|
25
25
|
"name": "HuaweiCloud Mate",
|
|
26
26
|
"url": "https://github.com/huaweicloud"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"mcpServers": "./.mcp.json",
|
|
18
18
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
19
19
|
"skills": "./skills/",
|
|
20
|
-
"version": "1.1.
|
|
20
|
+
"version": "1.1.10-next.0",
|
|
21
21
|
"author": {
|
|
22
22
|
"name": "HuaweiCloud Mate",
|
|
23
23
|
"url": "https://github.com/huaweicloud"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10-next.0",
|
|
4
4
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HuaweiCloud Mate",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10-next.0",
|
|
4
4
|
"description": "Guide coding agents to use Huawei Cloud Skills, KooCLI, APIs, SDKs, and future MCP capabilities with safer execution and less context.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "HuaweiCloud Mate",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "huaweicloud-devkit",
|
|
3
3
|
"id": "huaweicloud-devkit",
|
|
4
4
|
"displayName": "HuaweiCloud DevKit",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.10-next.0",
|
|
6
6
|
"family": "bundle-plugin",
|
|
7
7
|
"bundleFormat": "codex",
|
|
8
8
|
"description": "Guide coding agents to use Huawei Cloud safely — KooCLI, APIs, SDKs, 28 MCP tools, skills, and safety guardrails.",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"any": [
|
|
92
92
|
{
|
|
93
93
|
"field": "text",
|
|
94
|
-
"regex": "hcloud\\s+STS\\s+(AssumeAgency|
|
|
94
|
+
"regex": "hcloud\\s+STS\\s+(AssumeAgency|GetTemporaryCredential)\\b"
|
|
95
95
|
}
|
|
96
96
|
]
|
|
97
97
|
},
|
|
@@ -429,12 +429,6 @@
|
|
|
429
429
|
"field": "text",
|
|
430
430
|
"regex": "\\bfdisk\\b"
|
|
431
431
|
}
|
|
432
|
-
],
|
|
433
|
-
"none": [
|
|
434
|
-
{
|
|
435
|
-
"field": "text",
|
|
436
|
-
"regex": "\\bhcloud\\b"
|
|
437
|
-
}
|
|
438
432
|
]
|
|
439
433
|
},
|
|
440
434
|
"message": "The sandbox terminal command is destructively dangerous and could destroy the workspace.",
|
|
@@ -34,6 +34,16 @@ hcloud VPC ListVpcs --cli-region=<region>
|
|
|
34
34
|
hcloud VPC ListSubnets --vpc_id=<vpc-id> --cli-region=<region>
|
|
35
35
|
If no VPC/subnet exists: load `huawei-vpc` skill → create VPC → create subnet (with DNS) → create security group → return here.
|
|
36
36
|
|
|
37
|
+
**子网 DNS 前置修复(实测 #935 坑4)**:模板/预置子网的 `dnsList` 可能为空 —— 这会让 cloud-init 域名解析与 yum/dnf 安装**静默失败**(表现为下载/安装卡死且无明确报错,或 `Could not resolve host`)。创建 ECS 前先检查并补充华为云内网 DNS:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
hcloud VPC ShowSubnet --subnet_id=<subnet-id> --cli-region=<region> # 查看 dnsList
|
|
41
|
+
# dnsList 为空(或缺少内网 DNS)时先修复再建实例:
|
|
42
|
+
hcloud VPC UpdateSubnet --subnet_id=<subnet-id> --subnet.dnsList.1=100.125.1.250 --subnet.dnsList.2=100.125.129.250
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`100.125.1.250` / `100.125.129.250` 是华为云内网 DNS(各区域通用)。实例内自救兜底见下方 user_data 模板的「DNS 兜底」注释,但**修复子网 DNS 是唯一能让 cloud-init 首次开机就正常解析的路径**(user_data 只在 first boot 执行,错过即需人工补救)。
|
|
46
|
+
|
|
37
47
|
## 5. Create keypair (recommended over adminPass)
|
|
38
48
|
|
|
39
49
|
**MCP 环境下必须用"本地生成 + 导入"流程**——`NovaCreateKeypair` 返回的 `private_key` 会被 MCP 脱敏管道替换为 `<redacted>`,而私钥仅此一次机会,读不到即作废:
|
|
@@ -129,6 +139,22 @@ hcloud ECS CreateServers ... --server.user_data=$user_data
|
|
|
129
139
|
> 2. Either: SSH into the instance and run the setup commands manually (see `huawei-ecs` → SSH Connection Verification → Running Commands Inside the Instance)
|
|
130
140
|
> 3. Or: Delete the instance and recreate with corrected user_data (fresh boot)
|
|
131
141
|
|
|
142
|
+
### Update site content on an already-running instance (no rebuild)
|
|
143
|
+
|
|
144
|
+
user_data/cloud-init 方式**仅适用于创建时写入** —— 已运行实例更新站点内容不要重建实例,直接上传 + reload:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# 上传新产物(Windows 路径:references/windows-ssh.md §2)
|
|
148
|
+
scp -i <key> ./dist.tar.gz root@<eip>:/root/
|
|
149
|
+
# 或 rsync(增量,仅传变化文件)
|
|
150
|
+
rsync -avz --delete -e "ssh -i <key>" ./dist/ root@<eip>:/var/www/site/
|
|
151
|
+
|
|
152
|
+
# SSH 内解压并热加载 nginx(无需重建实例)
|
|
153
|
+
ssh -i <key> root@<eip> 'tar -xzf /root/dist.tar.gz -C /var/www/site/ && nginx -t && nginx -s reload'
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
要点:`nginx -s reload` 热加载配置与静态内容,连接不断;`nginx -t` 先验证配置再 reload,避免 reload 一个坏配置。Node 应用则重启进程(`pm2 reload` 或 kill + nohup 重启)。
|
|
157
|
+
|
|
132
158
|
## 7. EIP (two methods)
|
|
133
159
|
|
|
134
160
|
### Method A: Inline with CreateServers (Recommended)
|
|
@@ -25,3 +25,19 @@
|
|
|
25
25
|
- Nginx修改后 nginx -t 再 reload
|
|
26
26
|
- 按量付费停机仍计费
|
|
27
27
|
- 删除实例时 --delete_publicip=true --delete_volume=true
|
|
28
|
+
|
|
29
|
+
## 作品提交链接(api_link)校验规则(实测 #935 报告2 问题4/5、报告4 问题3)
|
|
30
|
+
|
|
31
|
+
① 提交路径必须包含 `/hc-activity/` 与 `index.html`,否则服务端返回 400 `OPENSERVICE_PARAM_ERROR 作品链接格式不合法`。
|
|
32
|
+
|
|
33
|
+
② 客户端正则与服务端规则存在不一致(客户端较宽松)—— 提交前以服务端严格规则为准做本地校验,避免提交才被拒:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# 本地预校验(服务端严格规则:路径须含 /hc-activity/ 且指向 index.html)
|
|
37
|
+
case "$LINK" in
|
|
38
|
+
*/hc-activity/*index.html) echo "OK: passes server-side validation" ;;
|
|
39
|
+
*) echo "INVALID: link must contain /hc-activity/ and index.html (server returns OPENSERVICE_PARAM_ERROR)" ;;
|
|
40
|
+
esac
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
③ 返回「**作品链接无效**」时区分语义:可能为服务端尚未探活成功(隧道/站点刚上线,服务端探测未完成),并非格式错误 —— 先确认隧道可达(curl 实测 HTTP 200),然后等 1-2 分钟后重试,不要立即改链接格式。
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
| Cannot SSH | 安全组未开放22端口 或 未绑定EIP | 1) 添加入方向规则 tcp 22。2) `hcloud EIP AssociatePublicips --publicip_id=<id> --publicip.associate_instance_id=<port-id> --publicip.associate_instance_type=PORT` |
|
|
14
14
|
| Flavor unavailable | 区域不支持该规格 | `hcloud ECS ListFlavors --cli-region=<r>` 先查。不硬编码 s6/m6 等规格名 |
|
|
15
15
|
| Insufficient resources | AZ 库存不足 | 换规格、换 AZ、或等待资源释放 |
|
|
16
|
+
| `Ecs.0019` flavor 已下线 | 规格已下架 | `hcloud ECS ListFlavors --cli-region=<r>` 查当前在售规格并切换替代规格(状态字段规则见 `references/flavors.md`) |
|
|
17
|
+
| `Ecs.0319` 可用区容量不足 | 目标 AZ 库存售罄 | 更换可用区或更换规格后重试 |
|
|
18
|
+
| `Ecs.0067` 余额受限 | 现金余额不足/历史欠费 | 查 BSS 现金余额并充值(`hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1`);代金券不参与按量付费下单风控,历史欠费需先结清 |
|
|
19
|
+
| `KPS.9004` 密钥对创建受限 | 现金余额不足/历史欠费 | 同上:查 BSS 现金余额并充值 + 历史欠费结清后重试 `hcloud ECS NovaCreateKeypair` |
|
|
16
20
|
| AuthFailure | AK/SK 过期或无效 | `npx huaweicloud-devkit auth init` 重新配置统一凭据 |
|
|
17
21
|
|
|
18
22
|
## 创建失败诊断流程
|
|
@@ -36,6 +40,35 @@ hcloud IMS ListImages --cli-region=<r> --__imagetype=gold --__isregistered=true
|
|
|
36
40
|
# 不支持的参数不要传,用 client-side 过滤
|
|
37
41
|
```
|
|
38
42
|
|
|
43
|
+
## EulerOS 3.0 firewalld:安全组放行后仍不可达(实测 #935 报告4 问题2)
|
|
44
|
+
|
|
45
|
+
EulerOS 3.0 镜像内置 firewalld 且**默认拒绝 SSH 入站** —— 安全组已放行 22 端口后 SSH 仍超时,是实例内防火墙在拦截,不是安全组问题。修复:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 镜像内放行 SSH(SSH 可用时)
|
|
49
|
+
firewall-cmd --permanent --add-service=ssh && firewall-cmd --reload
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
或改用 cloud-init user_data 自动部署(创建时写入,无需 SSH):
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# user_data(base64 后传 CreateServers)
|
|
56
|
+
#cloud-config
|
|
57
|
+
runcmd:
|
|
58
|
+
- firewall-cmd --permanent --add-service=ssh
|
|
59
|
+
- firewall-cmd --reload
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## SSH 失败自动诊断流程(实测 #935 报告3 问题5)
|
|
63
|
+
|
|
64
|
+
SSH 超时时按序排查,先比对**本机真实直连出口 IP** 与安全组 22 端口规则的源 IP 是否一致:
|
|
65
|
+
|
|
66
|
+
1. 查本机**真实直连出口**:Windows 用 `Invoke-RestMethod -Uri "https://api.ipify.org" -NoProxy`(配置了代理时,不带 `-NoProxy` 的 `api.ipify` 返回的是代理出口,不是真实直连出口 —— 详见 `references/windows-ssh.md` §0.1);Linux 用 `curl --noproxy '*' https://api.ipify.org`
|
|
67
|
+
2. 查安全组 22 端口规则的源 IP:`hcloud VPC ListSecurityGroupRules --security_group_id=<sg-id> --cli-region=<r>`
|
|
68
|
+
3. 两者不一致 → 更新规则源 IP 为真实直连出口的 `/32` 精确规则
|
|
69
|
+
4. 一致仍超时 → 查 EIP 绑定(`hcloud EIP ListPublicips`)→ 再查实例内防火墙(上方 EulerOS firewalld 小节)
|
|
70
|
+
5. 全部正常才考虑重装/重建
|
|
71
|
+
|
|
39
72
|
## 密钥对 vs 密码
|
|
40
73
|
|
|
41
74
|
| 方式 | 安全 | 建议 |
|
|
@@ -50,3 +83,21 @@ hcloud IMS ListImages --cli-region=<r> --__imagetype=gold --__isregistered=true
|
|
|
50
83
|
- `--delete_publicip` 默认 false — EIP 不随实例删除,继续计费
|
|
51
84
|
- `--delete_volume` 默认 false — 系统盘不随实例删除
|
|
52
85
|
- 数据盘默认随实例删除(与系统盘行为相反)
|
|
86
|
+
|
|
87
|
+
## 删除完成验证:轮询操作纠正(实测 #935 坑8)
|
|
88
|
+
|
|
89
|
+
`NovaShowJob` 操作**不存在**(KooCLI 与 ECS API 均无此操作,删除轮询用它必然报错)。删除 ECS 后的正确验证方式:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# 删除 ECS(异步任务)
|
|
93
|
+
hcloud ECS DeleteServers --servers.1.id=<instance-id> --delete_publicip=true --delete_volume=true
|
|
94
|
+
|
|
95
|
+
# 轮询直至目标实例状态为 DELETED(或列表查询 404)
|
|
96
|
+
for i in 1 2 3 4 5 6; do
|
|
97
|
+
hcloud ECS ListServersDetails --cli-region=<r> --limit=50 | grep -q "<instance-id>" || { echo "DELETED (not in list)"; break; }
|
|
98
|
+
hcloud ECS ListServersDetails --cli-region=<r> --id=<instance-id> | grep -q '"DELETED"' && { echo "DELETED"; break; }
|
|
99
|
+
echo "still deleting..."; sleep 10
|
|
100
|
+
done
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
列表查询返回 404 或实例不在列表中,同样视为删除完成。
|
|
@@ -19,6 +19,30 @@ done
|
|
|
19
19
|
|
|
20
20
|
Only after all retries fail, treat it as a network problem (security group port 22 ingress, EIP binding).
|
|
21
21
|
|
|
22
|
+
## 0.1 代理出口 IP 陷阱:`api.ipify` 返回的不是真实直连出口(实测 #935 坑6)
|
|
23
|
+
|
|
24
|
+
本机配置了 HTTP/HTTPS 代理时,`api.ipify`、`ifconfig.me` 等检测服务返回的是**代理出口 IP** 而非真实直连出口 —— 安全组按这个错误 IP 放通 22 端口后 SSH 仍然超时(连接根本不走代理)。
|
|
25
|
+
|
|
26
|
+
Windows 检测**真实直连出口**必须绕过代理:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
# 真实直连出口(-NoProxy 绕过本机代理,实测确认)
|
|
30
|
+
Invoke-RestMethod -Uri "https://api.ipify.org" -NoProxy
|
|
31
|
+
# 对照(会返回代理出口,仅用于确认差异):
|
|
32
|
+
Invoke-RestMethod -Uri "https://api.ipify.org"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
放通规则用真实直连出口的 `/32` 精确规则(不要放通 `0.0.0.0/0`,风险规则也会拦截):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
hcloud VPC CreateSecurityGroupRule --security_group_rule.security_group_id=<sg-id> \
|
|
39
|
+
--security_group_rule.direction=ingress --security_group_rule.port_range_min=22 \
|
|
40
|
+
--security_group_rule.port_range_max=22 --security_group_rule.protocol=tcp \
|
|
41
|
+
--security_group_rule.remote_ip_prefix=<真实直连出口IP>/32
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
SSH 超时时的完整诊断流程见下方 §5。
|
|
45
|
+
|
|
22
46
|
## 1. Login from Windows
|
|
23
47
|
|
|
24
48
|
```powershell
|
|
@@ -21,16 +21,16 @@ Always run `hcloud <Service> <Operation> --help` before constructing commands to
|
|
|
21
21
|
|
|
22
22
|
**Proactive by design**: any deployment intent ("部署一个博客", "搭一套环境", "买个服务器") automatically triggers stages 1-5 BEFORE anything is created. The user NEVER needs to ask for an architecture proposal, cost estimate, or risk warnings - they are built into the flow. Only stages 6-8 (create / verify / manage) wait for explicit user confirmation at the approval gates.
|
|
23
23
|
|
|
24
|
-
| Stage | What happens | Hard rule
|
|
25
|
-
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
-
| 1. Scale assessment | **FIRST inspect the project code** (clone remote repos to a temp dir, or read the local path): tech stack, data services (Redis/MySQL/SQLite...), build artifacts, existing Dockerfile/k8s manifests → then classify or ask scale | **NEVER present deployment options (sandbox/ECS/OBS...) before the codebase has been inspected** - options without code analysis are guesses. If scale is not stated or clearly inferable, ASK - present the 3 tiers as options with what each includes and its monthly cost band (see `references/architectures.md`), and let the user choose. Never assume a tier. The scale question and the hosting-target question are SEPARATE questions on separate axes. FunctionGraph filesystem is ephemeral - never recommend SQLite/local files for persistent data
|
|
27
|
-
| 2. Frontend hosting choice | Present BOTH options: (a) OBS+CDN+DNS custom domain, (b) ECS+EIP | For SPA/static frontends (Vue/React dist), **OBS hosting must always appear as an option** with cost comparison against same-host Nginx - do not silently merge the frontend into a compute node. For option (a) three prerequisites: domain ownership verification (CDN requires a DNS record or file upload first - `CDN.00010185` otherwise), ICP filing check, DNS hosting check; domain registration link: https://www.huaweicloud.com/product/domain.html
|
|
28
|
-
| 3. Architecture proposal | ASCII topology tree with dependencies | User confirms before continuing. **Architecture decision points must be surfaced as explicit choices, never silently made**: (a) app depends on Redis/MySQL/Kafka etc. → managed service (DCS/RDS/DMS, billed) vs same-host install (cheap, ops burden) - state the trade-off and ask; (b) repo ships a Dockerfile / SWR image / k8s manifests → offer container path (Docker on ECS or CCE) alongside source-build path; (c) frontend hosting layer (Nginx same-host vs OBS+CDN). Silent defaults here are a correctness failure
|
|
29
|
-
| 4. Parameter discovery | `ListFlavors` / `ListImages` / `huaweicloud_list_regions` | Never hardcode flavor/image names
|
|
30
|
-
| 5. Cost + balance gate | Price every resource via BSS `ListOnDemandResourceRatings`, then query balance | **前置拦截(实测 #922):估算成本 > 余额(含余额为 0)时 STOP — 不要带着一份注定失败的下单继续 stage 6**。第一条消息必须说明:"您的余额不足以覆盖本次部署的按时长计费资源(预计首月 <估算>,当前余额 <余额>),下单将失败(Ecs.7000 Insufficient account balance)——已暂停,请先充值或领券,完成后回复"已充值/继续"即可从本阶段续跑原配置"。充值入口:https://account.huaweicloud.com/usercenter/?region=cn-north-4#/userindex/balanceRecharge 。Remedy priority: (1) FIRST claim the one-time incentive voucher (huaweicloud_voucher_status → huaweicloud_voucher_claim) to offset usage fees; (2) then instruct the user to top up balance (via the link above) — pause the flow and resume from stage 5 with the SAME configuration after the top-up, never walk a known-doomed order; (3) free-tier resources (FunctionGraph, small OBS) proceed without any balance. Balance >= 估算成本 → report how long it can sustain (balance ÷ monthly estimate). **权限降级(实测)**:IAM 用户无 `billing:balance:view` 时余额查询报 `CBC.0151` → 不阻塞流程,明确告知"余额无法程序化查询,请自行核对;若下单报 Ecs.7000 即余额不足",领券后继续。定价编码逐服务查证,见 `references/resource-catalog.md` § Pricing |
|
|
31
|
-
| 6. Provision | deployment_id, session state, batch approval, ordered creation | See "Provisioning Rules" below
|
|
32
|
-
| 7. Verify | `curl -I` the site / API; expect 200 | DNS CNAME may take minutes to propagate - not an error
|
|
33
|
-
| 8. Manage | Session-scoped status query and destroy | See "Destroy Rules" below
|
|
24
|
+
| Stage | What happens | Hard rule |
|
|
25
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| 1. Scale assessment | **FIRST inspect the project code** (clone remote repos to a temp dir, or read the local path): tech stack, data services (Redis/MySQL/SQLite...), build artifacts, existing Dockerfile/k8s manifests → then classify or ask scale | **NEVER present deployment options (sandbox/ECS/OBS...) before the codebase has been inspected** - options without code analysis are guesses. If scale is not stated or clearly inferable, ASK - present the 3 tiers as options with what each includes and its monthly cost band (see `references/architectures.md`), and let the user choose. Never assume a tier. The scale question and the hosting-target question are SEPARATE questions on separate axes. FunctionGraph filesystem is ephemeral - never recommend SQLite/local files for persistent data |
|
|
27
|
+
| 2. Frontend hosting choice | Present BOTH options: (a) OBS+CDN+DNS custom domain, (b) ECS+EIP | For SPA/static frontends (Vue/React dist), **OBS hosting must always appear as an option** with cost comparison against same-host Nginx - do not silently merge the frontend into a compute node. For option (a) three prerequisites: domain ownership verification (CDN requires a DNS record or file upload first - `CDN.00010185` otherwise), ICP filing check, DNS hosting check; domain registration link: https://www.huaweicloud.com/product/domain.html |
|
|
28
|
+
| 3. Architecture proposal | ASCII topology tree with dependencies | User confirms before continuing. **Architecture decision points must be surfaced as explicit choices, never silently made**: (a) app depends on Redis/MySQL/Kafka etc. → managed service (DCS/RDS/DMS, billed) vs same-host install (cheap, ops burden) - state the trade-off and ask; (b) repo ships a Dockerfile / SWR image / k8s manifests → offer container path (Docker on ECS or CCE) alongside source-build path; (c) frontend hosting layer (Nginx same-host vs OBS+CDN). Silent defaults here are a correctness failure |
|
|
29
|
+
| 4. Parameter discovery | `ListFlavors` / `ListImages` / `huaweicloud_list_regions` | Never hardcode flavor/image names |
|
|
30
|
+
| 5. Cost + balance gate | Price every resource via BSS `ListOnDemandResourceRatings`, then query balance | **前置拦截(实测 #922):估算成本 > 余额(含余额为 0)时 STOP — 不要带着一份注定失败的下单继续 stage 6**。第一条消息必须说明:"您的余额不足以覆盖本次部署的按时长计费资源(预计首月 <估算>,当前余额 <余额>),下单将失败(Ecs.7000 Insufficient account balance)——已暂停,请先充值或领券,完成后回复"已充值/继续"即可从本阶段续跑原配置"。充值入口:https://account.huaweicloud.com/usercenter/?region=cn-north-4#/userindex/balanceRecharge 。Remedy priority: (1) FIRST claim the one-time incentive voucher (huaweicloud_voucher_status → huaweicloud_voucher_claim) to offset usage fees; (2) then instruct the user to top up balance (via the link above) — pause the flow and resume from stage 5 with the SAME configuration after the top-up, never walk a known-doomed order; (3) free-tier resources (FunctionGraph, small OBS) proceed without any balance. Balance >= 估算成本 → report how long it can sustain (balance ÷ monthly estimate). **权限降级(实测)**:IAM 用户无 `billing:balance:view` 时余额查询报 `CBC.0151` → 不阻塞流程,明确告知"余额无法程序化查询,请自行核对;若下单报 Ecs.7000 即余额不足",领券后继续。定价编码逐服务查证,见 `references/resource-catalog.md` § Pricing。**余额风控语义(实测 #935)**:按量付费下单校验的是**现金余额**而非代金券(券只在账单结算时抵扣,不参与下单风控);历史欠费(即使金额很小)同样触发 `KPS.9004`/`Ecs.0067` 拒单 —— 门禁检查项必须包含:现金余额充足 且 欠费已结清(查询:`hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1`)。**子网 DNS 前置修复(实测 #935 坑4)**:模板/预置子网 `dnsList` 可能为空,会导致 cloud-init 域名解析与 yum/dnf 静默失败 —— 创建 ECS 前先执行 `hcloud VPC UpdateSubnet` 补充华为云内网 DNS `100.125.1.250`、`100.125.129.250`:`hcloud VPC UpdateSubnet --subnet_id=<subnet-id> --subnet.dnsList.1=100.125.1.250 --subnet.dnsList.2=100.125.129.250` |
|
|
31
|
+
| 6. Provision | deployment_id, session state, batch approval, ordered creation | See "Provisioning Rules" below |
|
|
32
|
+
| 7. Verify | `curl -I` the site / API; expect 200 | DNS CNAME may take minutes to propagate - not an error |
|
|
33
|
+
| 8. Manage | Session-scoped status query and destroy | See "Destroy Rules" below |
|
|
34
34
|
|
|
35
35
|
## Provisioning Rules (Stage 6)
|
|
36
36
|
|
|
@@ -52,32 +52,34 @@ Execution: show the to-be-deleted list for final confirmation → delete in **re
|
|
|
52
52
|
|
|
53
53
|
## Critical Warnings
|
|
54
54
|
|
|
55
|
-
| Trap
|
|
56
|
-
|
|
|
57
|
-
| Stale `securityToken` poisons every hcloud call
|
|
58
|
-
| OBS writes bypass the REST write-prefix policy
|
|
59
|
-
| `OBS mb` flag rules differ from cp/rm
|
|
60
|
-
| Duplicate `OBS mb` is idempotent success
|
|
61
|
-
| Bucket ACL does not cascade to objects
|
|
62
|
-
| OBS static website bucket name must equal the domain
|
|
63
|
-
| VPC v3 API differs from older docs
|
|
64
|
-
| Public exposure is auto-blocked
|
|
65
|
-
| ECS CreateServers hidden required params
|
|
66
|
-
| FunctionGraph runtime/code enums are strict
|
|
67
|
-
| Keypairs: `NovaCreateKeypair`, not CreateKeypair
|
|
68
|
-
| Long inline args break MCP JSON
|
|
69
|
-
| EIP quota fails at RUN stage, not at plan
|
|
70
|
-
| Zero balance blocks order submission
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
| EIP
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
55
|
+
| Trap | Why / Rule |
|
|
56
|
+
| --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
57
|
+
| Stale `securityToken` poisons every hcloud call | Symptom: every API returns `APIGW.0301 Incorrect IAM authentication information` while OBS/obsutil still works. `configure set` refuses empty values and auth-sync never clears the field. Fix: `hcloud configure delete --cli-profile=default`, then re-run auth init with AK/SK only (no token) |
|
|
58
|
+
| OBS writes bypass the REST write-prefix policy | `mb` / `cp` / `rm` / `chattri` are obsutil-style commands. ALWAYS route them through `huaweicloud_plan_cli_command` → approval → `huaweicloud_run_approved_command`. Never treat them as read-only |
|
|
59
|
+
| `OBS mb` flag rules differ from cp/rm | `mb` does NOT accept `-f` (flag parse error) and REQUIRES explicit `-location=<region>` even with a regional endpoint (else `IllegalLocationConstraintException`) |
|
|
60
|
+
| Duplicate `OBS mb` is idempotent success | Same-account same-name bucket creation returns success, not an error - never treat a second create as failure. OBS deletes are also idempotent (deleting a nonexistent object succeeds) |
|
|
61
|
+
| Bucket ACL does not cascade to objects | Every uploaded object needs `-acl=public-read` at upload time (`-f` IS valid on cp/rm) |
|
|
62
|
+
| OBS static website bucket name must equal the domain | e.g. bucket `www.example.com` for domain `www.example.com` |
|
|
63
|
+
| VPC v3 API differs from older docs | v3 `CreateSecurityGroup` has NO `vpc_id` (account-scoped); `CreateSecurityGroupRule` uses `multiport=80` not `port_range_min/max`; `DeleteSubnet` requires `vpc_id` too. Always `--help` first |
|
|
64
|
+
| Public exposure is auto-blocked | Risk rules deny `0.0.0.0/0` port rules at plan time. For test/dev use a narrower `remote_ip_prefix` (e.g. the VPC CIDR) or get user consent for a documented exception |
|
|
65
|
+
| ECS CreateServers hidden required params | Besides flavor/image/nics/az it also needs `--server.vpcid` and `--server.root_volume.volumetype` - order submission fails without them |
|
|
66
|
+
| FunctionGraph runtime/code enums are strict | runtime must be exact (`Node.js18.15`, `Python3.9`, `Go1.x`, ...); inline code is the PAIR `--package=default --code_type=inline` (`--package=inline` → `FSS.1006`); TIMER triggers use `--event_data.schedule_type=Rate --event_data.schedule=1m` (`@every` style → `FSS.1109`); DeleteFunction takes `--function_urn` WITHOUT `:latest` |
|
|
67
|
+
| Keypairs: `NovaCreateKeypair`, not CreateKeypair | `ECS CreateKeypair` does NOT exist - use `hcloud ECS NovaCreateKeypair`; delete takes `--keypair_name` (not `--keypair.name`). The API-generated `private_key` is MASKED in tool output - for SSH access create the keypair in the console or import the user's own public key, then bind with `--server.key_name=<n>` |
|
|
68
|
+
| Long inline args break MCP JSON | Values >~2KB inline (e.g. `--server.user_data=<base64 cloud-init>`) fail JSON parsing silently. Write a local JSON file and pass `--cli-jsonInput=<file>` (see `references/resource-catalog.md` header note) |
|
|
69
|
+
| EIP quota fails at RUN stage, not at plan | `EIP.7905 Quota exceeded` appears only after plan+approval - pre-check quota during stage 5 (and count precisely: `ListPublicips --limit=50` truncates, a "50/50" read on a 59-EIP account is wrong). Released quotas may lag minutes before `EIP.7905` clears |
|
|
70
|
+
| Zero balance blocks order submission | ECS creation fails with `Ecs.7000 Insufficient account balance` when cash + voucher accounts are 0. This is the stage-5 gate materialized — and since #922 the gate INTERCEPTS before the order: when the estimate exceeds the balance, STOP at stage 5 (recharge entry + resume after top-up) instead of walking a known-doomed `CreateServers`. Free-tier resources (FunctionGraph, small OBS) DO work at 0 balance - the gate applies to order-submission resources only |
|
|
71
|
+
| Pay-per-use orders check CASH balance, not vouchers (#935) | 按量付费下单风控只校验**现金余额**:代金券不参与按量付费下单风控(券只在账单结算时抵扣);历史欠费(即使金额很小)同样触发 `KPS.9004`/`Ecs.0067` 拒单。stage-5 门禁检查项必须包含:现金余额充足 且 欠费已结清(`hcloud BSS ShowCustomerAccountBalances --cli-region=cn-north-1`) |
|
|
72
|
+
| Subnet `dnsList` may be empty on template/preset subnets (#935) | cloud-init 域名解析与 yum/dnf 静默失败。创建 ECS 前先 `hcloud VPC UpdateSubnet --subnet_id=<id> --subnet.dnsList.1=100.125.1.250 --subnet.dnsList.2=100.125.129.250` 补充华为云内网 DNS(详见 `huawei-ecs/references/create-instance.md` §4) |
|
|
73
|
+
| CDN mainland acceleration requires ICP filing | Unregistered domains cannot go live on CDN - check before stage 3. CDN create ALSO requires domain ownership verification first (`CDN.00010185 Verify domain ownership failed` - user must add a DNS record or upload a verification file) |
|
|
74
|
+
| CDN is a global service in KooCLI | CDN operations only accept `--cli-region=cn-north-1` or `ap-southeast-1` - never the resource region |
|
|
75
|
+
| OBS static website hosting has NO CLI path | `chattri` only sets ACL/storage-class; obsutil has no website command. Options: console setup, or CDN OBS-origin with `--domain.sources.1.enable_obs_web_hosting=1`. Without website hosting, verify via direct object URLs (still public HTTP 200) |
|
|
76
|
+
| DNS hosting location | `hcloud DNS ListPublicZones` decides: hosted in Huawei Cloud → auto-create CNAME record set; hosted elsewhere → output the CNAME value for manual setup at the user's DNS provider |
|
|
77
|
+
| EIP bills when idle; stopped ECS still bills | Include in cost estimate; destroy unattached EIPs |
|
|
78
|
+
| ECS delete defaults leak resources | `--delete_publicip` and `--delete_volume` are false by default - set `true` when tearing down |
|
|
79
|
+
| EIP binding type is non-obvious | `--publicip.associate_instance_type=PORT` (not INSTANCE) |
|
|
80
|
+
| State is session-only | Temp-dir file, dies with the session. Never promise cross-session deploy management |
|
|
81
|
+
| State file must be UTF-8 WITHOUT BOM | PowerShell `Set-Content -Encoding utf8` adds a BOM that breaks JSON parsers - write state with Node or another BOM-less writer |
|
|
82
|
+
| HTTPS needs a certificate | CDN serves plain HTTP by default; SSL cert (upload or SCM) required for HTTPS |
|
|
81
83
|
|
|
82
84
|
## MCP Tools
|
|
83
85
|
|
|
@@ -16,14 +16,15 @@ Domain expertise for Huawei Cloud Identity and Access Management (IAM). Covers u
|
|
|
16
16
|
|
|
17
17
|
## Critical Warnings
|
|
18
18
|
|
|
19
|
-
| Trap
|
|
20
|
-
|
|
|
21
|
-
| NEVER create IAM users for humans
|
|
22
|
-
| NEVER create long-term AK/SK
|
|
23
|
-
| Wildcard policies dangerous
|
|
24
|
-
| Agency trust is powerful
|
|
25
|
-
| Root account must have MFA
|
|
26
|
-
| `缺少必填参数 cli-domain-id` = invalid creds
|
|
19
|
+
| Trap | Why |
|
|
20
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
+
| NEVER create IAM users for humans | Use OneAccess (IAM Identity Center) or federated SSO |
|
|
22
|
+
| NEVER create long-term AK/SK | Use temporary STS tokens via agencies |
|
|
23
|
+
| Wildcard policies dangerous | Effect:Allow + Resource:* = full access. Always scope resources |
|
|
24
|
+
| Agency trust is powerful | Agencies let services assume roles. Always add conditions |
|
|
25
|
+
| Root account must have MFA | Root AK/SK is all-powerful. Enable MFA immediately |
|
|
26
|
+
| `缺少必填参数 cli-domain-id` = invalid creds | KooCLI's account-id lookup failed (APIGW.0301). Re-run `auth init`. Domain-level params (`--domain_id`, `--agency.domain_id`) are separate — get the account-id via `hcloud STS GetCallerIdentity --cli-region=<region>` when needed |
|
|
27
|
+
| Primary-account check = `username == domainName` | Use `huaweicloud_check_account_type` (one call). NOT `ShowDomainPasswordPolicy` (permission-gated, sub-users can succeed) and NOT `principal_id == account_id` (false for primary accounts too). Full procedure: references/quick-ref.md |
|
|
27
28
|
|
|
28
29
|
## Policy Structure
|
|
29
30
|
|
|
@@ -43,14 +44,15 @@ Domain expertise for Huawei Cloud Identity and Access Management (IAM). Covers u
|
|
|
43
44
|
|
|
44
45
|
## Common Workflows
|
|
45
46
|
|
|
46
|
-
| Task
|
|
47
|
-
|
|
|
48
|
-
| List users
|
|
49
|
-
| Create group
|
|
50
|
-
| Create custom policy
|
|
51
|
-
| Create agency
|
|
52
|
-
| Get temporary credential
|
|
53
|
-
|
|
|
47
|
+
| Task | Command | Steps |
|
|
48
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
|
49
|
+
| List users | hcloud IAM KeystoneListUsers --cli-region=<r> | references/quick-ref.md |
|
|
50
|
+
| Create group | hcloud IAM CreateGroupV5 --group_name=<name> | references/quick-ref.md |
|
|
51
|
+
| Create custom policy | hcloud IAM CreateCloudServiceCustomPolicy --role.display_name=<n> --role.type=<type> --role.policy.Statement.1.Effect=Allow | references/policy-examples.md |
|
|
52
|
+
| Create agency | hcloud IAM CreateAgency --agency.name=<n> --agency.domain_id=<id> --agency.trust_domain_name=<domain> | references/quick-ref.md |
|
|
53
|
+
| Get temporary credential | hcloud STS AssumeAgency --agency_urn=<urn> --agency_session_name=<n> --duration_seconds=3600 | references/quick-ref.md |
|
|
54
|
+
| Check primary vs sub-account | huaweicloud_check_account_type (or 2-call CLI fallback) | references/quick-ref.md |
|
|
55
|
+
| Attach policy to group | hcloud IAM AttachGroupPolicyV5 --group_id=<id> --policy_id=<id> | references/quick-ref.md |
|
|
54
56
|
|
|
55
57
|
## Policy Examples (Least Privilege)
|
|
56
58
|
|
|
@@ -83,6 +85,22 @@ Domain expertise for Huawei Cloud Identity and Access Management (IAM). Covers u
|
|
|
83
85
|
|
|
84
86
|
Agencies allow one service to act on behalf of another. Common use cases:
|
|
85
87
|
|
|
88
|
+
### STS 自委托需预创建(实测 #935 报告4 问题6)
|
|
89
|
+
|
|
90
|
+
生成 STS 临时凭证时报**委托不存在**时(如 `agency SELF_VERIFY not found`),需先预创建名为 `SELF_VERIFY` 的 IAM 自委托(agency)—— 活动/新环境默认**不预置**该委托:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# 1. 预创建自委托(信任本账号自身)
|
|
94
|
+
hcloud IAM CreateAgency --agency.name=SELF_VERIFY --agency.trust_domain_name=<本账号domain_name>
|
|
95
|
+
|
|
96
|
+
# 2. 授予基础权限(按需最小化)
|
|
97
|
+
hcloud IAM AssociateAgencyWithDomainPermission --agency_id=<agency-id> --role_id=<role-id>
|
|
98
|
+
|
|
99
|
+
# 3. 之后重试生成 STS 临时凭证
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
排查顺序:先 `hcloud IAM ListAgencies` 确认 `SELF_VERIFY` 是否存在,不存在再按上面步骤预创建,创建后重试 STS 调用。
|
|
103
|
+
|
|
86
104
|
### FunctionGraph Agency (VPC Access)
|
|
87
105
|
|
|
88
106
|
FunctionGraph needs an agency to access VPC resources (RDS, DCS, etc.):
|
|
@@ -104,6 +122,7 @@ Common roles for FunctionGraph: VPC Administrator, RDS Administrator, DCS Admini
|
|
|
104
122
|
|
|
105
123
|
- huaweicloud_list_operations service=IAM
|
|
106
124
|
- huaweicloud_run_readonly_command for user/policy discovery
|
|
125
|
+
- huaweicloud_check_account_type for primary/sub-account judgment
|
|
107
126
|
|
|
108
127
|
## References
|
|
109
128
|
|