Skill: sdk-team/alibabacloud-aes-sysom-os-diagnosis (version 0.0.1)

--- name: alibabacloud-aes-sysom-os-diagnosis description: | Perform SysOM deep OS-level diagnosis on Alibaba Cloud ECS instances to identify root causes of performance issues (CPU spikes, memory leaks, IO latency, etc.). Use when users report ECS instance performance problems, need kernel-level troubleshooting, or want to set up continuous automated diagnosis with instance enrollment and DingTalk alert notifications. --- # alibabacloud-aes-sysom-os-diagnosis > **Skill Name**: alibabacloud-aes-sysom-os-diagnosis > **Goal**: Perform SysOM deep OS-level diagnosis on Alibaba Cloud ECS instances, with optional instance enrollment and DingTalk alert configuration. --- ## Credential Security > **[CRITICAL] Credential Security Rules:** > - **NEVER** print, echo, or display AccessKey ID / AccessKey Secret values in conversation or command output (even partial masking of `LTAI_ACCESS_KEY_ID` is FORBIDDEN) > - **NEVER** ask the user to input AK/SK directly in the conversation or command line > - **NEVER** use `aliyun configure set` with literal credential values > - **ONLY** use `aliyun configure list` to check credential status > > ```bash > aliyun configure list --user-agent AlibabaCloud-Agent-Skills > ``` > Check the output for a valid profile (AK, STS, or OAuth identity). > > **If no valid profile exists, STOP here.** > 1. Obtain credentials from [Alibaba Cloud Console](https://ram.console.aliyun.com/manage/ak) > 2. Configure credentials **outside of this session** (via `aliyun configure` in terminal or environment variables in shell profile) > 3. Return and re-run after `aliyun configure list --user-agent AlibabaCloud-Agent-Skills` shows a valid profile --- ## RAM Policy For the full list of RAM permissions required by this skill, see [references/ram-policies.md](references/ram-policies.md). > **[MUST] Permission Failure Handling:** When any command or API call fails due to permission errors at any point during execution, follow this process: > 1. Read `references/ram-policies.md` to get the full list of permissions required by this SKILL > 2. Use `ram-permission-diagnose` skill to guide the user through requesting the necessary permissions > 3. Pause and wait until the user confirms that the required permissions have been granted --- ## Parameter Confirmation > **IMPORTANT: Parameter Confirmation** — Before executing any command or API call, > ALL user-customizable parameters (e.g., RegionId, instance names, CIDR blocks, > passwords, domain names, resource specifications, etc.) MUST be confirmed with the > user. Do NOT assume or use default values without explicit user approval. | Parameter | Required/Optional | Description | Default Value | |-----------|-------------------|-------------|---------------| | `region` | Required | Region of the ECS instance (e.g., `cn-hangzhou`) | None, must be provided by user | | `instance_id` | Required | ECS instance ID (e.g., `i-bp1xxxxxxxx`) | None, must be provided by user | | `ocd_description` | Optional | Problem description (English only, e.g., `high_cpu`) | `""` | | `start_time` | Optional | Diagnosis start timestamp (Unix seconds) | `0` (real-time) | | `end_time` | Optional | Diagnosis end timestamp (Unix seconds) | `0` | | `enable_diagnosis` | Optional | Force real-time diagnosis (highest priority) | `false` | | `uid` | Optional | Account ID owning the instance | `None` | | `skip_support_check` | Optional | Skip instance support check (speeds up workflow) | `false` | | `cluster_id` | Optional | ACK cluster ID (required for cluster enrollment) | None | --- ## Core Workflow The workflow has four phases with 14 steps. All `aliyun` CLI commands **MUST** include `--user-agent AlibabaCloud-Agent-Skills`. ### Phase 1: Environment Setup (Steps 0–3) **Step 0 — Enable AI-Mode and Update Plugins** Before executing any CLI commands, enable AI-Mode, set User-Agent, and update plugins: ```bash aliyun configure ai-mode enable aliyun configure ai-mode set-user-agent --user-agent [REDACTED_SECRET] aliyun plugin update ``` > **⚠️ The above three commands must be executed before all CLI operations, and only need to be run once.** **Step 1 — CLI Version Check** ```bash aliyun version --user-agent AlibabaCloud-Agent-Skills ``` Verify version >= 3.3.1. If not met, refer to `references/cli-installation-guide.md` for installation. **Step 2 — Enable Auto Plugin Installation** ```bash aliyun configure set --auto-plugin-install true --user-agent AlibabaCloud-Agent-Skills ``` **Step 3 — Credential Verification** ```bash aliyun configure list --user-agent AlibabaCloud-Agent-Skills ``` If no valid credentials exist, **STOP** and guide the user to configure credentials outside the session. --- ### Phase 2: Diagnosis Execution (Steps 4–9) For detailed workflow, see [references/diagnose-workflow.md](references/diagnose-workflow.md). **Step 4 — Ambiguous Problem Clarification (Inversion Gate)** Must confirm `region` and `instance_id`. If not provided by the user, ask explicitly. Also extract optional `ocd_description` (must be translated to English), time range, etc. > **⚠️ Time Inference Rule**: When the user's description contains **any temporal reference** (e.g., "this morning", "yesterday afternoon", "around 3pm", "last night"), you **MUST** proactively ask for the specific time range and recommend **historical diagnosis mode**. Do NOT silently default to real-time diagnosis when the problem clearly occurred in the past. **Step 5 — Cloud Assistant Online Check** ```bash aliyun ecs describe-cloud-assistant-status --biz-region-id <region> --instance-id <instance_id> --user-agent AlibabaCloud-Agent-Skills ``` Check if `CloudAssistantStatus` is `true` in the response. If offline, terminate the pipeline. **Step 6 — SysOM Role Initialization** ```bash aliyun sysom initial-sysom --check-only false --source aes-skills --user-agent AlibabaCloud-Agent-Skills ``` **Step 7 — Instance Support Check** ```bash aliyun sysom check-instance-support --instances <instance_id> --biz-region <region> --user-agent AlibabaCloud-Agent-Skills ``` **Step 8 — Invoke Diagnosis and Poll Results** #### Diagnosis Mode Decision Rules ``` if enable_diagnosis == true: mode = real-time diagnosis # enable_diagnosis has highest priority elif start_time != 0: mode = historical diagnosis # time range specified, retrospective analysis else: mode = real-time diagnosis # default ``` - **Real-time**: `start_time=0`, `end_time=0` - **Historical**: `start_time=<unix_ts>`, `end_time=<unix_ts>` - **Forced real-time**: when `enable_diagnosis=true`, force `start_time` to 0 even if provided #### Build params JSON Use **snake_case** keys (consistent with SDK). Required base fields (**ALL must be included**): ```json { "instance": "<instance_id>", "region": "<region>", "start_time": 0, "end_time": 0, "type": "ocd", "ai_roadmap": true, "enable_sysom_link": false } ``` > **⚠️ Anti-confusion Warning: `"type": "ocd"` is a REQUIRED field inside the params JSON — do NOT omit it!** > > `--service-name ocd` (CLI argument) and `"type": "ocd"` (params JSON field) are **two different levels of parameters**, both are mandatory: > - `--service-name ocd` → tells CLI which diagnosis service endpoint to call > - `"type": "ocd"` → tells the diagnosis engine which diagnosis type to execute internally > > **Do NOT omit `"type": "ocd"` from params just because `--service-name` already specifies `ocd`!** Conditional fields (add only when non-empty): - `ocd_description`: problem description in English (e.g., `high_cpu`) - `uid`: account ID owning the instance (integer) #### Invoke Diagnosis ```bash aliyun sysom invoke-diagnosis \ --service-name ocd \ --channel ecs \ --params '{"instance":"<instance_id>","region":"<region>","start_time":<start_time>,"end_time":<end_time>,"type":"ocd","ai_roadmap":true,"enable_sysom_link":false,"ocd_description":"<ocd_description>"}' \ --user-agent AlibabaCloud-Agent-Skills ``` Extract `task_id` from the response. If `Sysom.TaskInProgress` error is returned, extract the existing `task_id` from the error message and proceed to polling. #### Poll Results (interval: 10s, max: 60 attempts) ```bash aliyun sysom get-diagnosis-result --task-id <task_id> --user-agent AlibabaCloud-Agent-Skills ``` **Step 9 — Result Parsing and Output** Parse the returned JSON and present `summary.overall_status`, `summary.root_cause`, `summary.suggestions`, `issues[]`, and other key information to the user. --- ### Phase 3: Enrollment Recommendation (Steps 10–12) For detailed workflow, see [references/manage-and-alert-workflow.md](references/manage-and-alert-workflow.md). **Step 10 — Enrollment Recommendation and Intent Collection (Inversion Double Gate)** This step contains two strictly separated gates that **MUST be executed in order — merging, skipping, or simplifying is FORBIDDEN**. **10A — Prominent Enrollment Recommendation (First Gate)** **⚠️ Mandatory Rule: After presenting diagnosis results, you MUST immediately output the following recommendation content verbatim. Do NOT abbreviate, omit, or rephrase in your own words.** Replace `<instance_id>` with the actual instance ID, then output the following content **word-for-word**: <verbatim_output> > ## 🔔 Recommendation: Enroll Instance for 24/7 Automated Diagnosis > > The diagnosis just performed was a one-time manual operation. If you want SysOM to **continuously protect** this instance, we recommend **instance enrollment**. > > ### After enrollment, you will get: > > - 🔍 **Automated Diagnosis**: When the instance experiences performance issues like CPU spikes, memory leaks, or IO latency, SysOM will **automatically trigger deep diagnosis** without manual intervention > - 📲 **DingTalk Alerts**: Diagnosis reports will be **automatically pushed to DingTalk group bots**, notifying the ops team immediately > - 🛡️ **Continuous Monitoring**: 24/7 uninterrupted protection, shifting from "investigate after problems occur" to "automatically told the root cause when problems occur" > > **Would you like to enroll instance `<instance_id>`?** </verbatim_output> **After outputting the above, STOP. Wait for user reply. Do NOT ask about enrollment method in 10A.** - User **declines** → end the pipeline - User **agrees** → proceed to Step 10B **10B — Ask Enrollment Method (Second Gate)** Only after the user explicitly agrees in 10A, output the following (replace `<instance_id>` and `<region>` with actual values): <verbatim_output> > ### Please choose an enrollment method > > **A. Enroll current instance only** > Only enroll the instance just diagnosed: `<instance_id>` (`<region>`) > > **B. Enroll ACK cluster** > If this instance belongs to an ACK cluster, you can enroll **all nodes** in the cluster with one click. > Newly added nodes will be automatically enrolled — no manual action needed. > 👉 Please provide the **ACK Cluster ID** (e.g., `c9d7f3fc3d42********c1100ffb19d`) > > **C. Enroll multiple specified instances** > Batch enroll multiple instances. > 👉 Please provide the instance list in the format `InstanceID:Region`, separated by spaces > Example: `i-xxx:cn-beijing i-yyy:cn-hangzhou` > > Please choose A / B / C, or tell me your requirements directly. </verbatim_output> **After outputting the above, STOP. Wait for user reply.** **Step 11 — Execute Enrollment** > **Fixed parameter values for `--agent-id`, `--agent-version`, `--config-id` in enrollment commands are listed in the "Fixed Parameters" table in [references/related-commands.md](references/related-commands.md).** ```bash # Instance mode aliyun sysom install-agent \ --instances instance=<instance_id> region=<region> \ --install-type InstallAndUpgrade \ --agent-id <agent-id> \ --agent-version <agent-version> \ --user-agent AlibabaCloud-Agent-Skills # Cluster mode aliyun sysom install-agent-for-cluster \ --cluster-id <cluster_id> \ --agent-id <agent-id> \ --agent-version <agent-version> \ --config-id <config-id> \ --user-agent AlibabaCloud-Agent-Skills ``` **Step 12 — Enrollment Status Confirmation** ```bash # Instance mode — poll instance status (interval: 10s, max: 60 attempts) aliyun sysom list-instance-status --instance <instance_id> --biz-region <region> --user-agent AlibabaCloud-Agent-Skills # Cluster mode — get full cluster list, then match target cluster by cluster_id aliyun sysom list-clusters --user-agent AlibabaCloud-Agent-Skills # From the returned cluster list, match the target cluster by cluster_id field and check its cluster_status ``` > **⚠️ Enrollment success criteria: status `Running` means enrollment is complete — stop polling immediately and proceed to the next step.** --- ### Phase 4: Alert Configuration (Steps 13–15) For detailed workflow, see [references/manage-and-alert-workflow.md](references/manage-and-alert-workflow.md). **Step 13 — Collect DingTalk Webhook and Create Alert Destination (Inversion Gate + SDK Call)** After successful enrollment, you **MUST immediately collect the DingTalk bot Webhook URL** from the user to create an alert destination. This feature is **NOT supported by CLI** — use SDK scripts under `scripts/`. Ask the user: <verbatim_output> > 📲 Please provide the DingTalk group bot **Webhook URL** for receiving alert notifications. > Format: `https://oapi.dingtalk.com/robot/send?access_token=xxx` > > 💡 How to get it: DingTalk Group Settings → Bot Management → Add Bot → Custom Bot → Optional keyword: alert → Copy Webhook URL </verbatim_output> After the user provides the Webhook, initialize the SDK environment and create the alert destination: ```bash # Initialize SDK environment (first time only, can skip afterwards) bash scripts/setup-sdk.sh # Create alert destination (stdout outputs destination_id) .sysom-sdk-venv/bin/python scripts/create-alert-destination.py '<user-provided-webhook-url>' ``` > **⚠️ You MUST use `.sysom-sdk-venv/bin/python` to execute scripts** — using system `python3` is FORBIDDEN (signature algorithm depends on specific SDK version). On success, stdout outputs `destination_id` (a pure number). Record this value for use in Step 15. **Step 14 — Alert Item Selection (Inversion Gate)** ```bash aliyun sysom list-alert-items --user-agent AlibabaCloud-Agent-Skills ``` Display the alert items list (categorized by NODE/POD), supporting quick selection (`all`, `node-all`, `pod-all`) and numbered selection. **Step 15 — Create Alert Strategy (SDK Call)** After the user selects alert items, **create the alert strategy directly** with `destinations` set to the destination ID from Step 13. > **⚠️ CLI does NOT support the `destinations` parameter — you MUST use the SDK script to create alert strategies.** ```bash .sysom-sdk-venv/bin/python scripts/create-alert-strategy.py \ --name "aliyun-aes-skills-create-<YYYYMMDDHHmm>" \ --items "<alert_item_1>,<alert_item_2>" \ --clusters "<clusters_value>" \ --destinations "<destination_id>" ``` - Instance mode → `--clusters` value is `default` - Cluster mode → `--clusters` value is `<cluster_name>` (note: name, NOT ID) - `--destinations` → destination ID from Step 13 (multiple IDs comma-separated, e.g., `1,2`) - `--items` → alert item names comma-separated > **⚠️ You MUST use `.sysom-sdk-venv/bin/python` to execute scripts** — using system `python3` is FORBIDDEN. --- ## Success Verification For verification methods of each phase, see [references/verification-method.md](references/verification-method.md). --- ## Cleanup The diagnosis operations in this skill are **read-only** and do not modify instance state — no cleanup is needed. To uninstall an enrolled Agent, use `aliyun sysom uninstall-agent` (see [references/related-commands.md](references/related-commands.md) for parameters). **After all CLI operations are complete, you MUST disable AI-Mode:** ```bash aliyun configure ai-mode disable ``` --- ## Command Tables For the full CLI command list, see [references/related-commands.md](references/related-commands.md). --- ## Best Practices 1. **Check Cloud Assistant status before diagnosis**: SysOM diagnosis depends on Cloud Assistant being online — always confirm in Step 5 2. **Use real-time diagnosis mode**: Unless the user explicitly specifies a time range, default to real-time diagnosis 3. **Use English keywords for ocd_description**: API only supports `[a-zA-Z0-9_.~-]` characters 4. **Use double gate for enrollment recommendation**: Recommend first, then ask method — avoid information overload 5. **Cluster enrollment batch limit**: When exceeding 50 instances, the first batch installs only 50; the rest are installed automatically 6. **clusters parameter for alert strategy**: Use `default` for instance mode, use cluster **name** (not ID) for cluster mode 7. **Alert destinations via SDK**: Alert destination APIs are not supported by CLI — must use Python SDK (`alibabacloud_sysom20231230`) 8. **destinations parameter for alert strategy**: After creating an alert destination, include `destinations` (destination ID list) in `create-alert-strategy` — alerts will be pushed to DingTalk via SysOM 9. **Credential security**: Never print or echo AK/SK values in conversation 10. **All CLI commands must include `--user-agent AlibabaCloud-Agent-Skills`** 11. **Remediation suggestions may involve high-risk operations**: Follow the Human-in-the-loop protocol and wait for user confirmation --- ## Unsupported Scenarios - Non-Linux instances (Windows instances are not supported) - Instances with incompatible kernel versions (checked via check-instance-support) - Pure configuration issues (e.g., security group rules, VPC routing — no OS-level diagnosis needed) --- ## Error Handling | Error Scenario | CLI Response | Agent Action | |----------------|-------------|--------------| | Instance not supported by SysOM | check-instance-support returns unsupported | Inform user that kernel-level diagnosis is not supported, fall back to standard diagnosis | | Role authorization failure | initial-sysom returns error | Prompt user to check SysOM service activation status | | Diagnosis invocation failure | invoke-diagnosis returns error | Check credential and permission configuration | | Diagnosis timeout | get-diagnosis-result polling timeout | Suggest user retry later | | Insufficient permissions | API returns Forbidden | Read `references/ram-policies.md` and guide user to request permissions | | SDK not installed | `ModuleNotFoundError: No module named 'alibabacloud_sysom20231230'` | Prompt user to run `pip install alibabacloud_sysom20231230` | | Alert destination creation failure | SDK returns error | Check Webhook URL format and credential permissions | --- ## Reference Links | Reference | Description | |-----------|-------------| | [references/cli-installation-guide.md](references/cli-installation-guide.md) | Aliyun CLI installation and configuration guide | | [references/ram-policies.md](references/ram-policies.md) | RAM permission policy list | | [references/related-commands.md](references/related-commands.md) | Full CLI command list | | [references/verification-method.md](references/verification-method.md) | Success verification methods for each phase | | [references/diagnose-workflow.md](references/diagnose-workflow.md) | Detailed diagnosis workflow (Steps 4–9) | | [references/manage-and-alert-workflow.md](references/manage-and-alert-workflow.md) | Detailed enrollment and alert workflow (Steps 10–15) | | [references/acceptance-criteria.md](references/acceptance-criteria.md) | Test acceptance criteria |

path: references/acceptance-criteria.md
content: # Acceptance Criteria: alibabacloud-aes-sysom-os-diagnosis

**Scenario**: SysOM 深度诊断 — ECS 实例内核级性能诊断、纳管与告警配置
**Purpose**: Skill testing acceptance criteria

---

## Correct CLI Command Patterns

### 1. Product — verify product name exists

#### ✅ CORRECT
```bash
aliyun sysom invoke-diagnosis ...
aliyun ecs describe-cloud-assistant-status ...
```

#### ❌ INCORRECT
```bash
# 错误：产品名不存在
aliyun SysOM invoke-diagnosis ...
aliyun sysom InvokeDiagnosis ...
```

### 2. Command — verify action exists under the product

#### ✅ CORRECT
```bash
aliyun sysom invoke-diagnosis
aliyun sysom get-diagnosis-result
aliyun sysom initial-sysom --check-only false --source aes-skills
aliyun sysom check-instance-support
aliyun sysom install-agent
aliyun sysom install-agent-for-cluster
aliyun sysom list-instance-status
aliyun sysom list-clusters
aliyun sysom list-alert-items
aliyun sysom create-alert-strategy  # CLI 存在但不支持 destinations，需用 SDK 脚本
aliyun sysom uninstall-agent
```

#### ❌ INCORRECT
```bash
# 错误：使用传统 API 格式而非 plugin mode
aliyun sysom InvokeDiagnosis
aliyun sysom GetDiagnosisResult
aliyun sysom InstallAgent
```

### 3. Parameters — verify each parameter name exists

#### ✅ CORRECT
```bash
# invoke-diagnosis 参数（params key 使用 snake_case，必须包含 type）
aliyun sysom invoke-diagnosis --service-name ocd --channel ecs \
  --params '{"instance":"i-xxx","region":"cn-hangzhou","start_time":0,"end_time":0,"type":"ocd","ai_roadmap":true,"enable_sysom_link":false}'

# install-agent 参数
aliyun sysom install-agent --instances instance=i-xxx region=cn-hangzhou --install-type InstallAndUpgrade --agent-id xxx --agent-version 3.12.0-1

# describe-cloud-assistant-status 参数
aliyun ecs describe-cloud-assistant-status --biz-region-id cn-hangzhou --instance-id i-xxx

# list-instance-status 参数
aliyun sysom list-instance-status --instance i-xxx --biz-region cn-hangzhou

# list-clusters（不传 --cluster-id，获取全量后匹配）
aliyun sysom list-clusters

# create-alert-strategy（通过 SDK 脚本，CLI 不支持 destinations）
.sysom-sdk-venv/bin/python scripts/create-alert-strategy.py --name my-strategy --items "节点CPU使用率检测" --clusters "default" --destinations "1"
```

#### ❌ INCORRECT
```bash
# 错误：参数名不正确
aliyun sysom invoke-diagnosis --serviceName ocd  # 应为 --service-name
aliyun sysom install-agent --instanceId i-xxx    # 应为 --instances instance=i-xxx region=xxx
aliyun ecs describe-cloud-assistant-status --region-id cn-hangzhou  # 应为 --biz-region-id
aliyun sysom check-instance-support --region cn-hangzhou  # 应为 --biz-region

# 错误：invoke-diagnosis params 使用 camelCase 或缺少 type
aliyun sysom invoke-diagnosis --params '{"instanceId":"i-xxx","startTime":0}'  # key 应为 snake_case，且缺少 type

# 错误：list-clusters 传入 --cluster-id（应获取全量后匹配）
aliyun sysom list-clusters --cluster-id cxxx  # 应不传参数，获取全量列表后按 cluster_id 匹配
```

### 5. Alert Destination SDK Calls — verify SDK usage patterns

#### ✅ CORRECT
```bash
# SDK 环境初始化
bash scripts/setup-sdk.sh

# 创建告警联系人（通过脚本）
.sysom-sdk-venv/bin/python scripts/create-alert-destination.py 'https://oapi.dingtalk.com/robot/send?access_token=xxx'

# 创建告警联系人（指定名称）
.sysom-sdk-venv/bin/python scripts/create-alert-destination.py 'https://oapi.dingtalk.com/robot/send?access_token=xxx' '运维告警群'
```

#### ❌ INCORRECT
```bash
# 错误：尝试通过 CLI 调用告警联系人 API（不支持 CLI）
aliyun sysom create-alert-destination ...  # 此命令不存在

# 错误：未先运行 setup-sdk.sh 就直接调用脚本
python scripts/create-alert-destination.py '...'  # 应使用虚拟环境中的 python

# 错误：直接用 pip install 而非 setup-sdk.sh（不会创建虚拟环境）
pip install alibabacloud_sysom20231230
```

### 4. --user-agent flag present

#### ✅ CORRECT
```bash
aliyun sysom invoke-diagnosis --service-name ocd --channel ecs --params '...' --user-agent AlibabaCloud-Agent-Skills
```

#### ❌ INCORRECT
```bash
# 错误：缺少 --user-agent
aliyun sysom invoke-diagnosis --service-name ocd --channel ecs --params '...'
```

---

## Credential Verification Pattern

#### ✅ CORRECT
```bash
aliyun configure list --user-agent AlibabaCloud-Agent-Skills
```

#### ❌ INCORRECT
```bash
# 错误：打印 AK/SK 值
echo $ALIBABA_CLOUD_ACCESS_KEY_ID

# 错误：在命令行中传入明文凭据
aliyun configure set --access-key-id LTAI5tXXXXXX --access-key-secret 8dXXXXXXXX
```

---

## Parameter Handling

#### ✅ CORRECT
- 所有用户可定制参数（RegionId、instance_id 等）在执行前向用户确认
- `ocd_description` 使用纯英文关键词
- `--instances` 使用结构化格式 `instance=<id> region=<region>`

#### ❌ INCORRECT
- 假设 region 为 `cn-hangzhou` 而不询问用户
- 将中文直接传入 `ocd_description`
- `--instances` 使用 JSON 数组格式而非结构化格式

---

## CLI Plugin Mode Format

#### ✅ CORRECT
```bash
aliyun sysom invoke-diagnosis    # 小写 + 连字符
aliyun sysom get-diagnosis-result
aliyun sysom install-agent
```

#### ❌ INCORRECT
```bash
aliyun sysom InvokeDiagnosis     # 传统 API 格式
aliyun sysom GetDiagnosisResult
aliyun sysom InstallAgent
```


path: references/cli-installation-guide.md
content: # Aliyun CLI Installation & Configuration Guide

Complete guide for installing and configuring Aliyun CLI.

> **Aliyun CLI 3.3.1+**: Supports installing and using all published Alibaba Cloud product plugins. Make sure to upgrade to 3.3.1 or later for full plugin ecosystem coverage.

## Installation

### macOS

**Using Homebrew (Recommended)**
```bash
brew install aliyun-cli
# Upgrade to latest
brew upgrade aliyun-cli

# Verify version (>= 3.3.1)
aliyun version
```

**Using Binary**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-macosx-latest-amd64.tgz

# Extract
tar -xzf aliyun-cli-macosx-latest-amd64.tgz

# Move to PATH
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

### Linux

**Debian/Ubuntu**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

**CentOS/RHEL**
```bash
# Download
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-amd64.tgz
sudo mv aliyun /usr/local/bin/

# Verify
aliyun version
```

**ARM64 Architecture**
```bash
# Download ARM64 version
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-arm64.tgz

# Extract and install
tar -xzf aliyun-cli-linux-latest-arm64.tgz
sudo mv aliyun /usr/local/bin/
```

### Windows

**Using Binary**
1. Download from: https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip
2. Extract the ZIP file
3. Add the directory to your PATH environment variable
4. Open new Command Prompt or PowerShell
5. Verify: `aliyun version`

**Using PowerShell**
```powershell
# Download
Invoke-WebRequest -Uri "https://aliyuncli.alicdn.com/aliyun-cli-windows-latest-amd64.zip" -OutFile "aliyun-cli.zip"

# Extract
Expand-Archive -Path aliyun-cli.zip -DestinationPath C:\aliyun-cli

# Add to PATH (requires admin privileges)
$env:Path += ";C:\aliyun-cli"
[Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine)

# Verify
aliyun version
```

## Configuration

### Quick Start

```bash
aliyun configure set \
  --mode AK \
  --access-key-id <your-access-key-id> \
  --access-key-secret <your-access-key-secret> \
  --region cn-hangzhou
```

All `aliyun configure` commands support non-interactive flags, which is the recommended approach —
it works in scripts, CI/CD pipelines, and agent-driven automation without hanging on stdin prompts.

**Where to Get Access Keys**

1. Log in to Aliyun Console: https://ram.console.aliyun.com/
2. Navigate to: AccessKey Management
3. Create a new AccessKey pair
4. Save the secret immediately — it's only shown once

### Configuration Modes

Aliyun CLI supports 6 authentication modes. All examples below use non-interactive flags.

#### 1. AK Mode (Access Key)

Most common mode for personal accounts and scripts.

```bash
aliyun configure set \
  --mode AK \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --region cn-hangzhou
```

Configuration is stored in `~/.aliyun/config.json`:

```json
{
  "current": "default",
  "profiles": [
    {
      "name": "default",
      "mode": "AK",
      "access_key_id": "LTAI5tXXXXXXXX",
      "access_key_secret": "8dXXXXXXXXXXXXXXXXXXXXXXXX",
      "region_id": "cn-hangzhou",
      "output_format": "json",
      "language": "en"
    }
  ]
}
```

#### 2. StsToken Mode (Temporary Credentials)

For short-lived access (tokens expire in 1-12 hours).

```bash
aliyun configure set \
  --mode StsToken \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --sts-token v1.0:XXXXXXXXXXXXXXXX \
  --region cn-hangzhou
```

Use cases: CI/CD pipelines, temporary access for external contractors, cross-account access.

#### 3. RamRoleArn Mode (Assume RAM Role)

Assume a RAM role for elevated or cross-account access.

```bash
aliyun configure set \
  --mode RamRoleArn \
  --access-key-id LTAI5tXXXXXXXX \
  --access-key-secret 8dXXXXXXXXXXXXXXXXXXXXXXXX \
  --ram-role-arn acs:ram::123456789012:role/AdminRole \
  --role-session-name my-session \
  --region cn-hangzhou
```

Use cases: cross-account resource access, temporary elevated privileges, role-based access control.

#### 4. EcsRamRole Mode (ECS Instance RAM Role)

Use the RAM role attached to an ECS instance — no credentials needed.

```bash
aliyun configure set \
  --mode EcsRamRole \
  --ram-role-name MyEcsRole \
  --region cn-hangzhou
```

Requirements: must be running on an ECS instance with a RAM role attached.

Use cases: scripts and automation running on ECS instances.

#### 5. RsaKeyPair Mode (RSA Key Pair)

Use RSA key pair for authentication (generate key pair in Aliyun Console first).

```bash
aliyun configure set \
  --mode RsaKeyPair \
  --private-key /path/to/private-key.pem \
  --key-pair-name my-key-pair \
  --region cn-hangzhou
```

#### 6. RamRoleArnWithEcs Mode (ECS + RAM Role)

Combine ECS instance role with RAM role assumption for cross-account access from ECS.

```bash
aliyun configure set \
  --mode RamRoleArnWithEcs \
  --ram-role-name MyEcsRole \
  --ram-role-arn acs:ram::123456789012:role/TargetRole \
  --role-session-name my-session \
  --region cn-hangzhou
```

### Environment Variables

**Highest priority** - overrides config file

**Access Key Mode**
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou
```

**STS Token Mode**
```bash
export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
export ALIBABA_CLOUD_SECURITY_TOKEN=your_sts_token
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou
```

**ECS RAM Role Mode**
```bash
export ALIBABA_CLOUD_ECS_METADATA=role_name
```

**Use Case**:
- CI/CD pipelines
- Docker containers
- Temporary credential override

### Managing Multiple Profiles

**Create Named Profiles**

```bash
aliyun configure set --profile projectA \
  --mode AK \
  --access-key-id LTAI5tAAAAAAAA \
  --access-key-secret 8dAAAAAAAAAAAAAAAAAAAAAAAA \
  --region cn-hangzhou

aliyun configure set --profile projectB \
  --mode AK \
  --access-key-id LTAI5tBBBBBBBB \
  --access-key-secret 8dBBBBBBBBBBBBBBBBBBBBBBBB \
  --region cn-shanghai
```

**Use Specific Profile**

```bash
aliyun ecs describe-instances --profile projectA

export ALIBABA_CLOUD_PROFILE=projectA
aliyun ecs describe-instances   # Uses projectA
```

**List and Switch Profiles**

```bash
aliyun configure list                      # List all profiles
aliyun configure set --current projectA    # Switch default profile
```

### Credential Priority

Credentials are loaded in this order (first found wins):

1. **Command-line flag**: `--profile <name>`
2. **Environment variable**: `ALIBABA_CLOUD_PROFILE`
3. **Environment credentials**: `ALIBABA_CLOUD_ACCESS_KEY_ID`, etc.
4. **Configuration file**: `~/.aliyun/config.json` (current profile)
5. **ECS Instance RAM Role**: If running on ECS with attached role

## Verification

### Test Authentication

```bash
# Basic test - list regions
aliyun ecs describe-regions

# Expected output: JSON array of regions
```

**If successful**, you'll see:
```json
{
  "Regions": {
    "Region": [
      {
        "RegionId": "cn-hangzhou",
        "RegionEndpoint": "ecs.cn-hangzhou.aliyuncs.com",
        "LocalName": "华东 1（杭州）"
      },
      ...
    ]
  },
  "RequestId": "..."
}
```

**If failed**, you'll see error messages:
- `InvalidAccessKeyId.NotFound` - Wrong Access Key ID
- `SignatureDoesNotMatch` - Wrong Access Key Secret
- `InvalidSecurityToken.Expired` - STS token expired (for StsToken mode)
- `Forbidden.RAM` - Insufficient permissions

### Debug Configuration

```bash
# Show current configuration
aliyun configure get

# Test with debug logging
aliyun ecs describe-regions --log-level=debug

# Check credential provider
aliyun configure get mode
```

## Security Best Practices

### 1. Use RAM Users (Not Root Account)

❌ **Don't**: Use Aliyun root account credentials
✅ **Do**: Create RAM users with specific permissions

```bash
# Create RAM user in console
# Attach only necessary policies
# Use RAM user's access keys
```

### 2. Principle of Least Privilege

Grant only the minimum permissions needed:

```bash
# Example: Read-only ECS access
# Attach policy: AliyunECSReadOnlyAccess
```

### 3. Rotate Access Keys Regularly

```bash
# Create new access key in RAM Console, then update configuration
aliyun configure set --access-key-id NEW_KEY --access-key-secret NEW_SECRET
# Delete old access key from console
```

### 4. Use STS Tokens for Temporary Access

```bash
aliyun configure set --mode StsToken \
  --access-key-id XXXX --access-key-secret XXXX \
  --sts-token XXXX --region cn-hangzhou
```

### 5. Use ECS RAM Roles When Possible

```bash
aliyun configure set --mode EcsRamRole --ram-role-name MyRole --region cn-hangzhou
```

### 6. Never Commit Credentials

```bash
# Add to .gitignore
echo "~/.aliyun/config.json" >> .gitignore

# Use environment variables in CI/CD instead
```

### 7. Secure Config File

```bash
# Restrict permissions
chmod 600 ~/.aliyun/config.json
```

## Troubleshooting

### Issue: Command Not Found

```bash
# Check installation
which aliyun

# Check PATH
echo $PATH

# Reinstall or add to PATH
```

### Issue: Authentication Failed

```bash
# Verify configuration
aliyun configure get

# Test with debug
aliyun ecs describe-regions --log-level=debug

# Check credentials in console
# Verify access key is active
```

### Issue: Permission Denied

```bash
# Error: Forbidden.RAM

# Check RAM user permissions
# Attach necessary policies in RAM console
# Example: AliyunECSFullAccess for ECS operations
```

### Issue: STS Token Expired

```bash
# Error: InvalidSecurityToken.Expired

# Reconfigure with new token
aliyun configure set --mode StsToken \
  --access-key-id XXXX --access-key-secret XXXX \
  --sts-token NEW_TOKEN --region cn-hangzhou
```

### Issue: Wrong Region

```bash
# Some resources may not exist in the specified region

# Check available regions
aliyun ecs describe-regions

# Update default region
aliyun configure set region cn-shanghai
```

## Advanced Configuration

### Custom Endpoint

```bash
# Use custom or private endpoint
export ALIBABA_CLOUD_ECS_ENDPOINT=ecs-vpc.cn-hangzhou.aliyuncs.com
```

### Proxy Settings

```bash
# HTTP proxy
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

# No proxy for specific domains
export NO_PROXY=localhost,127.0.0.1,.aliyuncs.com
```

### Timeout Settings

```bash
# Connection timeout (default: 10s)
export ALIBABA_CLOUD_CONNECT_TIMEOUT=30

# Read timeout (default: 10s)
export ALIBABA_CLOUD_READ_TIMEOUT=30
```

## Next Steps

After installation and configuration:

1. **Install plugins** for services you need (v3.3.1+ supports all published product plugins):
   ```bash
   aliyun plugin install --names ecs vpc rds

   # List all available plugins
   aliyun plugin list-remote
   ```

2. **Explore commands**:
   ```bash
   aliyun ecs --help
   aliyun fc --help
   ```

3. **Read documentation**:
   - [Command Syntax Guide](./command-syntax.md)
   - [Global Flags Reference](./global-flags.md)
   - [Common Scenarios](./common-scenarios.md)

## References

- Official Documentation: https://help.aliyun.com/zh/cli/
- RAM Console: https://ram.console.aliyun.com/
- Access Key Management: https://ram.console.aliyun.com/manage/ak
- Plugin Repository: https://github.com/aliyun/aliyun-cli


path: references/diagnose-workflow.md
content: # Diagnosis Execution Detailed Workflow

This document contains the detailed execution steps for SysOM deep diagnosis (Steps 4–9), referenced from the Core Workflow in SKILL.md.

All `aliyun` CLI commands **MUST** include `--user-agent AlibabaCloud-Agent-Skills`.

---

## Step 4 — Ambiguous Problem Clarification (Inversion Gate)

Before entering the diagnosis pipeline, **the following two required parameters MUST be confirmed**. If the user's question does not include this information, you must ask the user — **do NOT guess or use default values**.

### Required Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `region` | Region of the ECS instance | `cn-hangzhou`, `cn-beijing`, `cn-shanghai` |
| `instance_id` | ECS instance ID | `i-bp1xxxxxxxxxxxxxxx` |

### Clarification Flow

**4a. Check if the user's input already contains region and instance_id**

Extract these two parameters from the user's problem description. Common expressions include:
- "instance i-bp1xxx in Hangzhou" (region=cn-hangzhou, instance_id=i-bp1xxx)
- "instance i-bp1xxx in Beijing" (region=cn-beijing, instance_id=i-bp1xxx)

**4b. If either parameter is missing, ask the user**

> 🔍 To perform SysOM deep diagnosis, I need to confirm the following:
>
> - **Instance ID**: Please provide the ECS instance ID (format: `i-bp1xxxxxxxx`)
> - **Region**: The Alibaba Cloud region where the instance is located (e.g., `cn-hangzhou`, `cn-beijing`, `cn-shanghai`)

**4c. Also extract optional context**

- `ocd_description`: The problem symptoms described by the user
- **Time range inference** (see below)
- `uid`: If the user mentioned an account ID

**⚠️ CRITICAL: Time Inference and Historical Diagnosis Recommendation**

When the user's description contains **any temporal reference** — even vague ones — you **MUST** proactively infer the time range and recommend historical diagnosis mode. Do NOT silently default to real-time diagnosis when the problem clearly occurred in the past.

**Time inference examples:**

| User Description | Inferred Action |
|-----------------|----------------|
| "The server crashed this morning" | Ask: "When exactly did the crash happen this morning? I'll use historical diagnosis to analyze that time window." |
| "Yesterday afternoon there was high CPU" | Ask: "Around what time yesterday afternoon? I'll run historical diagnosis for that period." |
| "It went down around 3am" | Convert to Unix timestamps for today's 3am (±30min buffer), recommend historical diagnosis |
| "The instance rebooted unexpectedly last night" | Ask for approximate time, recommend historical diagnosis |
| "There's been high load for the past 2 hours" | Calculate start_time = now - 2h, recommend historical diagnosis |
| "The server is slow right now" | No time inference needed, use real-time diagnosis (default) |

**Rules:**
1. If the user mentions a **past event** (crash, reboot, spike that already happened), you **MUST** ask for the specific time and recommend historical diagnosis
2. If the user describes an **ongoing issue** ("right now", "currently"), use real-time diagnosis
3. When asking for time, also provide the option: "Or would you prefer a real-time diagnosis to check the current state?"
4. Convert natural language time references to Unix timestamps using the current time as reference

**⚠️ IMPORTANT: `ocd_description` MUST be in English only**

The SysOM API restricts `ocd_description` to only `[a-zA-Z0-9_.~-]` characters. You must translate the user's problem description into short English keywords connected by underscores.

| User Description | ocd_description Value |
|-----------------|----------------------|
| High load / abnormal system load | `high_load` |
| CPU spike / high CPU usage | `high_cpu` |
| Memory leak / out of memory | `memory_leak` |
| High IO latency / slow disk | `io_latency` |
| Network packet loss / network jitter | `network_packet_loss` |
| Crash / kernel panic | `kernel_panic` |
| OOM / process killed | `oom_killed` |
| Overall server health check | `health_check` |

---

## Step 5 — Cloud Assistant Online Check

```bash
aliyun ecs describe-cloud-assistant-status \
  --biz-region-id <region> \
  --instance-id <instance_id> \
  --user-agent AlibabaCloud-Agent-Skills
```

Check the `InstanceCloudAssistantStatusSet.InstanceCloudAssistantStatus` array in the returned JSON, find the `CloudAssistantStatus` field for the target instance:

- `"true"` → Cloud Assistant is online, proceed to Step 6
- `"false"` → Inform user that Cloud Assistant is offline, terminate the pipeline
- API call failure → Ask user whether to continue

---

## Step 6 — SysOM Role Initialization

```bash
aliyun sysom initial-sysom --check-only false --source aes-skills --user-agent AlibabaCloud-Agent-Skills
```

Ensures the SysOM service role has been created. This step is idempotent and can be executed repeatedly.

---

## Step 7 — Instance Support Check

```bash
aliyun sysom check-instance-support \
  --instances <instance_id> \
  --biz-region <region> \
  --user-agent AlibabaCloud-Agent-Skills
```

Verify the target instance meets:
- Operating system is Linux
- Kernel version is compatible with SysOM diagnosis

If the instance is not supported, a clear failure reason is returned — suggest falling back to standard diagnosis.

---

## Step 8 — Invoke Diagnosis and Poll Results

### 8a. Diagnosis Mode Decision

Based on the user's input parameter combination, determine the diagnosis mode:

```
if enable_diagnosis == true:
    mode = real-time diagnosis    # enable_diagnosis has highest priority, force start_time to 0
elif start_time != 0:
    mode = historical diagnosis   # time range specified, retrospective analysis
else:
    mode = real-time diagnosis    # default
```

#### Optional Parameters and Defaults

| Parameter | Default | Description |
|-----------|---------|-------------|
| `start_time` | `0` | Diagnosis start timestamp (Unix seconds) |
| `end_time` | `0` | Diagnosis end timestamp (Unix seconds) |
| `enable_diagnosis` | `false` | Force real-time diagnosis |
| `ocd_description` | `""` | Problem description for intent recognition (English only) |
| `uid` | `None` | Account ID owning the instance |
| `skip_support_check` | `false` | Skip instance support check (speeds up workflow) |

### 8b. Build params JSON

Use **snake_case** keys (consistent with SDK). Required base fields (**ALL must be included**):

```json
{
  "instance": "<instance_id>",
  "region": "<region>",
  "start_time": 0,
  "end_time": 0,
  "type": "ocd",
  "ai_roadmap": true,
  "enable_sysom_link": false
}
```

> **⚠️ Anti-confusion Warning: `"type": "ocd"` is a REQUIRED field inside the params JSON — do NOT omit it!**
>
> `--service-name ocd` (CLI argument) and `"type": "ocd"` (params JSON field) are **two different levels of parameters**, both are mandatory:
> - `--service-name ocd` → tells CLI which diagnosis service endpoint to call
> - `"type": "ocd"` → tells the diagnosis engine which diagnosis type to execute internally
>
> **Do NOT omit `"type": "ocd"` from params just because `--service-name` already specifies `ocd`!**

Conditional fields (add to JSON only when non-empty):
- `"ocd_description": "<english_keywords>"` — add when user's problem description is not empty
- `"uid": <integer>` — add when user provides an account ID

**Impact of diagnosis mode on params**:
- **Real-time**: `start_time: 0`, `end_time: 0`
- **Historical**: `start_time: <unix_ts>`, `end_time: <unix_ts>`
- **Forced real-time** (`enable_diagnosis=true`): force `start_time` to `0` even if user provided a value

### 8c. Invoke Diagnosis

```bash
aliyun sysom invoke-diagnosis \
  --service-name ocd \
  --channel ecs \
  --params '{"instance":"<instance_id>","region":"<region>","start_time":<start_time>,"end_time":<end_time>,"type":"ocd","ai_roadmap":true,"enable_sysom_link":false,"ocd_description":"<ocd_description>"}' \
  --user-agent AlibabaCloud-Agent-Skills
```

Extract `task_id` from the response.

**Special handling**: If `Sysom.TaskInProgress` error is returned, it means a diagnosis task is already in progress. Extract the existing `task_id` from the error message (regex match `ocd(<task_id>)`) and proceed directly to polling.

### 8d. Poll Diagnosis Results

Interval: 10 seconds, max 60 attempts:

```bash
aliyun sysom get-diagnosis-result \
  --task-id <task_id> \
  --user-agent AlibabaCloud-Agent-Skills
```

Check the `status` field in the response:
- `Ready` / `Running` → continue polling
- `Success` → diagnosis complete, proceed to Step 9
- `Fail` → diagnosis failed, inform the user

> **⛔ Behavioral Constraints During Polling (MUST OBEY):**
>
> During polling while waiting for diagnosis results, the following actions are **STRICTLY FORBIDDEN (both executing and suggesting to the user)**:
> 1. **FORBIDDEN** to invoke Cloud Assistant to execute commands on the instance (e.g., `top`, `vmstat`, `dmesg`, `iostat`)
> 2. **FORBIDDEN** to call ECS monitoring, CloudMonitor, or other APIs
> 3. **FORBIDDEN** to attempt "alternative diagnosis methods" or initiate new diagnosis tasks
> 4. **FORBIDDEN** to call any command not listed in this skill's [Command Tables]
> 5. **FORBIDDEN** to suggest any of the above actions to the user as "alternatives" or "fallback options"
>
> **The ONLY permitted action**: continue calling `aliyun sysom get-diagnosis-result` to poll, or stop after timeout.
>
> **Timeout handling**: If still incomplete after 60 polling attempts, you **MUST and can ONLY** output the following template, then stop:
>
> ```
> ⏳ SysOM diagnosis task timed out
> - Task ID: <task_id>
> - Current status: <status>
> - Suggestion: Please continue waiting for the diagnosis to complete.
> ```
>
> **FORBIDDEN to add any "alternative diagnosis method" suggestions in the timeout output. Actions that cannot be performed must not be suggested.**

---

## Step 9 — Result Parsing and Output

### Key Field Interpretation

| Field | Meaning | How Agent Should Use It |
|-------|---------|------------------------|
| `summary.overall_status` | Overall status (Info/Warn/Critical) | Determine problem severity |
| `summary.root_cause` | SysOM root cause analysis | Kernel-level root cause evidence |
| `summary.suggestions` | Remediation suggestion list | Incorporate directly into recommendations |
| `issues[]` | Issues found by each sub-diagnostic item | Analyze item by item to locate specific subsystem |
| `diagnose_mode` | Diagnosis mode identifier | Distinguish real-time vs. historical diagnosis |

---

## SysOM Diagnosis Capability Coverage

| Subsystem | Diagnostic Tool | Diagnostic Content |
|-----------|----------------|-------------------|
| CPU | monitor | User-space/kernel-space CPU usage analysis, CPU saturation detection |
| Memory | memgraph | Memory panoramic analysis, memory leak detection, OOM diagnosis |
| IO | iofsstat, iodiagnose | IO traffic attribution analysis, IO latency diagnosis, iowait analysis |
| Network | packetdrop, netjitter | Packet loss diagnosis, network jitter analysis |
| Load | loadtask | System load anomaly analysis, load jitter diagnosis |
| Scheduling | delay | CPU scheduling jitter, scheduling latency diagnosis |
| Crash | vmcore | Crash cause analysis, kernel panic diagnosis |
| Health Score | healthy_score | Overall server health scoring |


path: references/manage-and-alert-workflow.md
content: # Enrollment and Alert Detailed Workflow

This document contains the detailed execution steps for SysOM instance enrollment and alert configuration (Steps 10–15).

All `aliyun` CLI commands **MUST** include `--user-agent AlibabaCloud-Agent-Skills`.

---

## Enrollment Recommendation Phase (Inversion + Pipeline Pattern)

After diagnosis is complete, **proactively recommend instance enrollment to the user**. After enrollment, SysOM will continuously monitor instance health. When performance issues occur, it will automatically trigger diagnosis and push reports to DingTalk group bots, enabling 24/7 unattended intelligent operations.

### Step 10 — Enrollment Recommendation and Intent Collection (Inversion Double Gate)

This step contains two strictly separated gates that **MUST be executed in order — merging, skipping, or simplifying is FORBIDDEN**.

#### Step 10A — Prominent Enrollment Recommendation (First Gate)

**⚠️ Mandatory Rule: After presenting diagnosis results, you MUST immediately output the following recommendation content verbatim. Do NOT abbreviate, omit, or rephrase in your own words.**

You must output the following complete content (replace `<instance_id>` with the actual instance ID):

---

> ## 🔔 Recommendation: Enroll Instance for 24/7 Automated Diagnosis
>
> The diagnosis just performed was a one-time manual operation. If you want SysOM to **continuously protect** this instance, we recommend **instance enrollment**.
>
> ### After enrollment, you will get:
>
> - 🔍 **Automated Diagnosis**: When the instance experiences performance issues like CPU spikes, memory leaks, or IO latency, SysOM will **automatically trigger deep diagnosis** without manual intervention
> - 📲 **DingTalk Alerts**: Diagnosis reports will be **automatically pushed to DingTalk group bots**, notifying the ops team immediately
> - 🛡️ **Continuous Monitoring**: 24/7 uninterrupted protection, shifting from "investigate after problems occur" to "automatically told the root cause when problems occur"
>
> **Would you like to enroll instance `<instance_id>`?**

---

**After outputting the above, STOP. Wait for user reply.**

- User **declines** → end the pipeline
- User **agrees** → proceed to Step 10B

**⚠️ Do NOT ask about enrollment method in Step 10A.**

#### Step 10B — Ask Enrollment Method (Second Gate)

**Only execute this step after the user explicitly agrees to enrollment in Step 10A.**

You must output the following complete content (replace `<instance_id>` and `<region>` with actual values):

---

> ### Please choose an enrollment method
>
> **A. Enroll current instance only**
> Only enroll the instance just diagnosed: `<instance_id>` (`<region>`)
>
> **B. Enroll ACK cluster**
> If this instance belongs to an ACK cluster, you can enroll **all nodes** in the cluster with one click.
> Newly added nodes will be automatically enrolled — no manual action needed.
> 👉 Please provide the **ACK Cluster ID** (e.g., `c9d7f3fc3d42********c1100ffb19d`)
>
> **C. Enroll multiple specified instances**
> Batch enroll multiple instances.
> 👉 Please provide the instance list in the format `InstanceID:Region`, separated by spaces
> Example: `i-xxx:cn-beijing i-yyy:cn-hangzhou`
>
> Please choose A / B / C, or tell me your requirements directly.

---

**After outputting the above, STOP. Wait for user reply.**

#### Intent Parsing Rules

| User Reply | Enrollment Mode | Parameters to Collect |
|-----------|----------------|----------------------|
| Choose A / enroll current instance / agree directly | Single instance | No additional parameters needed, reuse instance_id and region from Step 4 |
| Choose B / provided a cluster ID | Cluster | `cluster_id` (ask if not provided) |
| Choose C / provided multiple instances | Multi-instance | Parse the instance list provided by user |

---

### Step 11 — Execute Enrollment

#### Enroll Single or Multiple Instances

```bash
aliyun sysom install-agent \
  --instances instance=<instance_id_1> region=<region_1> \
  --instances instance=<instance_id_2> region=<region_2> \
  --install-type InstallAndUpgrade \
  --agent-id 74a86327-3170-412c-8e67-da3389ec56a9 \
  --agent-version 3.12.0-1 \
  --user-agent AlibabaCloud-Agent-Skills
```

#### Enroll ACK Cluster

```bash
aliyun sysom install-agent-for-cluster \
  --cluster-id <cluster_id> \
  --agent-id 74a86327-3170-412c-8e67-da3389ec56a9 \
  --agent-version 3.12.0-1 \
  --config-id 8gj86wrt7-3170-412c-8e67-da3389ecg6a9 \
  --user-agent AlibabaCloud-Agent-Skills
```

#### install-type Enum Values

| Value | Description |
|-------|-------------|
| `InstallAndUpgrade` | Install if not present, upgrade if present (default) |
| `OnlyInstallNotHasAgent` | Install if not present, skip if present |
| `OnlyUpgradeHasAgent` | Skip if not present, upgrade if present |
| `OnlyInstallWithoutStart` | Install component only, do not start service |

> **Note**: For cluster enrollment, the initial enrollment installs the agent on all current ECS instances in the cluster (first batch limited to 50 if exceeding 50 instances). Newly added ECS instances will be automatically enrolled.

---

### Step 12 — Enrollment Status Confirmation and Result Output

#### Instance Mode — Poll Instance Status (interval: 10s, max: 60 attempts)

```bash
aliyun sysom list-instance-status \
  --instance <instance_id> \
  --biz-region <region> \
  --user-agent AlibabaCloud-Agent-Skills
```

#### Cluster Mode — Poll Cluster Status

Get the full cluster list (**do NOT pass `--cluster-id`**), then match the target cluster by `cluster_id` field:

```bash
aliyun sysom list-clusters \
  --user-agent AlibabaCloud-Agent-Skills
```

From the returned cluster list, iterate through each cluster object, find the entry where `cluster_id` matches the target, and check its `cluster_status` field. Also record the `name` field for later use in create-alert-strategy.

#### Enrollment Status Reference

| Status | Meaning | Icon |
|--------|---------|------|
| `installing` / `Installing` | Installing | ⏳ |
| `running` / `Running` | Enrollment successful | ✅ |
| `failed` / `Offline` | Failed/Abnormal | ❌ |
| `stopped` | Agent stopped | ⏹️ |

#### Result Display

- **All successful** → Inform user that all instances are enrolled, SysOM will continuously monitor
- **Partially failed** → List successful and failed instances, suggest checking failed ones
- **All failed** → Suggest checking network connectivity, RAM permissions, OS compatibility

---

## Alert Configuration Phase (Pipeline Pattern)

After enrollment is complete, **proceed directly to alert configuration**: first create alert destination (collect Webhook), then select alert items, and finally create alert strategy.

### Step 13 — Collect DingTalk Webhook and Create Alert Destination (Inversion Gate + SDK Call)

**⚠️ Mandatory Rule: After successful enrollment, you MUST immediately collect the DingTalk bot Webhook URL from the user. Do NOT skip this step.**

Alert destinations are used to push SysOM alerts to DingTalk group bots. This feature is **NOT supported by CLI** — use Python SDK scripts under `scripts/`.

> **⚠️ SDK Prerequisites**
>
> Before executing this step, run `scripts/setup-sdk.sh` to initialize the SDK environment (checks Python >= 3.8, creates virtual environment, installs SDK):
> ```bash
> bash scripts/setup-sdk.sh
> ```

#### Step 13a — Collect Webhook URL from User

You must output the following complete content:

---

> 📲 Please provide the DingTalk group bot **Webhook URL** for receiving alert notifications.
> Format: `https://oapi.dingtalk.com/robot/send?access_token=xxx`
>
> 💡 How to get it: DingTalk Group Settings → Bot Management → Add Bot → Custom Bot → Optional keyword: alert → Copy Webhook URL

---

**After outputting the above, STOP. Wait for user reply.**

#### Step 13b — Create Alert Destination

After the user provides the Webhook URL, **immediately create the alert destination via script** — no further confirmation needed:

```bash
.sysom-sdk-venv/bin/python scripts/create-alert-destination.py '<user-provided-webhook-url>'
```

Optionally specify a destination name:

```bash
.sysom-sdk-venv/bin/python scripts/create-alert-destination.py '<webhook-url>' '<destination-name>'
```

> **⚠️ You MUST use the virtual environment Python to execute scripts**
>
> **FORBIDDEN** to use `python3` or `python` directly — system Python dependencies may be incompatible, causing signature verification failures.

On success, **stdout outputs `destination_id` (a pure number)**, detailed info is output to stderr.

**Result handling**:

- **Success** → Display destination ID and name, inform user of successful creation, record `destination_id` for Step 15, **immediately proceed to Step 14**
- **Failure** → Display error message, suggest checking Webhook URL format and RAM permissions

---

### Step 14 — Alert Item Selection (Inversion Gate)

**⚠️ Mandatory Rule: After successful alert destination creation, you MUST immediately display the alert items list. Do NOT skip this step.**

**14a. Get Available Alert Items List**

```bash
aliyun sysom list-alert-items --user-agent AlibabaCloud-Agent-Skills
```

**14b. Display Alert Items List to User**

Display the API-returned alert items categorized, each with a number. Format:

---

> ## 🔔 Please select alert items to enable
>
> Enter numbers, separated by spaces:
>
> **Quick selection**: `all` = select all | `node-all` = all NODE items | `pod-all` = all POD items
>
> **【NODE Saturation】**
>   1. Node CPU Usage Detection
>   2. Node Kernel CPU Usage Detection
>   ... (populate based on actual API response)

---

**After outputting, STOP. Wait for user reply.**

#### User Input Parsing Rules

| User Input | Parsing Method |
|-----------|---------------|
| `all` | Select all alert items |
| `node-all` | Select all NODE category items |
| `pod-all` | Select all POD category items |
| `1 2 4 11 12 21` | Select by number |
| `node-all 22 23` | Mixed usage |

---

### Step 15 — Create Alert Strategy

After the user selects alert items, **create the alert strategy directly** with `destinations` set to the destination ID from Step 13.

**15a. Determine clusters Parameter**

| Enrollment Mode | clusters Value |
|----------------|---------------|
| Instance mode (Step 10 chose A or C) | `["default"]` |
| Cluster mode (Step 10 chose B) | `["<cluster_name>"]` (note: name, NOT ID) |

**15b. Execute Creation (SDK Call)**

> **⚠️ CLI does NOT support the `destinations` parameter — you MUST use the SDK script to create alert strategies.**

```bash
.sysom-sdk-venv/bin/python scripts/create-alert-strategy.py \
  --name "aliyun-aes-skills-create-<YYYYMMDDHHmm>" \
  --items "<alert_item_1>,<alert_item_2>" \
  --clusters "<clusters_value>" \
  --destinations "<destination_id>"
```

Parameter reference:

| Parameter | Description | Example |
|-----------|-------------|---------|
| `--name` | Strategy name | `aliyun-aes-skills-create-202604151900` |
| `--items` | Alert item names, comma-separated | `Node CPU Usage Detection,Node Memory Usage Detection` |
| `--clusters` | Clusters, comma-separated (use `default` for instance mode) | `default` |
| `--destinations` | Alert destination IDs, comma-separated | `1,2` |
| `--k8s-label` | Enable k8s labels (optional) | Defaults to false if omitted |

> **⚠️ You MUST use `.sysom-sdk-venv/bin/python` to execute scripts** — using system `python3` is FORBIDDEN.

On success, **stdout outputs the strategy name**, detailed info is output to stderr.

**15c. Display Results**

- **Success** → Display strategy name, alert item count, cluster, status, associated alert destinations; inform user that alerts will be pushed to DingTalk via SysOM
- **Failure** → Display error message, suggest checking RAM permissions, enrollment status, network connectivity

---

### Alert Destination Management (On Demand)

Users can manage existing alert destinations via SDK as needed. The following operations all use the Python SDK — **NOT supported by CLI**.

#### Get Alert Destination Details

```python
from alibabacloud_sysom20231230 import models

request = models.GetAlertDestinationRequest(id=<destination_id>)
response = client.get_alert_destination(request)
```

#### Update Alert Destination

Only fill in the fields that need to be modified:

```python
from alibabacloud_sysom20231230 import models

request = models.UpdateAlertDestinationRequest(
    id='<destination_id>',
    name='<new_name>',                         # optional
    target='dingtalk',                         # optional
    params=models.UpdateAlertDestinationRequestParams(
        webhook='<new_webhook_url>'            # optional
    )
)
response = client.update_alert_destination(request)
```

#### Delete Alert Destination

```python
from alibabacloud_sysom20231230 import models

request = models.DeleteAlertDestinationRequest(id=<destination_id>)
response = client.delete_alert_destination(request)
```

#### List All Alert Destinations

Filter by `name` parameter (optional); omit to return all:

```python
from alibabacloud_sysom20231230 import models

request = models.ListAlertDestinationsRequest(name='<optional_filter_name>')
response = client.list_alert_destinations(request)
```


path: references/ram-policies.md
content: # RAM Policies: alibabacloud-aes-sysom-os-diagnosis

This document lists all APIs and their corresponding RAM permissions used by the SysOM deep diagnosis skill.

---

## SysOM Permissions

| API | RAM Action | Description |
|-----|-----------|-------------|
| InitialSysom | `sysom:InitialSysom` | Initialize SysOM role authorization |
| CheckInstanceSupport | `sysom:CheckInstanceSupport` | Check if instance supports SysOM diagnosis |
| InvokeDiagnosis | `sysom:InvokeDiagnosis` | Invoke intelligent diagnosis |
| GetDiagnosisResult | `sysom:GetDiagnosisResult` | Get diagnosis result |
| InstallAgent | `sysom:InstallAgent` | Enroll instance (install Agent) |
| InstallAgentForCluster | `sysom:InstallAgentForCluster` | Enroll ACK cluster |
| ListInstanceStatus | `sysom:ListInstanceStatus` | Query instance enrollment status |
| ListClusters | `sysom:ListClusters` | Query cluster enrollment status |
| ListAlertItems | `sysom:ListAlertItems` | Get available alert items list |
| CreateAlertStrategy | `sysom:CreateAlertStrategy` | Create alert strategy |
| CreateAlertDestination | `sysom:CreateAlertDestination` | Create alert destination (SDK call) |
| UpdateAlertDestination | `sysom:UpdateAlertDestination` | Update alert destination (SDK call) |
| DeleteAlertDestination | `sysom:DeleteAlertDestination` | Delete alert destination (SDK call) |
| GetAlertDestination | `sysom:GetAlertDestination` | Get alert destination details (SDK call) |
| ListAlertDestinations | `sysom:ListAlertDestinations` | List alert destinations (SDK call) |

## ECS Permissions

| API | RAM Action | Description |
|-----|-----------|-------------|
| DescribeCloudAssistantStatus | `ecs:DescribeCloudAssistantStatus` | Check Cloud Assistant online status |

## Minimum Permission Policy Example

```json
{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sysom:InitialSysom",
        "sysom:CheckInstanceSupport",
        "sysom:InvokeDiagnosis",
        "sysom:GetDiagnosisResult",
        "sysom:InstallAgent",
        "sysom:InstallAgentForCluster",
        "sysom:ListInstanceStatus",
        "sysom:ListClusters",
        "sysom:ListAlertItems",
        "sysom:CreateAlertStrategy",
        "sysom:CreateAlertDestination",
        "sysom:UpdateAlertDestination",
        "sysom:DeleteAlertDestination",
        "sysom:GetAlertDestination",
        "sysom:ListAlertDestinations"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ecs:DescribeCloudAssistantStatus"
      ],
      "Resource": "*"
    }
  ]
}
```

## Permission Tiers

| Phase | Required Permissions | Description |
|-------|---------------------|-------------|
| Diagnosis | `sysom:InitialSysom`, `sysom:CheckInstanceSupport`, `sysom:InvokeDiagnosis`, `sysom:GetDiagnosisResult`, `ecs:DescribeCloudAssistantStatus` | Minimum permissions for deep diagnosis |
| Enrollment | `sysom:InstallAgent` or `sysom:InstallAgentForCluster`, `sysom:ListInstanceStatus`, `sysom:ListClusters` | Enroll instances or clusters |
| Alert | `sysom:ListAlertItems`, `sysom:CreateAlertStrategy` | Configure anomaly event alerts |
| Alert Destination | `sysom:CreateAlertDestination`, `sysom:UpdateAlertDestination`, `sysom:DeleteAlertDestination`, `sysom:GetAlertDestination`, `sysom:ListAlertDestinations` | Manage alert destinations (SDK call) |


path: references/related-commands.md
content: # Related Commands: alibabacloud-aes-sysom-os-diagnosis

This skill uses the `aliyun` CLI to call SysOM and ECS APIs. All commands **MUST** include `--user-agent AlibabaCloud-Agent-Skills`.

---

## Diagnosis Phase

| Product | CLI Command | Description |
|---------|------------|-------------|
| sysom | `aliyun sysom initial-sysom --check-only false --source aes-skills` | Initialize SysOM role authorization |
| sysom | `aliyun sysom check-instance-support --instances <id> --biz-region <region>` | Check if instance supports diagnosis |
| sysom | `aliyun sysom invoke-diagnosis --service-name ocd --channel ecs --params '<JSON>'` | Invoke intelligent diagnosis (params keys use snake_case, must include `type: "ocd"`) |
| sysom | `aliyun sysom get-diagnosis-result --task-id <task_id>` | Get diagnosis result |
| ecs | `aliyun ecs describe-cloud-assistant-status --biz-region-id <region> --instance-id <id>` | Check Cloud Assistant online status |

## Enrollment Phase

| Product | CLI Command | Description |
|---------|------------|-------------|
| sysom | `aliyun sysom install-agent --instances instance=<id> region=<region> --install-type InstallAndUpgrade --agent-id <id> --agent-version <ver>` | Enroll instance |
| sysom | `aliyun sysom install-agent-for-cluster --cluster-id <id> --agent-id <id> --agent-version <ver> --config-id <id>` | Enroll ACK cluster |
| sysom | `aliyun sysom list-instance-status --instance <id> --biz-region <region>` | Query instance enrollment status |
| sysom | `aliyun sysom list-clusters` | Get full cluster list (do not pass cluster-id; match target from response by cluster_id) |

## Alert Phase

| Product | CLI Command | Description |
|---------|------------|-------------|
| sysom | `aliyun sysom list-alert-items` | Get available alert items list |

## Alert Strategy Creation (SDK Call, NOT supported by CLI)

> CLI does not support the `destinations` parameter — alert strategy creation must use the SDK script.

| SDK Script | Description |
|-----------|-------------|
| `.sysom-sdk-venv/bin/python scripts/create-alert-strategy.py --name <name> --items <items> --clusters <clusters> --destinations <ids>` | Create alert strategy (supports destinations to associate alert destinations) |

## Alert Destination (SDK Call, NOT supported by CLI)

> The following APIs are called via Python SDK (`alibabacloud_sysom20231230`), NOT supported by `aliyun` CLI.

| SDK Method | Description |
|-----------|-------------|
| `client.create_alert_destination(request)` | Create alert destination (DingTalk bot Webhook) |
| `client.update_alert_destination(request)` | Update alert destination |
| `client.delete_alert_destination(request)` | Delete alert destination |
| `client.get_alert_destination(request)` | Get alert destination details |
| `client.list_alert_destinations(request)` | List alert destinations (filterable by name) |

## Cleanup

| Product | CLI Command | Description |
|---------|------------|-------------|
| sysom | `aliyun sysom uninstall-agent --instances instance=<id> region=<region> --agent-id <id> --agent-version <ver>` | Uninstall Agent |

## Fixed Parameters

| Parameter | Value | Description |
|-----------|-------|-------------|
| `--agent-id` | [REDACTED_SECRET] | Agent ID |
| `--agent-version` | `3.12.0-1` | Agent version |
| `--install-type` | `InstallAndUpgrade` | Installation type (default) |
| `--config-id` | [REDACTED_SECRET] | Cluster component config ID |
| `--channel` | `ecs` | Diagnosis channel (fixed) |
| `--service-name` | `ocd` | Diagnosis type (intelligent diagnosis) |
| `--user-agent` | `AlibabaCloud-Agent-Skills` | Must be appended to all commands |


path: references/verification-method.md
content: # Success Verification: alibabacloud-aes-sysom-os-diagnosis

This document describes the success verification methods for each phase. All `aliyun` CLI commands **MUST** include `--user-agent AlibabaCloud-Agent-Skills`.

---

## 1. Environment Setup Verification

### 1.1 CLI Version

```bash
aliyun version --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: Version >= 3.3.1

### 1.2 Credential Configuration

```bash
aliyun configure list --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: Output contains a valid profile (AK, STS, or OAuth identity)

---

## 2. Diagnosis Phase Verification

### 2.1 Cloud Assistant Online Check

```bash
aliyun ecs describe-cloud-assistant-status \
  --biz-region-id <region> \
  --instance-id <instance_id> \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: `CloudAssistantStatus` is `"true"` in the response

### 2.2 SysOM Role Initialization

```bash
aliyun sysom initial-sysom --check-only false --source aes-skills --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: No error returned

### 2.3 Instance Support Check

```bash
aliyun sysom check-instance-support \
  --instances <instance_id> \
  --biz-region <region> \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: Instance is marked as supported in the response

### 2.4 Diagnosis Execution

```bash
aliyun sysom invoke-diagnosis \
  --service-name ocd \
  --channel ecs \
  --params '{"instanceId":"<instance_id>","region":"<region>","enableDiagnosis":true,"startTime":0,"endTime":0,"aiRoadmap":true,"enableSysomLink":false}' \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: Response contains `task_id`

### 2.5 Diagnosis Result

```bash
aliyun sysom get-diagnosis-result \
  --task-id <task_id> \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: `status` is `Success`, response contains `summary` and `issues` data

---

## 3. Enrollment Phase Verification

### 3.1 Instance Enrollment

```bash
aliyun sysom install-agent \
  --instances instance=<instance_id> region=<region> \
  --install-type InstallAndUpgrade \
  --agent-id 74a86327-3170-412c-8e67-da3389ec56a9 \
  --agent-version 3.12.0-1 \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: No error returned

### 3.2 Instance Status Polling

```bash
aliyun sysom list-instance-status \
  --instance <instance_id> \
  --biz-region <region> \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: Instance `status` is `running`

### 3.3 Cluster Enrollment

```bash
aliyun sysom install-agent-for-cluster \
  --cluster-id <cluster_id> \
  --agent-id 74a86327-3170-412c-8e67-da3389ec56a9 \
  --agent-version 3.12.0-1 \
  --config-id 8gj86wrt7-3170-412c-8e67-da3389ecg6a9 \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: No error returned

### 3.4 Cluster Status Polling

```bash
aliyun sysom list-clusters \
  --cluster-id <cluster_id> \
  --user-agent AlibabaCloud-Agent-Skills
```

**Success criteria**: `cluster_status` is `Running`

---

## 4. Alert Phase Verification

### 4.1 SDK Environment Initialization

```bash
bash scripts/setup-sdk.sh
```

**Success criteria**: Output shows `✅ SDK installation successful`, Python version >= 3.8

### 4.2 Alert Destination Creation (Script Call)

```bash
.sysom-sdk-venv/bin/python scripts/create-alert-destination.py 'https://oapi.dingtalk.com/robot/send?access_token=xxx'
```

**Success criteria**: stdout outputs `destination_id` (a pure number), stderr outputs `✅ Alert destination created successfully`

### 4.3 Alert Strategy Creation (SDK Script Call)

```bash
.sysom-sdk-venv/bin/python scripts/create-alert-strategy.py \
  --name "aliyun-aes-skills-create-<YYYYMMDDHHmm>" \
  --items "<alert_items>" \
  --clusters "default" \
  --destinations "<destination_id>"
```

**Success criteria**: stdout outputs strategy name, stderr outputs `✅ Alert strategy created successfully`


path: scripts/create-alert-destination.py
content: #!/usr/bin/env python3
"""
SysOM 告警联系人创建脚本

功能：通过 SDK 创建钉钉告警联系人（Alert Destination）
用法：python scripts/create-alert-destination.py <webhook_url> [destination_name]

参数：
  webhook_url        钉钉群机器人 Webhook 地址（必填）
  destination_name   告警联系人名称（可选，默认自动生成）

凭据来源（按优先级）：
  1. 环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET
  2. aliyun CLI 配置文件 ~/.aliyun/config.json（自动读取当前 profile）

返回：
  成功时输出 destination_id（纯数字），供后续 create-alert-strategy 使用
"""

import json
import os
import sys
from datetime import datetime


def validate_arguments():
    if len(sys.argv) < 2:
        print("❌ 缺少必填参数：webhook_url", file=sys.stderr)
        print(f"用法：python {sys.argv[0]} <webhook_url> [destination_name]", file=sys.stderr)
        sys.exit(1)

    webhook_url = sys.argv[1]
    if not webhook_url.startswith("https://oapi.dingtalk.com/robot/send"):
        print("⚠️  Webhook 地址格式可能不正确，预期格式：https://oapi.dingtalk.com/robot/send?access_token=xxx", file=sys.stderr)

    timestamp = datetime.now().strftime("%Y%m%d%H%M")
    destination_name = sys.argv[2] if len(sys.argv) > 2 else f"aliyun-aes-skills-destination-{timestamp}"

    return webhook_url, destination_name


def load_credentials_from_cli_config():
    config_path = os.path.join(os.path.expanduser("~"), ".aliyun", "config.json")
    if not os.path.exists(config_path):
        return None, None

    try:
        with open(config_path, "r", encoding="utf-8") as f:
            config = json.load(f)

        current_profile = config.get("current", "")
        profiles = config.get("profiles", [])

        target_profile = None
        for profile in profiles:
            if profile.get("name") == current_profile:
                target_profile = profile
                break

        if not target_profile and profiles:
            target_profile = profiles[0]

        if target_profile:
            [REDACTED_SECRET]"access_key_id", "")
            [REDACTED_SECRET]"access_key_secret", "")
            if access_key_id and [REDACTED_SECRET] = target_profile.get("name", "default")
                print(f"🔑 从 aliyun CLI 配置读取凭据（profile: {profile_name}）", file=sys.stderr)
                return access_key_id, access_key_secret
    except (json.JSONDecodeError, KeyError, TypeError):
        pass

    return None, None

def validate_credentials():
    [REDACTED_SECRET]"ALIBABA_CLOUD_ACCESS_KEY_ID")
    [REDACTED_SECRET]"ALIBABA_CLOUD_ACCESS_KEY_SECRET")

    if access_key_id and [REDACTED_SECRET]"🔑 从环境变量读取凭据", file=sys.stderr)
        return access_key_id, access_key_secret

    access_key_id, [REDACTED_SECRET])
    if access_key_id and [REDACTED_SECRET] access_key_id, access_key_secret

    print("❌ 未找到阿里云凭据，请通过以下任一方式配置：", file=sys.stderr)
    print("   方式1：aliyun configure（推荐，脚本自动读取）", file=sys.stderr)
    print("   方式2：export ALIBABA_CLOUD_ACCESS_KEY_ID=<your_ak>", file=sys.stderr)
    print("          export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your_sk>", file=sys.stderr)
    sys.exit(1)


def main():
    webhook_url, destination_name = validate_arguments()
    access_key_id, [REDACTED_SECRET])

    try:
        from alibabacloud_tea_openapi.utils_models import Config
        from alibabacloud_sysom20231230.client import Client
        from alibabacloud_sysom20231230 import models
    except ImportError:
        print("❌ SDK 未安装，请先运行：bash scripts/setup-sdk.sh", file=sys.stderr)
        sys.exit(1)

    config = Config(
        [REDACTED_SECRET],
        [REDACTED_SECRET],
        endpoint="sysom.aliyuncs.com",
        user_agent="AlibabaCloud-Agent-Skills/alibabacloud-aes-sysom-os-diagnosis",
        connect_timeout=10000,
        read_timeout=30000
    )
    client = Client(config)

    request = models.CreateAlertDestinationRequest(
        target="dingtalk",
        name=destination_name,
        source="aes-skills",
        params=models.CreateAlertDestinationRequestParams(
            webhook=webhook_url
        )
    )

    try:
        response = client.create_alert_destination(request)
        response_body = response.body

        if hasattr(response_body, "to_map"):
            result = response_body.to_map()
        else:
            result = {"body": str(response_body)}

        code = result.get("code", "")
        if code == "Success":
            data = result.get("data", {})
            destination_id = data.get("id")
            print(destination_id)
            print(f"✅ 告警联系人创建成功", file=sys.stderr)
            print(f"   ID: {destination_id}", file=sys.stderr)
            print(f"   名称: {destination_name}", file=sys.stderr)
            print(f"   目标: dingtalk", file=sys.stderr)
        else:
            message = result.get("message", "未知错误")
            print(f"❌ 创建失败：{code} - {message}", file=sys.stderr)
            print(json.dumps(result, indent=2, ensure_ascii=False), file=sys.stderr)
            sys.exit(1)

    except Exception as error:
        print(f"❌ API 调用异常：{error}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/create-alert-strategy.py
content: #!/usr/bin/env python3
"""
SysOM 告警策略创建脚本

功能：通过 SDK 创建告警策略（支持 destinations 参数，CLI 不支持此参数）
用法：.sysom-sdk-venv/bin/python scripts/create-alert-strategy.py \
        --name <策略名称> \
        --items <告警项1>,<告警项2> \
        --clusters <集群1> \
        --destinations <联系人ID1>,<联系人ID2>

参数：
  --name          策略名称（必填）
  --items         告警项列表，逗号分隔（必填）
  --clusters      集群列表，逗号分隔（必填，实例模式填 default）
  --destinations  告警联系人 ID 列表，逗号分隔（必填）
  --k8s-label     是否启用 k8s 标签（可选，默认 false）

凭据来源（按优先级）：
  1. 环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET
  2. aliyun CLI 配置文件 ~/.aliyun/config.json（自动读取当前 profile）

返回：
  成功时 stdout 输出策略名称，详细信息输出到 stderr
"""

import argparse
import json
import os
import sys


def parse_arguments():
    parser = argparse.ArgumentParser(description="创建 SysOM 告警策略")
    parser.add_argument("--name", required=True, help="策略名称")
    parser.add_argument("--items", required=True, help="告警项列表，逗号分隔")
    parser.add_argument("--clusters", required=True, help="集群列表，逗号分隔（实例模式填 default）")
    parser.add_argument("--destinations", required=True, help="告警联系人 ID 列表，逗号分隔")
    parser.add_argument("--k8s-label", action="store_true", default=False, help="是否启用 k8s 标签")
    return parser.parse_args()


def load_credentials_from_cli_config():
    config_path = os.path.join(os.path.expanduser("~"), ".aliyun", "config.json")
    if not os.path.exists(config_path):
        return None, None

    try:
        with open(config_path, "r", encoding="utf-8") as f:
            config = json.load(f)

        current_profile = config.get("current", "")
        profiles = config.get("profiles", [])

        target_profile = None
        for profile in profiles:
            if profile.get("name") == current_profile:
                target_profile = profile
                break

        if not target_profile and profiles:
            target_profile = profiles[0]

        if target_profile:
            [REDACTED_SECRET]"access_key_id", "")
            [REDACTED_SECRET]"access_key_secret", "")
            if access_key_id and [REDACTED_SECRET] = target_profile.get("name", "default")
                print(f"🔑 从 aliyun CLI 配置读取凭据（profile: {profile_name}）", file=sys.stderr)
                return access_key_id, access_key_secret
    except (json.JSONDecodeError, KeyError, TypeError):
        pass

    return None, None

def validate_credentials():
    [REDACTED_SECRET]"ALIBABA_CLOUD_ACCESS_KEY_ID")
    [REDACTED_SECRET]"ALIBABA_CLOUD_ACCESS_KEY_SECRET")

    if access_key_id and [REDACTED_SECRET]"🔑 从环境变量读取凭据", file=sys.stderr)
        return access_key_id, access_key_secret

    access_key_id, [REDACTED_SECRET])
    if access_key_id and [REDACTED_SECRET] access_key_id, access_key_secret

    print("❌ 未找到阿里云凭据，请通过以下任一方式配置：", file=sys.stderr)
    print("   方式1：aliyun configure（推荐，脚本自动读取）", file=sys.stderr)
    print("   方式2：export ALIBABA_CLOUD_ACCESS_KEY_ID=<your_ak>", file=sys.stderr)
    print("          export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your_sk>", file=sys.stderr)
    sys.exit(1)


def main():
    args = parse_arguments()
    access_key_id, [REDACTED_SECRET])

    items_list = [item.strip() for item in args.items.split(",") if item.strip()]
    clusters_list = [cluster.strip() for cluster in args.clusters.split(",") if cluster.strip()]

    try:
        destinations_list = [int(d.strip()) for d in args.destinations.split(",") if d.strip()]
    except ValueError:
        print("❌ destinations 参数格式错误，应为逗号分隔的整数 ID（如：1,2,3）", file=sys.stderr)
        sys.exit(1)

    if not items_list:
        print("❌ 至少需要指定一个告警项（--items）", file=sys.stderr)
        sys.exit(1)

    if not destinations_list:
        print("❌ 至少需要指定一个告警联系人 ID（--destinations）", file=sys.stderr)
        sys.exit(1)

    try:
        from alibabacloud_tea_openapi.utils_models import Config
        from alibabacloud_sysom20231230.client import Client
        from alibabacloud_sysom20231230 import models
    except ImportError:
        print("❌ SDK 未安装，请先运行：bash scripts/setup-sdk.sh", file=sys.stderr)
        sys.exit(1)

    config = Config(
        [REDACTED_SECRET],
        [REDACTED_SECRET],
        endpoint="sysom.aliyuncs.com",
        user_agent="AlibabaCloud-Agent-Skills/alibabacloud-aes-sysom-os-diagnosis",
        connect_timeout=10000,
        read_timeout=30000
    )
    client = Client(config)

    strategy = models.CreateAlertStrategyRequestStrategy(
        clusters=clusters_list,
        items=items_list,
        destinations=destinations_list
    )

    request = models.CreateAlertStrategyRequest(
        name=args.name,
        enabled=True,
        k_8s_label=args.k8s_label,
        strategy=strategy
    )

    try:
        response = client.create_alert_strategy(request)
        response_body = response.body

        if hasattr(response_body, "to_map"):
            result = response_body.to_map()
        else:
            result = {"body": str(response_body)}

        code = result.get("code", "")
        if code == "Success":
            print(args.name)
            print(f"✅ 告警策略创建成功", file=sys.stderr)
            print(f"   策略名称: {args.name}", file=sys.stderr)
            print(f"   告警项数: {len(items_list)}", file=sys.stderr)
            print(f"   集群: {', '.join(clusters_list)}", file=sys.stderr)
            print(f"   告警联系人 ID: {destinations_list}", file=sys.stderr)
        else:
            message = result.get("message", "未知错误")
            print(f"❌ 创建失败：{code} - {message}", file=sys.stderr)
            print(json.dumps(result, indent=2, ensure_ascii=False), file=sys.stderr)
            sys.exit(1)

    except Exception as error:
        print(f"❌ API 调用异常：{error}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/setup-sdk.sh
content: #!/bin/bash
# SysOM Alert Destination SDK 环境初始化脚本
# 功能：检测 Python 版本 >= 3.8，创建虚拟环境，安装 alibabacloud_sysom20231230 SDK
# 用法：bash scripts/setup-sdk.sh

set -e

VENV_DIR=".sysom-sdk-venv"
MIN_PYTHON_VERSION="3.8"
SDK_PACKAGE="alibabacloud_sysom20231230==1.16.0"

echo "🔍 检测 Python 环境..."

# 查找可用的 Python 解释器
PYTHON_CMD=""
for cmd in python3 python; do
    if command -v "$cmd" &>/dev/null; then
        PYTHON_CMD="$cmd"
        break
    fi
done

if [ -z "$PYTHON_CMD" ]; then
    echo "❌ 未找到 Python 解释器，请先安装 Python >= ${MIN_PYTHON_VERSION}"
    echo "   安装指南：https://www.python.org/downloads/"
    exit 1
fi

# 检测 Python 版本
PYTHON_VERSION=$($PYTHON_CMD -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
PYTHON_MAJOR=$($PYTHON_CMD -c "import sys; print(sys.version_info.major)")
PYTHON_MINOR=$($PYTHON_CMD -c "import sys; print(sys.version_info.minor)")

if [ "$PYTHON_MAJOR" -lt 3 ] || ([ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 8 ]); then
    echo "❌ Python 版本过低：当前 ${PYTHON_VERSION}，要求 >= ${MIN_PYTHON_VERSION}"
    echo "   请升级 Python：https://www.python.org/downloads/"
    exit 1
fi

echo "✅ Python ${PYTHON_VERSION} 满足要求（>= ${MIN_PYTHON_VERSION}）"

# 确定脚本所在目录（scripts/），虚拟环境创建在 skill 根目录
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_ROOT="$(dirname "$SCRIPT_DIR")"
VENV_PATH="${SKILL_ROOT}/${VENV_DIR}"

# 创建虚拟环境
if [ -d "$VENV_PATH" ]; then
    echo "📦 虚拟环境已存在：${VENV_PATH}"
else
    echo "📦 创建虚拟环境：${VENV_PATH}"
    $PYTHON_CMD -m venv "$VENV_PATH"
fi

# 激活虚拟环境并安装 SDK
echo "📥 安装 SDK：${SDK_PACKAGE}"
"${VENV_PATH}/bin/pip" install --quiet --upgrade pip
"${VENV_PATH}/bin/pip" install --quiet "$SDK_PACKAGE"

# 验证安装
SDK_VERSION=$("${VENV_PATH}/bin/python" -c "import alibabacloud_sysom20231230; print(alibabacloud_sysom20231230.__version__)")
echo "✅ SDK 安装成功：${SDK_PACKAGE} v${SDK_VERSION}"
echo ""
echo "📌 后续使用 SDK 时，请通过以下方式运行 Python 脚本："
echo "   ${VENV_PATH}/bin/python scripts/create-alert-destination.py <webhook_url> [name]"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)