huaweicloud-devkit 1.0.2-next.6 → 1.0.2-next.8
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/.agents/plugins/marketplace.json +18 -18
- package/LICENSE +201 -201
- package/README.md +16 -1
- package/README.zh-CN.md +16 -1
- package/bin/setup.cjs +5 -3
- package/integrations/opencode/opencode.json +1 -4
- package/package.json +15 -3
- package/plugins/huaweicloud-core/.claude-plugin/plugin.json +3 -16
- package/plugins/huaweicloud-core/.codex-plugin/plugin.json +3 -16
- package/plugins/huaweicloud-core/.cursor-plugin/plugin.json +3 -16
- package/plugins/huaweicloud-core/.mcp.json +1 -3
- package/plugins/huaweicloud-core/.workbuddy-plugin/plugin.json +3 -16
- package/plugins/huaweicloud-core/hooks/huaweicloud-safety.py +136 -136
- package/plugins/huaweicloud-core/safety/policy.json +75 -100
- package/plugins/huaweicloud-core/safety/rules/cloud-risk-rules.json +41 -13
- package/plugins/huaweicloud-core/skills/huawei-apig/SKILL.md +34 -34
- package/plugins/huaweicloud-core/skills/huawei-billing/SKILL.md +18 -18
- package/plugins/huaweicloud-core/skills/huawei-cbr/SKILL.md +19 -19
- package/plugins/huaweicloud-core/skills/huawei-cce/SKILL.md +32 -32
- package/plugins/huaweicloud-core/skills/huawei-cloud-eye/SKILL.md +30 -30
- package/plugins/huaweicloud-core/skills/huawei-cloud-find-skills/SKILL.md +12 -11
- package/plugins/huaweicloud-core/skills/huawei-cloud-find-skills/scripts/search-skills.mjs +64 -17
- package/plugins/huaweicloud-core/skills/huawei-cts/SKILL.md +20 -20
- package/plugins/huaweicloud-core/skills/huawei-dds-dcs/SKILL.md +31 -31
- package/plugins/huaweicloud-core/skills/huawei-deployment/SKILL.md +20 -20
- package/plugins/huaweicloud-core/skills/huawei-dew/SKILL.md +39 -30
- package/plugins/huaweicloud-core/skills/huawei-dew/references/csms-usage.md +8 -1
- package/plugins/huaweicloud-core/skills/huawei-dew/references/kms-usage.md +6 -0
- package/plugins/huaweicloud-core/skills/huawei-ecs/SKILL.md +39 -36
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/create-instance.md +15 -4
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/flavors.md +11 -9
- package/plugins/huaweicloud-core/skills/huawei-ecs/references/troubleshooting.md +13 -13
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/SKILL.md +40 -39
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/apig-event-format.md +12 -10
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/create-function.md +21 -20
- package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/triggers.md +19 -19
- package/plugins/huaweicloud-core/skills/huawei-gaussdb/SKILL.md +20 -20
- package/plugins/huaweicloud-core/skills/huawei-getting-started/SKILL.md +27 -23
- package/plugins/huaweicloud-core/skills/huawei-iam/SKILL.md +27 -27
- package/plugins/huaweicloud-core/skills/huawei-iam/references/policy-examples.md +65 -39
- package/plugins/huaweicloud-core/skills/huawei-iam/references/quick-ref.md +9 -9
- package/plugins/huaweicloud-core/skills/huawei-modelarts/SKILL.md +25 -25
- package/plugins/huaweicloud-core/skills/huawei-obs/SKILL.md +44 -44
- package/plugins/huaweicloud-core/skills/huawei-obs/references/bucket-create.md +19 -19
- package/plugins/huaweicloud-core/skills/huawei-obs/references/bucket-lifecycle.md +12 -7
- package/plugins/huaweicloud-core/skills/huawei-obs/references/common-pitfalls.md +13 -12
- package/plugins/huaweicloud-core/skills/huawei-obs/references/single-file-share.md +4 -4
- package/plugins/huaweicloud-core/skills/huawei-rds/SKILL.md +63 -58
- package/plugins/huaweicloud-core/skills/huawei-sandbox/SKILL.md +39 -39
- package/plugins/huaweicloud-core/skills/huawei-smn-dms/SKILL.md +26 -26
- package/plugins/huaweicloud-core/skills/huawei-vpc/SKILL.md +39 -39
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/network.md +13 -12
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/security-group.md +20 -19
- package/plugins/huaweicloud-core/skills/huawei-vpc/references/subnet.md +15 -15
- package/plugins/huaweicloud-core/skills/huawei-waf-aad/SKILL.md +18 -18
- package/plugins/huaweicloud-core/skills/huaweicloud-api-and-sdk/SKILL.md +13 -13
- package/plugins/huaweicloud-core/skills/huaweicloud-api-and-sdk/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/SKILL.md +6 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-capability-discovery/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/SKILL.md +11 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-cli-and-auth/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/skills/huaweicloud-core/SKILL.md +53 -53
- package/plugins/huaweicloud-core/skills/huaweicloud-core/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/skills/huaweicloud-core/references/report-issue.md +6 -6
- package/plugins/huaweicloud-core/skills/huaweicloud-core/references/select.md +3 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-safety/SKILL.md +0 -1
- package/plugins/huaweicloud-core/skills/huaweicloud-safety/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/skills/huaweicloud-troubleshooting/SKILL.md +33 -33
- package/plugins/huaweicloud-core/skills/huaweicloud-troubleshooting/agents/openai.yaml +3 -3
- package/plugins/huaweicloud-core/src/auth/agent-registration.mjs +39 -4
- package/plugins/huaweicloud-core/src/auth/credentials.mjs +12 -4
- package/plugins/huaweicloud-core/src/auth/service.mjs +1 -1
- package/plugins/huaweicloud-core/src/data/icons-manifest.v1.json +3517 -0
- package/plugins/huaweicloud-core/src/hcloud-cli.mjs +16 -7
- package/plugins/huaweicloud-core/src/icon-library.mjs +171 -0
- package/plugins/huaweicloud-core/src/mcp-server.mjs +0 -1
- package/plugins/huaweicloud-core/src/proxy/proxy-agent.mjs +10 -102
- package/plugins/huaweicloud-core/src/proxy/proxy-config.mjs +4 -1
- package/plugins/huaweicloud-core/src/risk-rule-engine.mjs +4 -1
- package/plugins/huaweicloud-core/src/safety-policy.mjs +122 -68
- package/plugins/huaweicloud-core/src/sandbox/hdkitservice-api.mjs +2 -7
- package/plugins/huaweicloud-core/src/sandbox/hwlink-api.mjs +10 -22
- package/plugins/huaweicloud-core/src/sandbox/session-manager.mjs +32 -11
- package/plugins/huaweicloud-core/src/search-market.mjs +46 -12
- package/plugins/huaweicloud-core/src/setup-cli.mjs +743 -168
- package/plugins/huaweicloud-core/src/tools.mjs +427 -114
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-exec-client.js +54 -34
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-fair-queue.js +1 -5
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-multiplexer.js +3 -15
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-packet.js +3 -16
- package/plugins/huaweicloud-core/src/ws-exec/hwlink-terminal-channel.js +37 -31
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: huawei-ecs
|
|
3
|
-
description:
|
|
3
|
+
description: 'Use when creating, configuring, managing, or troubleshooting ECS instances on Huawei Cloud. Covers instance creation (hcloud ECS CreateServers), flavor selection, image management, security groups, EIP binding, disk attachment, auto-scaling (AS), and troubleshooting. Triggers on: ECS, instance, flavor, image, security group, EIP, EVS, auto-scaling. NOT for: CCE container workloads (use huawei-cce), BMS bare metal servers.'
|
|
4
4
|
version: 1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -17,6 +17,7 @@ Domain expertise for Huawei Cloud Elastic Cloud Server (ECS). Covers instance li
|
|
|
17
17
|
## Prerequisites
|
|
18
18
|
|
|
19
19
|
Before creating an ECS instance from scratch, you MUST have:
|
|
20
|
+
|
|
20
21
|
- A VPC (see `huawei-vpc`)
|
|
21
22
|
- A subnet with DNS configured (see `huawei-vpc`)
|
|
22
23
|
- A security group with application ports open (see `huawei-vpc`)
|
|
@@ -25,39 +26,39 @@ If these do not exist, load the `huawei-vpc` skill first and create them before
|
|
|
25
26
|
|
|
26
27
|
## Critical Warnings
|
|
27
28
|
|
|
28
|
-
| Trap
|
|
29
|
-
|
|
30
|
-
| Flavor not in region
|
|
31
|
-
| Security group denies all
|
|
32
|
-
| EIP bills when idle
|
|
33
|
-
| Stopped instance still bills
|
|
34
|
-
| Disk survives instance delete | Deleting instance does NOT delete system disk by default
|
|
29
|
+
| Trap | Why |
|
|
30
|
+
| ----------------------------- | --------------------------------------------------------------------------- |
|
|
31
|
+
| Flavor not in region | Not all flavors available everywhere. Check with ECS ListFlavors first |
|
|
32
|
+
| Security group denies all | New SGs deny ALL inbound. Must explicitly add rules |
|
|
33
|
+
| EIP bills when idle | Unattached EIP still incurs charges |
|
|
34
|
+
| Stopped instance still bills | Pay-per-use instances bill when stopped (unless shutdown-no-billing flavor) |
|
|
35
|
+
| Disk survives instance delete | Deleting instance does NOT delete system disk by default |
|
|
35
36
|
|
|
36
37
|
## Flavor Selection Guide
|
|
37
38
|
|
|
38
39
|
Flavor families are **region-dependent**. Always run `hcloud ECS ListFlavors --cli-region=<r>` to discover available flavors before recommending.
|
|
39
40
|
|
|
40
|
-
| Scenario
|
|
41
|
-
|
|
42
|
-
| Web app / microservices | General-purpose (ac, s, sn, c) | 2-4 vCPU, 4-8 GB RAM
|
|
43
|
-
| Database / big data
|
|
44
|
-
| AI inference
|
|
45
|
-
| HPC
|
|
41
|
+
| Scenario | Family | What to look for |
|
|
42
|
+
| ----------------------- | ------------------------------ | ------------------------- |
|
|
43
|
+
| Web app / microservices | General-purpose (ac, s, sn, c) | 2-4 vCPU, 4-8 GB RAM |
|
|
44
|
+
| Database / big data | Memory-optimized (m, r) | 4-8 vCPU, 16-64 GB RAM |
|
|
45
|
+
| AI inference | GPU (g, p) | 8+ vCPU, 64+ GB RAM + GPU |
|
|
46
|
+
| HPC | High-IO (h, ir, i) | 8+ vCPU, local SSD |
|
|
46
47
|
|
|
47
48
|
> See `references/flavors.md` for discovery workflow. **Do not hardcode flavor names** — availability changes by region and over time.
|
|
48
49
|
|
|
49
50
|
## Common Workflows
|
|
50
51
|
|
|
51
|
-
| Task
|
|
52
|
-
|
|
53
|
-
| List flavors
|
|
54
|
-
| Create instance
|
|
55
|
-
| Find by name
|
|
56
|
-
| Bind EIP
|
|
57
|
-
| Security group rule | hcloud VPC CreateSecurityGroupRule --security_group_id=<id> --direction=<direction> --protocol=<protocol>
|
|
58
|
-
| Attach disk
|
|
59
|
-
| Delete instance
|
|
60
|
-
| Reboot instance
|
|
52
|
+
| Task | Command | Steps |
|
|
53
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
54
|
+
| List flavors | hcloud ECS ListFlavors --cli-region=<region> | references/flavors.md |
|
|
55
|
+
| Create instance | hcloud ECS CreateServers --server.name=<n> --server.flavorRef=<id> --server.imageRef=<id> --server.nics.1.subnet_id=<id> --server.availability_zone=<az> | references/create-instance.md |
|
|
56
|
+
| Find by name | See "How to search for instances" below | |
|
|
57
|
+
| Bind EIP | hcloud EIP AssociatePublicips --publicip_id=<id> --publicip.associate_instance_id=<port-id> --publicip.associate_instance_type=PORT | Get port ID from `hcloud ECS ListServersDetails --server_id=<id>` → `OS-EXT-IPS:port_id` |
|
|
58
|
+
| Security group rule | hcloud VPC CreateSecurityGroupRule --security_group_id=<id> --direction=<direction> --protocol=<protocol> | references/sg.md |
|
|
59
|
+
| Attach disk | hcloud EVS AttachVolume --volume_id=<id> --server_id=<id> | references/evs.md |
|
|
60
|
+
| Delete instance | hcloud ECS DeleteServers --servers.1.id=<id> --delete_publicip=true --delete_volume=true | references/create-instance.md |
|
|
61
|
+
| Reboot instance | hcloud ECS BatchRebootServers --reboot.servers.1.id=<id> --reboot.type=SOFT | NOT `RebootServer` — that operation does not exist |
|
|
61
62
|
|
|
62
63
|
## How to Search for Instances
|
|
63
64
|
|
|
@@ -112,6 +113,7 @@ ssh -o StrictHostKeyChecking=accept-new -i <key> root@<eip> 'command'
|
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
Example — re-run failed cloud-init setup manually:
|
|
116
|
+
|
|
115
117
|
```bash
|
|
116
118
|
ssh -o StrictHostKeyChecking=accept-new -i <key> root@<eip> 'dnf install -y nginx && systemctl enable --now nginx'
|
|
117
119
|
```
|
|
@@ -127,14 +129,14 @@ ssh -o StrictHostKeyChecking=accept-new -i <key> root@<eip> 'dnf install -y ngin
|
|
|
127
129
|
|
|
128
130
|
## Troubleshooting
|
|
129
131
|
|
|
130
|
-
| Error
|
|
131
|
-
|
|
132
|
-
| Cannot SSH
|
|
133
|
-
| Flavor unavailable
|
|
134
|
-
| Insufficient resources
|
|
135
|
-
| AuthFailure
|
|
136
|
-
| APIGW.0802 / region permission | IAM user has no access to this region -> IAM console → User → Permissions → add region, or switch to another region
|
|
137
|
-
| Cannot SSH (port 22 open)
|
|
132
|
+
| Error | Root Cause -> Fix |
|
|
133
|
+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
134
|
+
| Cannot SSH | SG missing port 22 or no EIP -> Add ingress rule / Bind EIP |
|
|
135
|
+
| Flavor unavailable | Region limitation -> ListFlavors in target region |
|
|
136
|
+
| Insufficient resources | Stock depleted -> Change flavor or AZ |
|
|
137
|
+
| AuthFailure | Expired AK/SK -> re-run `npx huaweicloud-devkit auth init` |
|
|
138
|
+
| APIGW.0802 / region permission | IAM user has no access to this region -> IAM console → User → Permissions → add region, or switch to another region |
|
|
139
|
+
| Cannot SSH (port 22 open) | SCP policy may be blocking SSH. Check `SYS.0403` errors in command output -> Use cloud-init/user_data for initial setup instead. See `references/create-instance.md` §Bootstrap |
|
|
138
140
|
|
|
139
141
|
## Security Considerations
|
|
140
142
|
|
|
@@ -158,6 +160,7 @@ Prefer these tools over raw hcloud CLI — they enforce safety policies:
|
|
|
158
160
|
## Without MCP (Fallback)
|
|
159
161
|
|
|
160
162
|
If MCP tools are NOT available (new install, session not restarted):
|
|
163
|
+
|
|
161
164
|
- Raw hcloud commands WILL appear in shell history — passwords and secrets are at risk
|
|
162
165
|
- Always use key_name instead of adminPass
|
|
163
166
|
- Verify safety manually: no secret value reads, no credential file access
|
|
@@ -171,10 +174,10 @@ Fall back to hcloud CLI. State: "MCP unavailable, using local hcloud CLI."
|
|
|
171
174
|
|
|
172
175
|
Flexus is the lightweight ECS family. Two variants:
|
|
173
176
|
|
|
174
|
-
| Variant
|
|
175
|
-
|
|
176
|
-
| **Flexus L** | HCSS (hcss:lightInstances) |
|
|
177
|
-
| **Flexus X** | Standard ECS API
|
|
177
|
+
| Variant | API | CLI | Billing |
|
|
178
|
+
| ------------ | -------------------------- | :---------------------------------: | ------------------- |
|
|
179
|
+
| **Flexus L** | HCSS (hcss:lightInstances) | ❌ No hcloud — Python SDK only | Prepaid only |
|
|
180
|
+
| **Flexus X** | Standard ECS API | ✅ `hcloud ECS` with `x1.*` flavors | On-demand & prepaid |
|
|
178
181
|
|
|
179
182
|
For Flexus X, use standard ECS CreateServers flow with `x1.*` flavors. For Flexus L, manual console provisioning is recommended — no KooCLI path exists.
|
|
180
183
|
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
**Before executing any command: If MCP tools are not available** (new session after install), restart your session or use hcloud CLI directly with caution. Commands using adminPass/password WILL appear in shell history — prefer key_name.
|
|
4
4
|
|
|
5
5
|
## 1. Discover flavors
|
|
6
|
+
|
|
6
7
|
hcloud ECS ListFlavors --cli-region=<region> --cli-output=json
|
|
7
8
|
Filter for `os_extra_specs.cond:operation:status == normal` — most results are abandoned. See references/flavors.md.
|
|
8
9
|
|
|
9
10
|
## 2. Find availability zones
|
|
11
|
+
|
|
10
12
|
hcloud ECS NovaListAvailabilityZones --cli-region=<region>
|
|
11
13
|
|
|
12
14
|
## 3. Find image
|
|
@@ -19,27 +21,32 @@ hcloud IMS ListImages --cli-region=<region> --__imagetype=gold --__isregistered=
|
|
|
19
21
|
If searching by name (e.g. --name="Ubuntu") returns empty: use broad search without name filter, pick from results. Some regions only offer Huawei Cloud EulerOS (HCE).
|
|
20
22
|
|
|
21
23
|
Common images (verify live per region):
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
| Image | Region | ID |
|
|
26
|
+
| ---------------- | ---------- | ------------------------------------ |
|
|
24
27
|
| HCE 2.0 Standard | cn-north-4 | 7d940784-ac0a-425f-b3fa-8478f1a1df70 |
|
|
25
|
-
| Ubuntu 22.04
|
|
26
|
-
| CentOS 8.2
|
|
28
|
+
| Ubuntu 22.04 | Query live | Query live |
|
|
29
|
+
| CentOS 8.2 | Query live | Query live |
|
|
27
30
|
|
|
28
31
|
## 4. Verify or create VPC/subnet
|
|
32
|
+
|
|
29
33
|
hcloud VPC ListVpcs --cli-region=<region>
|
|
30
34
|
hcloud VPC ListSubnets --vpc_id=<vpc-id> --cli-region=<region>
|
|
31
35
|
If no VPC/subnet exists: load `huawei-vpc` skill → create VPC → create subnet (with DNS) → create security group → return here.
|
|
32
36
|
|
|
33
37
|
## 5. Create keypair (recommended over adminPass)
|
|
38
|
+
|
|
34
39
|
hcloud ECS NovaCreateKeypair --keypair.name=<name>
|
|
35
40
|
Save the returned private key to a local file. The public key is auto-injected.
|
|
36
41
|
|
|
37
42
|
Password alternative:
|
|
43
|
+
|
|
38
44
|
- adminPass: 8-26 chars, must have uppercase + lowercase + digit + special char
|
|
39
45
|
- Passwords appear ONCE in creation output and are not retrievable
|
|
40
46
|
- Passwords are logged in shell history — this is a security risk
|
|
41
47
|
|
|
42
48
|
## 6. Create instance
|
|
49
|
+
|
|
43
50
|
hcloud ECS CreateServers --cli-region=<region> --server.name=<name> --server.flavorRef=<flavor-id> --server.imageRef=<image-id> --server.nics.1.subnet_id=<subnet-id> --server.root_volume.volumetype=<type> --server.root_volume.size=<minsize> --server.vpcid=<vpc-id> --server.availability_zone=<az> --server.key_name=<keypair-name> --server.count=1
|
|
44
51
|
|
|
45
52
|
### Bootstrap with user_data (cloud-init)
|
|
@@ -63,6 +70,7 @@ hcloud ECS CreateServers ... --server.user_data=$user_data
|
|
|
63
70
|
> **Debugging**: If the script didn't run, check `/var/log/cloud-init-output.log` on the instance.
|
|
64
71
|
>
|
|
65
72
|
> **Recovery after failure**: user_data only executes on **first boot**. Restarting the instance will NOT re-run user_data scripts. If cloud-init fails (e.g., DNS missing → `yum`/`apt` cannot resolve repos):
|
|
73
|
+
>
|
|
66
74
|
> 1. Fix the root cause (e.g., update subnet DNS via `VPC UpdateSubnet`)
|
|
67
75
|
> 2. Either: SSH into the instance and run the setup commands manually (see `huawei-ecs` → SSH Connection Verification → Running Commands Inside the Instance)
|
|
68
76
|
> 3. Or: Delete the instance and recreate with corrected user_data (fresh boot)
|
|
@@ -70,6 +78,7 @@ hcloud ECS CreateServers ... --server.user_data=$user_data
|
|
|
70
78
|
## 7. EIP (two methods)
|
|
71
79
|
|
|
72
80
|
### Method A: Inline with CreateServers (Recommended)
|
|
81
|
+
|
|
73
82
|
Add EIP parameters to the `CreateServers` command in step 6:
|
|
74
83
|
|
|
75
84
|
```bash
|
|
@@ -84,6 +93,7 @@ hcloud ECS CreateServers \
|
|
|
84
93
|
> **Trap**: Parameter names differ from `EIP CreatePublicip`. Use `iptype` (not `type`), `sharetype` (not `share_type`), and `chargemode` (not `charging_mode`). Always verify with `hcloud ECS CreateServers --help`.
|
|
85
94
|
|
|
86
95
|
### Method B: Create and bind separately
|
|
96
|
+
|
|
87
97
|
hcloud EIP CreatePublicip --publicip.type=<type> --bandwidth.size=<size> --bandwidth.share_type=<share-type> --bandwidth.name=<name>
|
|
88
98
|
|
|
89
99
|
```bash
|
|
@@ -131,3 +141,4 @@ Warning: --delete_publicip and --delete_volume default to false. Set to true to
|
|
|
131
141
|
- Flavor: must be available in target region — always ListFlavors first
|
|
132
142
|
- Root volume: SSD 40GB min
|
|
133
143
|
- Keypair is safer than adminPass (passwords leak into shell history)
|
|
144
|
+
```
|
|
@@ -20,21 +20,23 @@ hcloud ECS ListFlavors --cli-region=<region> --cli-output=json \
|
|
|
20
20
|
|
|
21
21
|
## Step 2: Filter by scenario
|
|
22
22
|
|
|
23
|
-
| Scenario
|
|
24
|
-
|
|
25
|
-
| Web app / microservices | General-purpose families (ac, s, sn) | 2-4 vCPU, 4-8 GB RAM
|
|
26
|
-
| Database / big data
|
|
27
|
-
| AI inference / training | GPU families (g, p)
|
|
28
|
-
| HPC / high throughput
|
|
23
|
+
| Scenario | Look for | Preference |
|
|
24
|
+
| ----------------------- | ------------------------------------ | ---------------------- |
|
|
25
|
+
| Web app / microservices | General-purpose families (ac, s, sn) | 2-4 vCPU, 4-8 GB RAM |
|
|
26
|
+
| Database / big data | Memory-optimized families (m, r) | 4-8 vCPU, 16-64 GB RAM |
|
|
27
|
+
| AI inference / training | GPU families (g, p) | 8+ vCPU, 64+ GB RAM |
|
|
28
|
+
| HPC / high throughput | High-IO families (h, ir, i) | 8+ vCPU, local SSD |
|
|
29
29
|
|
|
30
30
|
## Step 3: Match spec from ListFlavors output
|
|
31
31
|
|
|
32
32
|
Common naming pattern: `<family><gen>.<type>x<ratio>`
|
|
33
|
+
|
|
33
34
|
- `ac6.2xlarge.2` = ac6 family, 2xlarge (8 vCPU), ratio 2 (vCPU:RAM = 1:2 → 16 GB)
|
|
34
35
|
|
|
35
36
|
## Do Not Hardcode
|
|
36
37
|
|
|
37
38
|
Flavor family names are region-dependent. Example discrepancies seen in testing:
|
|
39
|
+
|
|
38
40
|
- cn-south-1: ac6/ac7/kc/r-c7e (s6/m6/g6 NOT available)
|
|
39
41
|
- Other regions may have s6/m6/g6 families
|
|
40
42
|
|
|
@@ -44,10 +46,10 @@ Always run ListFlavors and pick from actual results.
|
|
|
44
46
|
|
|
45
47
|
`ListFlavors` returns ALL specs including abandoned ones. Before selecting a spec, check the `os_extra_specs` field in the JSON response:
|
|
46
48
|
|
|
47
|
-
| Field
|
|
48
|
-
|
|
49
|
+
| Field | Values | Meaning |
|
|
50
|
+
| -------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------ |
|
|
49
51
|
| `os_extra_specs.cond:operation:status` | `normal`, `abandon`, `sellout` | Only `normal` specs can be created. `abandon` = deprecated, `sellout` = out of stock |
|
|
50
|
-
| `os_extra_specs.cond:operation:az`
|
|
52
|
+
| `os_extra_specs.cond:operation:az` | e.g. `cn-north-4g(normal)` | Spec is available in this AZ. Multiple entries = multiple AZ support |
|
|
51
53
|
|
|
52
54
|
A flavor can be `normal` globally but `abandon` in specific AZs. Selecting an `abandon` or `sellout` spec will fail with **`Ecs.0019`** at creation time — there is no pre-flight validation in `ListFlavors`. If creation fails:
|
|
53
55
|
|
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
## 错误码映射
|
|
6
6
|
|
|
7
|
-
| 错误
|
|
8
|
-
|
|
9
|
-
| `Ecs.0005` flavor-image 不匹配
|
|
10
|
-
| `[USE_ERROR]不正确的参数:imagetype`
|
|
11
|
-
| `[USE_ERROR]不正确的参数:chargingMode`
|
|
12
|
-
| `[USE_ERROR]不正确的参数:__support_amd` | 参数无效
|
|
13
|
-
| Cannot SSH
|
|
14
|
-
| Flavor unavailable
|
|
15
|
-
| Insufficient resources
|
|
16
|
-
| AuthFailure
|
|
7
|
+
| 错误 | 根因 | 修复 |
|
|
8
|
+
| --------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| `Ecs.0005` flavor-image 不匹配 | 镜像虚拟化类型与规格不兼容 | 检查 image `__support_amd`/`__support_xen` 与 flavor `os_extra_specs`。BareMetal 镜像不兼容标准 ECS 规格 |
|
|
10
|
+
| `[USE_ERROR]不正确的参数:imagetype` | 参数名错误 | KooCLI 使用双下划线前缀:`--__imagetype=gold`(不是 `--imagetype`) |
|
|
11
|
+
| `[USE_ERROR]不正确的参数:chargingMode` | 参数路径错误 | 计费模式参数路径:`--server.extendparam.chargingMode=postPaid`。不传默认按需付费 |
|
|
12
|
+
| `[USE_ERROR]不正确的参数:__support_amd` | 参数无效 | `IMS ListImages` 某些版本不支持此过滤。去掉该参数,使用 client-side 过滤 |
|
|
13
|
+
| Cannot SSH | 安全组未开放22端口 或 未绑定EIP | 1) 添加入方向规则 tcp 22。2) `hcloud EIP BindPublicIp` |
|
|
14
|
+
| Flavor unavailable | 区域不支持该规格 | `hcloud ECS ListFlavors --cli-region=<r>` 先查。不硬编码 s6/m6 等规格名 |
|
|
15
|
+
| Insufficient resources | AZ 库存不足 | 换规格、换 AZ、或等待资源释放 |
|
|
16
|
+
| AuthFailure | AK/SK 过期或无效 | `npx huaweicloud-devkit auth init` 重新配置统一凭据 |
|
|
17
17
|
|
|
18
18
|
## 创建失败诊断流程
|
|
19
19
|
|
|
@@ -38,10 +38,10 @@ hcloud IMS ListImages --cli-region=<r> --__imagetype=gold --__isregistered=true
|
|
|
38
38
|
|
|
39
39
|
## 密钥对 vs 密码
|
|
40
40
|
|
|
41
|
-
| 方式
|
|
42
|
-
|
|
41
|
+
| 方式 | 安全 | 建议 |
|
|
42
|
+
| -------------------------- | ----- | -------------------------------------------------- |
|
|
43
43
|
| `--server.key_name=<name>` | ✅ 高 | **推荐**。先 `hcloud DEW CreateKeypair` 创建密钥对 |
|
|
44
|
-
| `--server.adminPass=<pw>`
|
|
44
|
+
| `--server.adminPass=<pw>` | ❌ 低 | 密码明文进入 shell 历史。仅测试用 |
|
|
45
45
|
|
|
46
46
|
密码要求:8-26 字符,含大写 + 小写 + 数字 + 特殊字符。
|
|
47
47
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: huawei-functiongraph
|
|
3
|
-
description:
|
|
3
|
+
description: 'Use when creating, deploying, or managing serverless functions on FunctionGraph. Covers triggers (APIG/OBS/timer/SMN), cold start, reserved concurrency. Triggers: FunctionGraph, serverless, function, Lambda, trigger. NOT for: CCE containers (use huawei-cce).'
|
|
4
4
|
version: 1
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -20,16 +20,16 @@ Domain expertise for Huawei Cloud FunctionGraph. Covers function lifecycle, code
|
|
|
20
20
|
|
|
21
21
|
## Critical Warnings
|
|
22
22
|
|
|
23
|
-
| Trap
|
|
24
|
-
|
|
25
|
-
| Service name is `FunctionGraph`
|
|
26
|
-
| CLI requires `project_id`
|
|
27
|
-
| Cold start 100ms-2s
|
|
28
|
-
| Max execution 900s
|
|
29
|
-
| Env vars plaintext
|
|
30
|
-
| **ZIP upload is unreliable**
|
|
31
|
-
| **DeleteFunction strip `:latest`**
|
|
32
|
-
| **DeleteFunctionTrigger does NOT cascade** | Deleting a DEDICATEDGATEWAY trigger leaves the API in APIG. Manually clean up: `hcloud APIG DeleteApiV2 --instance_id=<id> --api_id=<api-id>`.
|
|
23
|
+
| Trap | Why |
|
|
24
|
+
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| Service name is `FunctionGraph` | NOT `FGS`. KooCLI 7.x uses the full service name |
|
|
26
|
+
| CLI requires `project_id` | Get it: `hcloud IAM KeystoneListProjects` or extract from URN `urn:fss:<region>:<project_id>:...` |
|
|
27
|
+
| Cold start 100ms-2s | Reserve concurrency for latency-sensitive workloads |
|
|
28
|
+
| Max execution 900s | Use ECS/CCE for long-running tasks |
|
|
29
|
+
| Env vars plaintext | Use DEW for secrets |
|
|
30
|
+
| **ZIP upload is unreliable** | `CreateFunction --code_type=zip --code_filename=xxx.zip` succeeds even with a nonexistent file — the function is created with empty code. Prefer `code_type=inline` for simple functions. If using zip, verify `code_size` > placeholder after creation and run `InvokeFunction` to confirm output. |
|
|
31
|
+
| **DeleteFunction strip `:latest`** | Passing `urn:fss:...:function:xxx:latest` causes FSS.0400. Strip `:latest` suffix (DeleteFunction only — UpdateApiV2 needs the full URN). |
|
|
32
|
+
| **DeleteFunctionTrigger does NOT cascade** | Deleting a DEDICATEDGATEWAY trigger leaves the API in APIG. Manually clean up: `hcloud APIG DeleteApiV2 --instance_id=<id> --api_id=<api-id>`. |
|
|
33
33
|
|
|
34
34
|
## Prerequisites
|
|
35
35
|
|
|
@@ -42,13 +42,13 @@ hcloud FunctionGraph --help # confirm service is available
|
|
|
42
42
|
|
|
43
43
|
If you see `FSS.0403 Forbidden`, the user needs these permissions:
|
|
44
44
|
|
|
45
|
-
| Operation
|
|
46
|
-
|
|
45
|
+
| Operation | Required Permission |
|
|
46
|
+
| --------------- | --------------------------------------- |
|
|
47
47
|
| Create function | `functiongraph:function:createFunction` |
|
|
48
|
-
| List functions
|
|
48
|
+
| List functions | `functiongraph:function:list` |
|
|
49
49
|
| Delete function | `functiongraph:function:deleteFunction` |
|
|
50
|
-
| Invoke function | `functiongraph:function:invoke`
|
|
51
|
-
| Create trigger
|
|
50
|
+
| Invoke function | `functiongraph:function:invoke` |
|
|
51
|
+
| Create trigger | `functiongraph:trigger:*` |
|
|
52
52
|
|
|
53
53
|
Grant via IAM console (`FunctionGraph FullAccess` role) or ask project admin.
|
|
54
54
|
|
|
@@ -56,18 +56,19 @@ Grant via IAM console (`FunctionGraph FullAccess` role) or ask project admin.
|
|
|
56
56
|
|
|
57
57
|
Always discover parameters with `--help` before executing. These are the correct operation names:
|
|
58
58
|
|
|
59
|
-
| Task
|
|
60
|
-
|
|
61
|
-
| List functions
|
|
62
|
-
| Show function
|
|
63
|
-
| Create function | `CreateFunction`
|
|
64
|
-
| Delete function | `DeleteFunction`
|
|
65
|
-
| Invoke function | `InvokeFunction`
|
|
66
|
-
| Create trigger
|
|
67
|
-
| List triggers
|
|
68
|
-
| Delete trigger
|
|
59
|
+
| Task | Operation | Gotchas |
|
|
60
|
+
| --------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| List functions | `ListFunctions` | |
|
|
62
|
+
| Show function | `ShowFunctionConfig` | |
|
|
63
|
+
| Create function | `CreateFunction` | references/create-function.md |
|
|
64
|
+
| Delete function | `DeleteFunction` | Strip `:latest` from URN |
|
|
65
|
+
| Invoke function | `InvokeFunction` | Requires body param (`--name=<value>` becomes event body). Use `--x_cff_request_version=v0` for raw output, `v1` for APIG-wrapped. |
|
|
66
|
+
| Create trigger | `CreateFunctionTrigger` | references/triggers.md |
|
|
67
|
+
| List triggers | `ListFunctionTriggers` | |
|
|
68
|
+
| Delete trigger | `DeleteFunctionTrigger` | |
|
|
69
69
|
|
|
70
70
|
Discover exact parameters:
|
|
71
|
+
|
|
71
72
|
```bash
|
|
72
73
|
hcloud FunctionGraph CreateFunction --help
|
|
73
74
|
hcloud FunctionGraph CreateFunctionTrigger --help
|
|
@@ -83,19 +84,19 @@ See `references/deploy-workflow.md` for a step-by-step example with code templat
|
|
|
83
84
|
|
|
84
85
|
## Troubleshooting
|
|
85
86
|
|
|
86
|
-
| Error
|
|
87
|
-
|
|
88
|
-
| `不支持的服务名称:FGS`
|
|
89
|
-
| `不支持的operation:CreateTrigger` | Use `CreateFunctionTrigger`
|
|
90
|
-
| `FSS.0403` / Forbidden
|
|
91
|
-
| `缺少必填参数:{*}` on Invoke
|
|
92
|
-
| APIG/EOM trigger error
|
|
93
|
-
| `event_data` parse error
|
|
94
|
-
| FSS.1078 / code upload fails
|
|
95
|
-
| DeleteFunction with `:latest`
|
|
96
|
-
| Code too large
|
|
97
|
-
| Cold start slow
|
|
98
|
-
| Auth failure
|
|
87
|
+
| Error | Root Cause -> Fix |
|
|
88
|
+
| --------------------------------- | ------------------------------------------------------------------------ |
|
|
89
|
+
| `不支持的服务名称:FGS` | Use `FunctionGraph`, not `FGS` |
|
|
90
|
+
| `不支持的operation:CreateTrigger` | Use `CreateFunctionTrigger` |
|
|
91
|
+
| `FSS.0403` / Forbidden | Missing IAM permissions — see IAM Permissions above |
|
|
92
|
+
| `缺少必填参数:{*}` on Invoke | Add body param: `--name=<value>` |
|
|
93
|
+
| APIG/EOM trigger error | `trigger_type_code=APIG` deprecated — use `DEDICATEDGATEWAY` |
|
|
94
|
+
| `event_data` parse error | Use dotted format: `--event_data.key=value`, NOT JSON string |
|
|
95
|
+
| FSS.1078 / code upload fails | `--code_filename` is filename-only, no path. `cd` to zip directory first |
|
|
96
|
+
| DeleteFunction with `:latest` | Strip `:latest` version suffix from URN |
|
|
97
|
+
| Code too large | Inline limit 10KB — use `zip`/`obs` code type |
|
|
98
|
+
| Cold start slow | Set reserved instances for critical functions |
|
|
99
|
+
| Auth failure | Run `npx huaweicloud-devkit auth init` |
|
|
99
100
|
|
|
100
101
|
## Security Considerations
|
|
101
102
|
|
package/plugins/huaweicloud-core/skills/huawei-functiongraph/references/apig-event-format.md
CHANGED
|
@@ -22,6 +22,7 @@ When APIG calls FunctionGraph via DEDICATEDGATEWAY trigger, the event structure
|
|
|
22
22
|
`event["body"]` is Base64 encoded. You MUST decode it:
|
|
23
23
|
|
|
24
24
|
**Python handler template:**
|
|
25
|
+
|
|
25
26
|
```python
|
|
26
27
|
import json, base64
|
|
27
28
|
|
|
@@ -38,18 +39,19 @@ def handler(event, context):
|
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
**Node.js handler template:**
|
|
42
|
+
|
|
41
43
|
```js
|
|
42
44
|
exports.handler = async (event, context) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
let body = event.body || '';
|
|
46
|
+
if (event.isBase64Encoded) {
|
|
47
|
+
body = Buffer.from(body, 'base64').toString('utf8');
|
|
48
|
+
}
|
|
49
|
+
const data = body ? JSON.parse(body) : {};
|
|
50
|
+
return {
|
|
51
|
+
statusCode: 200,
|
|
52
|
+
body: JSON.stringify({ message: 'ok', received: data }),
|
|
53
|
+
headers: { 'Content-Type': 'application/json' },
|
|
54
|
+
};
|
|
53
55
|
};
|
|
54
56
|
```
|
|
55
57
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Runtime Options
|
|
4
4
|
|
|
5
|
-
| Runtime
|
|
6
|
-
|
|
7
|
-
| Python3.9
|
|
8
|
-
| Python3.10
|
|
9
|
-
| Node.js 18
|
|
10
|
-
| Java 8/11/17
|
|
11
|
-
| Go 1.x
|
|
12
|
-
| C# (.NET Core) | `CsharpDemo::CsharpDemo.Function::Handler` | Namespace.Class::Method
|
|
5
|
+
| Runtime | Handler Format | Example |
|
|
6
|
+
| -------------- | ------------------------------------------ | ----------------------------------------------------------------- |
|
|
7
|
+
| Python3.9 | `index.handler` | `def handler(event, context): return {"statusCode": 200}` |
|
|
8
|
+
| Python3.10 | `index.handler` | Same as 3.9 |
|
|
9
|
+
| Node.js 18 | `index.handler` | `exports.handler = async (event, context) => ({statusCode: 200})` |
|
|
10
|
+
| Java 8/11/17 | `com.example.Handler::handleRequest` | Java class method |
|
|
11
|
+
| Go 1.x | `handler` | Go function name |
|
|
12
|
+
| C# (.NET Core) | `CsharpDemo::CsharpDemo.Function::Handler` | Namespace.Class::Method |
|
|
13
13
|
|
|
14
14
|
## Create Function (inline)
|
|
15
15
|
|
|
@@ -26,13 +26,13 @@ hcloud FunctionGraph CreateFunction \
|
|
|
26
26
|
--cli-region=<region>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
| Param
|
|
30
|
-
|
|
31
|
-
| `--func_name`
|
|
32
|
-
| `--runtime`
|
|
33
|
-
| `--handler`
|
|
34
|
-
| `--memory_size` | No
|
|
35
|
-
| `--timeout`
|
|
29
|
+
| Param | Required | Range/Default |
|
|
30
|
+
| --------------- | -------- | ------------------------- |
|
|
31
|
+
| `--func_name` | Yes | 1-60 chars |
|
|
32
|
+
| `--runtime` | Yes | See runtime options above |
|
|
33
|
+
| `--handler` | Yes | Per runtime |
|
|
34
|
+
| `--memory_size` | No | 128-4096 MB, default 128 |
|
|
35
|
+
| `--timeout` | No | 1-900s, default 3 |
|
|
36
36
|
|
|
37
37
|
## ZIP Upload Warning
|
|
38
38
|
|
|
@@ -49,11 +49,11 @@ Grant `FunctionGraph FullAccess` role or custom policy.
|
|
|
49
49
|
|
|
50
50
|
## Error Codes
|
|
51
51
|
|
|
52
|
-
| Error
|
|
53
|
-
|
|
54
|
-
| FSS.0400 | `:latest` suffix on URN. Strip it
|
|
55
|
-
| FSS.1417 | Missing DEDICATEDGATEWAY params
|
|
56
|
-
| FSS.0403 | Insufficient IAM permission
|
|
52
|
+
| Error | Root Cause -> Fix |
|
|
53
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
+
| FSS.0400 | `:latest` suffix on URN. Strip it |
|
|
55
|
+
| FSS.1417 | Missing DEDICATEDGATEWAY params |
|
|
56
|
+
| FSS.0403 | Insufficient IAM permission |
|
|
57
57
|
| FSS.1020 | Missing `--app_xrole` when binding VPC. Create IAM agency with `trust_domain_name=functiongraph`. See `huawei-iam` skill → Agencies section |
|
|
58
58
|
|
|
59
59
|
## VPC + Agency Configuration
|
|
@@ -68,4 +68,5 @@ hcloud IAM GrantRoleToAgency --agency_name=<name> --role_id=<role-id>
|
|
|
68
68
|
# 3. Use in CreateFunction
|
|
69
69
|
hcloud FunctionGraph CreateFunction --func_vpc.vpc_id=<vpc> --func_vpc.subnet_id=<subnet> --app_xrole=<name> ...
|
|
70
70
|
```
|
|
71
|
+
|
|
71
72
|
| QuotaExceeded | Max 10 functions per project per region |
|
|
@@ -16,12 +16,12 @@ KooCLI uses **dotted key-value format**, NOT JSON strings:
|
|
|
16
16
|
|
|
17
17
|
## Trigger Types
|
|
18
18
|
|
|
19
|
-
| Type
|
|
20
|
-
|
|
21
|
-
| APIG Dedicated | `DEDICATEDGATEWAY`
|
|
22
|
-
| Timer / Cron
|
|
23
|
-
| OBS
|
|
24
|
-
| SMN
|
|
19
|
+
| Type | `--trigger_type_code` | Notes |
|
|
20
|
+
| -------------- | --------------------- | ---------------------------------------------------------- |
|
|
21
|
+
| APIG Dedicated | `DEDICATEDGATEWAY` | Use this, not `APIG` (deprecated). Requires APIG instance. |
|
|
22
|
+
| Timer / Cron | `TIMER` | Simplest trigger for testing. No APIG dependency. |
|
|
23
|
+
| OBS | `OBS` | Event when objects created/deleted in bucket |
|
|
24
|
+
| SMN | `SMN` | Message notification trigger |
|
|
25
25
|
|
|
26
26
|
## TIMER Trigger (Simple Testing)
|
|
27
27
|
|
|
@@ -46,22 +46,22 @@ hcloud FunctionGraph CreateFunctionTrigger \
|
|
|
46
46
|
|
|
47
47
|
These are labeled optional by `--help` but are **required** for DEDICATEDGATEWAY:
|
|
48
48
|
|
|
49
|
-
| Param
|
|
50
|
-
|
|
51
|
-
| `--event_data.protocol`
|
|
52
|
-
| `--event_data.sl_domain`
|
|
53
|
-
| `--event_data.env_name`
|
|
54
|
-
| `--event_data.env_id`
|
|
55
|
-
| `--event_data.instance_id` | APIG dedicated instance ID
|
|
56
|
-
| `--event_data.group_id`
|
|
57
|
-
| `--event_data.name`
|
|
49
|
+
| Param | Note |
|
|
50
|
+
| -------------------------- | ---------------------------------------------------------------------------- |
|
|
51
|
+
| `--event_data.protocol` | `HTTPS` or `HTTP` or `BOTH` |
|
|
52
|
+
| `--event_data.sl_domain` | Subdomain from APIG instance (e.g. `xxxx.apic.<region>.huaweicloudapis.com`) |
|
|
53
|
+
| `--event_data.env_name` | API environment name (`RELEASE`) |
|
|
54
|
+
| `--event_data.env_id` | API environment ID |
|
|
55
|
+
| `--event_data.instance_id` | APIG dedicated instance ID |
|
|
56
|
+
| `--event_data.group_id` | API group ID |
|
|
57
|
+
| `--event_data.name` | API name — **hyphens (`-`) are DISALLOWED**. Use underscores (`_`) instead. |
|
|
58
58
|
|
|
59
59
|
### Error Mapping
|
|
60
60
|
|
|
61
|
-
| Error
|
|
62
|
-
|
|
63
|
-
| FSS.1417
|
|
64
|
-
| API name regex fail | Rename API — remove hyphens (`-`), use `[a-zA-Z0-9_]+` only.
|
|
61
|
+
| Error | Root Cause → Fix |
|
|
62
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| FSS.1417 | Missing `instance_id`, `group_id`, `protocol`, `env_name`, or `env_id`. These are labeled optional but REQUIRED. |
|
|
64
|
+
| API name regex fail | Rename API — remove hyphens (`-`), use `[a-zA-Z0-9_]+` only. |
|
|
65
65
|
|
|
66
66
|
### Example
|
|
67
67
|
|