Install
openclaw skills install @wlc-dev/huawei-cloud-dcs-list
List Huawei Cloud DCS (Distributed Cache Service, Redis / Memcached) instances in a tenant region through KooCLI (hcloud DCS ListInstances — read-only GET /v2/{project_id}/instances), with an automatic fallback to the official huaweicloudsdkdcs v2 SDK when hcloud is not installed. 2. Default output is the compact instance-name list (名称列表, also available via --names-only); --table renders the full-field table (名称/ID/引擎/版本/容量/规格/状态/连接地址/端口/可用区), --json outputs the raw response array, and --md / --format md prints a GitHub-flavored Markdown table with the same fixed ten columns as export-markdown 口径 (缺失字段渲染 -, | 转义为 \|, 换行转空格). --md-output 可把该表格原子落盘(内容与 stdout 一致). 3. Supports --name (server-side fuzzy query, plus --name-equal exact match), --instance-id / --ip / --status / --tags filtering (all real server-side ListInstances query parameters), region override, and automatic limit/offset paging. 4. Explicit error hints for empty instance lists (「当前区域无 DCS 实例」), 403 / insufficient IAM permission (「无权限访问分布式缓存服务(DCS)」), missing or invalid AK/SK credentials, missing project_id on the SDK fallback, and hcloud not installed. 5. Built-in write-intent guard: any mutating intent (create / delete / update / resize / restart / flush / clear / restore / backup / freeze) or any operation other than ListInstances is rejected before execution — this skill is strictly read-only. 6. Triggers include: "list DCS instances", "DCS instance list", "查询 DCS 实例列表", "DCS 实例列表", "Redis 实例列表", "缓存实例列表", "查询缓存实例", "DCS inventory", "list cache instances", "华为云 DCS 列表", "DCS 实例 Markdown 表格", "导出 DCS 实例 Markdown", "DCS 实例表格输出". 7. Offline unit tests (mocked hcloud subprocess) cover output modes (names / table / json / md), filters, paging, error scenarios, SDK fallback, Markdown escaping + atomic file writing, and the write-intent guard.
openclaw skills install @wlc-dev/huawei-cloud-dcs-listQuery the DCS (Distributed Cache Service, Redis / Memcached) instance list of
a tenant region through KooCLI hcloud DCS ListInstances (official read-only
GET /v2/{project_id}/instances, verified in the huaweicloudsdkdcs v2
client _list_instances_http_info metadata — resource_path: "/v2/{project_id}/instances", method: "GET"). The skill is aimed at DCS
inventory inspection, daily operations patrol, and as a pre-query step for
other DCS skills that need an instance_id.
Architecture:
agent → python3 scripts/list_dcs.py → hcloud DCS ListInstances --cli-region=<region>
→ Huawei Cloud DCS OpenAPI (dcs.<region>.myhuaweicloud.com) → parsed JSON → names list / table / --json / markdown (+ optional --md-output file)
(hcloud binary missing) → fallback: huaweicloudsdkdcs v2 DcsClient.list_instances
Key properties:
ListInstances
(GET). A write-intent guard scans user arguments and validates the
operation name; mutating intents (create / delete / update / resize /
restart / flush / clear / restore / backup / freeze ...) are rejected with
an explicit message before any command runs.huaweicloudsdkdcs v2 SDK (DcsClient.list_instances). Credentials are
always read by the CLI profile / whitelisted SDK environment variables —
never handled by the script.--table renders the full-field
table, --json the raw response array, and --md / --format md a
Markdown table.--md prints a fixed
ten-column GitHub-flavored table (名称/ID/引擎/版本/容量/规格/状态/连接地址/
端口/可用区) identical to the DCS export-markdown 口径; missing fields
render -, | is escaped as \| and line breaks collapse to a space, so a
value can never break the table. --md-output <path> additionally writes
exactly that text through a temp file + atomic rename (失败非零退出、不留
残缺文件); an empty list prints only the friendly hint — no header, no file.--name / --instance_id /
--ip / --status / --tags are real ListInstances query parameters
(verified against hcloud DCS ListInstances --help); paging uses
--limit (1~1000) + --offset and is fetched automatically until
instance_num is reached.Out of scope: every mutating DCS action (create / delete / resize / restart / flush / clear data / restore backup / reset password / upgrade / IP exchange). Those require a dedicated write-capable skill and explicit user confirmation.
hcloud) installed — see
references/cli-installation-guide.md.
Alternative: pip install huaweicloudsdkdcs to enable the SDK fallback path./v2/{project_id}/instances; when falling back to the SDK, supply the
project id via --project-id or the HUAWEICLOUD_SDK_PROJECT_ID /
HUAWEI_PROJECT_ID environment variables. The KooCLI path resolves it
from the profile automatically.dcs:instance:list; least-privilege
policy in references/iam-policies.md.dcs.cn-north-4.myhuaweicloud.com.cn-north-4).--json for downstream tooling, --md for a pasted-into-
ticket Markdown table (optionally persisted with --md-output).# Compact instance-name list (default — the core ask of this skill)
python3 scripts/list_dcs.py --region cn-north-4
python3 scripts/list_dcs.py --names-only
# Full-field table (名称/ID/引擎/容量/状态/连接地址/端口 etc.)
python3 scripts/list_dcs.py --table
# Raw JSON of every returned field
python3 scripts/list_dcs.py --json
# Markdown table (fixed 10 columns, same口径 as the DCS export-markdown 能力)
python3 scripts/list_dcs.py --md
python3 scripts/list_dcs.py --format md
python3 scripts/list_dcs.py --format table # same as --table
python3 scripts/list_dcs.py --format names # same as --names-only
# Markdown + atomic file write (file content == stdout table)
python3 scripts/list_dcs.py --md --md-output ./dcs_instances.md
# Markdown combined with server-side filters / paging
python3 scripts/list_dcs.py --md --status RUNNING --page-size 500
python3 scripts/list_dcs.py --format md --name-equal --name cache-demo-01
# Filter by instance name (server-side fuzzy query parameter)
python3 scripts/list_dcs.py --name cache-demo
python3 scripts/list_dcs.py --name-equal --name cache-demo-01 # exact match
# Filter by exact instance ID / connection IP / status / tags
python3 scripts/list_dcs.py --instance-id 55f47f3d-...
python3 scripts/list_dcs.py --ip 192.168.0.10
python3 scripts/list_dcs.py --status RUNNING
python3 scripts/list_dcs.py --tags env=prod
# Automatic paging; page size is tunable (1~1000, default 100)
python3 scripts/list_dcs.py --page-size 500
# Combine filters
python3 scripts/list_dcs.py --region cn-south-1 --status RUNNING --names-only
Equivalent direct KooCLI command (the script wraps exactly this call, with automatic offset paging):
hcloud DCS ListInstances --cli-region=cn-north-4 --limit=100 --offset=0
hcloud DCS ListInstances --cli-region=cn-north-4 --name=cache-demo --status=RUNNING
| Parameter | Required | Description | Example |
|---|---|---|---|
--region / -r | No | Huawei Cloud region (default cn-north-4) | cn-south-1 |
--names-only | No | Output instance names only — this is also the default mode | — |
--table | No | Output the full-field table (名称/ID/引擎/版本/容量/规格/状态/连接地址/端口) | — |
--json | No | Output the raw instance array as JSON | — |
--md | No | Output a GitHub-flavored Markdown table with the fixed 10 columns of the DCS export-markdown 口径 (missing fields -) | — |
--format | No | Output format selector: names (default) / table / json / md | md |
--md-output | No | md mode only: atomically write the table to this .md path (content identical to stdout; parent dirs created; failure exits non-zero and leaves no partial file) | ./dcs_instances.md |
--name | No | Filter by instance name — real server-side query parameter (fuzzy) | cache-demo |
--name-equal | No | Exact-match switch: drops the fuzzy server param and filters locally, case-insensitive | used with --name |
--instance-id | No | Filter by exact instance ID — real server-side query parameter | 55f47f3d-... |
--ip | No | Filter by connection IP address — real server-side query parameter | 192.168.0.10 |
--status | No | Filter by instance state — real server-side query parameter (RUNNING / ERROR / ...) | RUNNING |
--tags | No | Filter by instance tags — real server-side query parameter (key1=value1,key2=value2) | env=prod |
--page-size | No | Page size for ListInstances (default 100, range 1–1000; pages are fetched automatically) | 500 |
--project-id | No | Project ID (needed by the SDK fallback path for /v2/{project_id}/instances) | 05f... |
--operation | No | hcloud DCS operation name; only ListInstances is allowed | ListInstances |
Output-mode precedence (backwards compatible): --json → --names-only
(default) → --table → --md → --format value. Without any mode flag the
script prints the instance-name list; --json wins over everything, --table
requires the full-field table, and --md / --format md produce the identical
Markdown table (--format md and --md are byte-for-byte the same output).
--md-output is only accepted in Markdown mode — with any other mode the
script exits 1 with an explicit hint.
--operation value for
mutating vocabulary (create, delete, update, modify, resize,
restart, reboot, flush, clear, restore, backup, freeze,
unfreeze, release, and DCS operation names such as CreateInstance,
BatchDeleteInstances, DeleteSingleInstance, ResizeInstance,
RestartOrFlushInstances, UpdateInstance, ResetInstancePassword).--md-output path is a filesystem target, not a DCS operation, so
that single value is excluded from the scan (--md-output /tmp/dcs-backup.md
is allowed) — every other argument is still checked.GuardError, prints
[错误] 检测到写操作意图 ... 已被守卫拦截, and exits with code 1 before
a single hcloud command is executed.hcloud DCS ListInstances (GET) — or the SDK list_instances call
in the fallback path — is ever constructed by build_command(); there is
no code path that can issue a mutating DCS API call.hcloud <Service> <Operation> --cli-region=<region> [--key=value ...]
DCS.ListInstances.--cli-region=<value>, e.g. --cli-region=cn-north-4
(required for every concrete DCS call).--key=value, e.g. --name=cache-demo,
--instance_id=<id>, --ip=192.168.0.10, --status=RUNNING,
--tags=env=prod. All of these are real server-side ListInstances query
parameters (verified against the huaweicloudsdkdcs v2
ListInstancesRequest model).--limit (integer, 1~1000; KooCLI defaults to 10 per page
when unset) + --offset (integer, ≥ 0); the script fetches pages
automatically until the response instance_num total is reached._http_info) —
GET /v2/{project_id}/instances (huaweicloudsdkdcs v2
_list_instances_http_info); the project_id is resolved by KooCLI from
the credential profile.| Scenario | Behavior |
|---|---|
| Empty instance list | Exit 0, prints 当前区域(<x>)无 DCS 实例 (+ active filters); in md mode no header row and no file is written |
| 403 / insufficient IAM permission | Exit 1, 无权限访问分布式缓存服务(DCS),请检查 IAM 权限 hint |
| Missing / invalid AK-SK | Exit 1, explicit hint to configure hcloud credentials out-of-band (never in chat) |
| Missing project_id (SDK fallback) | Exit 1, hint to pass --project-id or set the project-id env var |
| hcloud not installed | Exit 1 after SDK fallback also unavailable, hint to install KooCLI or pip install huaweicloudsdkdcs |
| Network / API failure | Exit 1 with the hcloud stderr excerpt |
DCS API error body returned with exit code 0 (e.g. DCS.4062 invalid parameter) | Exit 1, DCS API 错误 <error_code>: <error_msg> — never reported as unparseable output (a diagnostic table appended after the JSON is ignored) |
KooCLI usage error ([USE_ERROR] ..., even with exit code 0) | Exit 1, explicit hcloud 参数错误 hint pointing to hcloud DCS ListInstances --help |
--page-size out of range (not 1~1000) | Exit 1, explicit range error before any call |
--md-output given outside md mode | Exit 1, explicit hint that --md-output requires --md / --format md |
--md-output write failure (permissions / disk) | Exit 1, [错误] Markdown 文件写入失败…,未留下残缺文件; no partial target file, temp file removed |
| Write intent detected | Exit 1, GuardError message, no command executed |
Exit codes: 0 success / empty region; 1 config, auth, guard, or API error.
| Scenario | Handling |
|---|---|
Non-RUNNING instances (ERROR / FROZEN / ...) | Reported with their state, not treated as failure |
--name | Forwarded as the real fuzzy server-side query parameter; --name-equal switches to exact local matching (case-insensitive) |
--instance-id / --ip / --status / --tags filters | Forwarded as real server-side query parameters (verified API params) |
| Large instance count | Automatic limit/offset paging driven by instance_num (max 100 pages) |
| Extra response fields | Table columns are built from the union of returned fields — new fields appear automatically |
| Field missing on an instance | Rendered as - in the table (and in md mode) |
| Value containing a pipe character / line breaks (md mode) | Pipe escaped as |; line breaks collapse to a single space — the table can never be broken by data |
Empty list in md mode with --md-output | Friendly hint only; no header, no separator, and no file at the target path (an existing file is left untouched) |
az_codes / tags lists | Flattened into comma-joined cells for the table |
| Instance without a name | The name list falls back to instance_id |
| Non-JSON hcloud output | ApiError with the raw excerpt (first 200 chars) |
| hcloud absent, SDK installed | Transparent fallback to huaweicloudsdkdcs list_instances, same output modes |
| User asks to create/delete/resize/flush | Out of scope — blocked by the write-intent guard; a write-capable skill with explicit user confirmation is required |
Offline unit tests with a mocked hcloud subprocess (no credentials, no network):
python3 -m unittest discover -s tests -v
templates/test-vars.json carries the live read-only smoke cases (three
hcloud DCS ListInstances calls — list / name filter / status filter — all
GET); the smoke runner only allowlists hcloud/curl, so every script-level
output mode is covered by the offline tests above instead.
Coverage: write-intent guard (read passes / create / batch delete / resize /
restart / flush / clear / restore / backup / freeze / normalized variants /
operation whitelist / --md-output path exemption), command construction (real
server-side filters forwarded; paging params; no write flags ever), JSON
extraction, failure classification (missing AK/SK, 403, generic,
[USE_ERROR] with rc=0), offset paging (instance_num-driven / full-page
fallback / empty), SDK fallback (env credentials, alternative prefixes,
missing credentials, missing project id, pagination, filters; request
construction matches the real ListInstancesRequest signature), rendering
(table with engine/capacity/status/ip/port/az fields / names / fallbacks),
Markdown mode (fixed 10-column header + separator, column order, - for
missing fields, pipe/newline escaping, --md vs --format md equivalence,
filters/paging combination, empty list → no header and no file, atomic
--md-output write + write-failure cleanup, --md-output rejected outside md
mode, mode precedence), and all main() output modes including default names
list, empty, filter, exact-name and error paths.
| Document | Content |
|---|---|
| references/iam-policies.md | Least-privilege read-only IAM policy |
| references/cli-installation-guide.md | KooCLI installation and credential configuration |
| references/verification-method.md | How the skill and its tests were verified |
| references/dataflow-diagram.md | Mermaid data flow diagram |
| references/acceptance-criteria.md | Acceptance criteria checklist |