From 2802ccc148a826b2c3a9541e913d856eb35d5fa8 Mon Sep 17 00:00:00 2001 From: "yanbiao.0" Date: Thu, 19 Mar 2026 15:27:40 +0800 Subject: [PATCH] feat: add rds postgresql skills --- skills/volcengine-rds-postgresql/SKILL.md | 183 ++++++ .../requirements.txt | 5 + .../scripts/call_rds_postgresql.py | 557 ++++++++++++++++++ 3 files changed, 745 insertions(+) create mode 100644 skills/volcengine-rds-postgresql/SKILL.md create mode 100644 skills/volcengine-rds-postgresql/requirements.txt create mode 100644 skills/volcengine-rds-postgresql/scripts/call_rds_postgresql.py diff --git a/skills/volcengine-rds-postgresql/SKILL.md b/skills/volcengine-rds-postgresql/SKILL.md new file mode 100644 index 00000000..ea4cfdda --- /dev/null +++ b/skills/volcengine-rds-postgresql/SKILL.md @@ -0,0 +1,183 @@ +--- +name: volcengine-rds-postgresql +description: 使用火山引擎 RDS PostgreSQL,帮助用户完成 RDS PostgreSQL 相关的实例管理、数据库操作、账号管理和运维任务,可直接调用 uv run ./scripts/call_rds_postgresql.py 脚本获取实时结果。 +metadata: {"clawdbot":{"emoji":"🐘","homepage":"https://www.volcengine.com/product/rds-postgresql","requires":{"bins":["uv"],"env":["VOLCENGINE_ACCESS_KEY","VOLCENGINE_SECRET_KEY"]},"os":["darwin","linux"]},"openclaw":{"emoji":"🐘","homepage":"https://www.volcengine.com/product/rds-postgresql","requires":{"bins":["uv"],"env":["VOLCENGINE_ACCESS_KEY","VOLCENGINE_SECRET_KEY"]},"os":["darwin","linux"]},"moltbot":{"emoji":"🐘","homepage":"https://www.volcengine.com/product/rds-postgresql","requires":{"bins":["uv"],"env":["VOLCENGINE_ACCESS_KEY","VOLCENGINE_SECRET_KEY"]},"os":["darwin","linux"]}} +--- + +## Skill 概览 + +本 Skill 用于在对话中充当 **火山引擎 RDS PostgreSQL 的智能运维代理**: + +- **理解用户的自然语言需求**(中文或英文),识别是否与 RDS PostgreSQL 相关; +- **直接调用内置脚本** `scripts/call_rds_postgresql.py` 实时查询 RDS PostgreSQL 并获取结果; +- 当获取到结果或用户粘贴错误信息时,**进一步解释、诊断并给出后续建议**。 + +**工作模式**: +- 使用 `scripts/call_rds_postgresql.py` 脚本直接获取 RDS PostgreSQL 的实时响应 + +**运行方式**: +脚本支持两种运行方式: +```bash +# 方式 1: 使用 uv (推荐,自动管理依赖) +uv run ./scripts/call_rds_postgresql.py [action] [options] + +# 方式 2: 使用 python (需要预先安装依赖) +python ./scripts/call_rds_postgresql.py [action] [options] +``` + +## 标准使用流程 + +1. **确认任务类型与参数** + - 判断用户意图:查询实例列表、查看实例详情、管理数据库、管理账号、查看参数配置、创建实例等。 + - 收集必要参数(如未指定则使用默认值): + - `--region`:地域 ID(默认 `cn-beijing`) + - `--action`:操作类型(如 `list-instances`、`describe-instance`、`list-databases` 等) + - `--instance-id`:实例 ID(部分操作必需) + +2. **构造查询并调用脚本** + - 示例(以下命令可使用 `uv run` 或 `python` 运行): + ```bash + # 查询实例列表 + uv run ./scripts/call_rds_postgresql.py list-instances + # 或 + python ./scripts/call_rds_postgresql.py list-instances + + # 查询指定实例详情 + uv run ./scripts/call_rds_postgresql.py describe-instance --instance-id postgres-xxx + # 或 + python ./scripts/call_rds_postgresql.py describe-instance --instance-id postgres-xxx + + # 查询实例的数据库列表 + uv run ./scripts/call_rds_postgresql.py list-databases --instance-id postgres-xxx + # 或 + python ./scripts/call_rds_postgresql.py list-databases --instance-id postgres-xxx + + # 查询实例的账号列表 + uv run ./scripts/call_rds_postgresql.py list-accounts --instance-id postgres-xxx + # 或 + python ./scripts/call_rds_postgresql.py list-accounts --instance-id postgres-xxx + + # 查询实例参数 + uv run ./scripts/call_rds_postgresql.py list-parameters --instance-id postgres-xxx + # 或 + python ./scripts/call_rds_postgresql.py list-parameters --instance-id postgres-xxx + + # 查询 VPC 列表(用于创建实例) + uv run ./scripts/call_rds_postgresql.py list-vpcs + # 或 + python ./scripts/call_rds_postgresql.py list-vpcs + + # 查询子网列表 + uv run ./scripts/call_rds_postgresql.py list-subnets --vpc-id vpc-xxx --zone-id cn-beijing-a + # 或 + python ./scripts/call_rds_postgresql.py list-subnets --vpc-id vpc-xxx --zone-id cn-beijing-a + ``` + +3. **解析结果并后续处理** + - 将 RDS PostgreSQL 的响应用自然语言解释给用户; + - 如返回包含敏感操作,评估风险并提醒: + - 避免在生产环境直接执行高风险操作(如删除实例、删除数据库等); + - 建议在测试环境验证或做好备份。 + +## 工具脚本使用说明 + +### 支持的操作(Actions) + +| 操作 | 说明 | 必需参数 | +|------|------|----------| +| `list-instances` | 查询 RDS PostgreSQL 实例列表 | 无 | +| `describe-instance` | 查询指定实例详情 | `--instance-id` | +| `list-databases` | 查询实例的数据库列表 | `--instance-id` | +| `list-accounts` | 查询实例的账号列表 | `--instance-id` | +| `list-parameters` | 查询实例的参数配置 | `--instance-id` | +| `list-parameter-templates` | 查询参数模板列表 | 无 | +| `describe-parameter-template` | 查询参数模板详情 | `--template-id` | +| `list-vpcs` | 查询 VPC 列表 | 无 | +| `list-subnets` | 查询子网列表 | `--vpc-id` | +| `get-price` | 查询实例价格 | 多个配置参数 | + +### 命令行参数 + +| 参数 | 说明 | 默认值 | +|------|------|--------| +| `action` | 操作类型(必需) | - | +| `--region` / `-r` | 火山引擎地域 ID | `cn-beijing` | +| `--instance-id` / `-i` | 实例 ID | 无 | +| `--page-number` | 分页页码 | `1` | +| `--page-size` | 每页记录数 | `10` | +| `--output` / `-o` | 输出格式(json/table) | `json` | + +> **注意**:`--region`、`--page-number`、`--page-size` 等全局参数必须放在子命令**之前**,例如: +> ```bash +> uv run ./scripts/call_rds_postgresql.py --region cn-shanghai list-instances +> ``` +> 放在子命令之后会被忽略(argparse 解析限制)。 + +### 输出格式 + +脚本会将查询信息输出到 `stderr`,将结果输出到 `stdout`,便于分离日志和结果: + +``` +[操作] list-instances +[地域] cn-beijing +============================================================ +[查询结果] +<实际结果内容> +``` + +## 常见使用场景 + +### 1. 查看所有实例 +```bash +uv run ./scripts/call_rds_postgresql.py list-instances +``` + +### 2. 查看实例详情 +```bash +uv run ./scripts/call_rds_postgresql.py describe-instance --instance-id postgres-xxx +``` + +### 3. 查看实例的数据库 +```bash +uv run ./scripts/call_rds_postgresql.py list-databases --instance-id postgres-xxx +``` + +### 4. 查看实例的账号 +```bash +uv run ./scripts/call_rds_postgresql.py list-accounts --instance-id postgres-xxx +``` + +### 5. 查看实例参数配置 +```bash +uv run ./scripts/call_rds_postgresql.py list-parameters --instance-id postgres-xxx +``` + +### 6. 按版本过滤实例 +```bash +uv run ./scripts/call_rds_postgresql.py list-instances --db-engine-version PostgreSQL_14 +``` + +### 7. 创建实例前查询网络信息 +```bash +# 先查询 VPC +uv run ./scripts/call_rds_postgresql.py list-vpcs + +# 再查询子网 +uv run ./scripts/call_rds_postgresql.py list-subnets --vpc-id vpc-xxx --zone-id cn-beijing-a +``` + +## 环境变量配置 + +1. 获取火山引擎访问凭证:参考 [用户指南](https://www.volcengine.com/docs/6291/65568?lang=zh) 获取 AK/SK + +2. 配置以下环境变量: + +```bash +export VOLCENGINE_ACCESS_KEY="your-access-key" +export VOLCENGINE_SECRET_KEY="your-secret-key" +export VOLCENGINE_REGION="cn-beijing" # 可选,默认 cn-beijing +``` + +> **权限说明**:`list-vpcs` 和 `list-subnets` 调用的是 VPC 服务接口,AK/SK 需要同时授予 +> **RDS PostgreSQL** 和 **VPC**(`vpc:DescribeVpcs`、`vpc:DescribeSubnets`)两个服务的权限, +> 否则会返回 `AccessDenied 403` 错误。 diff --git a/skills/volcengine-rds-postgresql/requirements.txt b/skills/volcengine-rds-postgresql/requirements.txt new file mode 100644 index 00000000..20619190 --- /dev/null +++ b/skills/volcengine-rds-postgresql/requirements.txt @@ -0,0 +1,5 @@ +# 火山引擎 RDS PostgreSQL 运维助手工具依赖 + +## Python 依赖包 + +volcengine-python-sdk[rdspostgresqlv2,vpc]>=1.0.0 diff --git a/skills/volcengine-rds-postgresql/scripts/call_rds_postgresql.py b/skills/volcengine-rds-postgresql/scripts/call_rds_postgresql.py new file mode 100644 index 00000000..4c34ded9 --- /dev/null +++ b/skills/volcengine-rds-postgresql/scripts/call_rds_postgresql.py @@ -0,0 +1,557 @@ +#!/usr/bin/env -S uv run +# /// script +# requires-python = ">=3.9" +# dependencies = [ +# "volcengine-python-sdk[rdspostgresqlv2,vpc]>=1.0.0", +# ] +# /// +# -*- coding: utf-8 -*- +""" +火山引擎 RDS PostgreSQL 运维助手调用脚本 +用于接收用户命令并调用火山引擎 RDS PostgreSQL API,返回结果 +""" + +import os +import sys +import argparse +import json +from typing import Optional, Any, Dict + +try: + import volcenginesdkcore + from volcenginesdkrdspostgresql.api.rds_postgresql_api import RDSPOSTGRESQLApi + from volcenginesdkrdspostgresql import models + from volcenginesdkvpc.api.vpc_api import VPCApi + from volcenginesdkvpc.models import ( + DescribeVpcsRequest, + DescribeSubnetsRequest, + ) +except ImportError as e: + print( + "错误: 缺少必要的依赖包。请先安装: pip install 'volcengine-python-sdk[rdspostgresqlv2,vpc]'", + file=sys.stderr, + ) + print(f"详细错误: {e}", file=sys.stderr) + sys.exit(1) + + +class RDSPostgreSQLClient: + """火山引擎 RDS PostgreSQL 客户端封装""" + + def __init__(self, region: str = "cn-beijing", endpoint: Optional[str] = None): + """ + 初始化 RDS PostgreSQL 客户端 + + Args: + region: 地域 ID,默认为 cn-beijing + endpoint: API 端点(可选) + """ + self.region = region + self.endpoint = endpoint + self.client = self._create_client() + self.vpc_client = self._create_vpc_client() + + def _create_client(self) -> RDSPOSTGRESQLApi: + """创建火山引擎 RDS PostgreSQL 客户端""" + access_key = os.getenv("VOLCENGINE_ACCESS_KEY") + secret_key = os.getenv("VOLCENGINE_SECRET_KEY") + + if not access_key or not secret_key: + raise ValueError( + "未找到火山引擎访问凭证。请设置环境变量:\n" + " VOLCENGINE_ACCESS_KEY\n" + " VOLCENGINE_SECRET_KEY" + ) + + configuration = volcenginesdkcore.Configuration() + configuration.ak = access_key + configuration.sk = secret_key + configuration.region = self.region + if self.endpoint: + configuration.host = self.endpoint + + return RDSPOSTGRESQLApi( + volcenginesdkcore.ApiClient(configuration, "X-Rdsmgr-Source", "mcp_skill") + ) + + def _create_vpc_client(self) -> VPCApi: + """创建火山引擎 VPC 客户端""" + access_key = os.getenv("VOLCENGINE_ACCESS_KEY") + secret_key = os.getenv("VOLCENGINE_SECRET_KEY") + + configuration = volcenginesdkcore.Configuration() + configuration.ak = access_key + configuration.sk = secret_key + configuration.region = self.region + + return VPCApi(volcenginesdkcore.ApiClient(configuration)) + + def _to_dict(self, obj: Any) -> Any: + """将 SDK 响应对象转换为字典""" + if obj is None: + return None + if hasattr(obj, "to_dict"): + return obj.to_dict() + if isinstance(obj, list): + return [self._to_dict(item) for item in obj] + if isinstance(obj, dict): + return {k: self._to_dict(v) for k, v in obj.items()} + return obj + + def list_instances( + self, + page_number: int = 1, + page_size: int = 10, + instance_id: Optional[str] = None, + instance_name: Optional[str] = None, + instance_status: Optional[str] = None, + db_engine_version: Optional[str] = None, + ) -> Dict[str, Any]: + """查询 RDS PostgreSQL 实例列表""" + req_params = { + "page_number": page_number, + "page_size": page_size, + } + if instance_id: + req_params["instance_id"] = instance_id + if instance_name: + req_params["instance_name"] = instance_name + if instance_status: + req_params["instance_status"] = instance_status + if db_engine_version: + req_params["db_engine_version"] = db_engine_version + + resp = self.client.describe_db_instances( + models.DescribeDBInstancesRequest(**req_params) + ) + return self._to_dict(resp) + + def describe_instance(self, instance_id: str) -> Dict[str, Any]: + """查询指定实例详情""" + resp = self.client.describe_db_instance_detail( + models.DescribeDBInstanceDetailRequest(instance_id=instance_id) + ) + return self._to_dict(resp) + + def list_databases( + self, + instance_id: str, + db_name: Optional[str] = None, + page_number: int = 1, + page_size: int = 10, + ) -> Dict[str, Any]: + """查询实例的数据库列表""" + req_params = { + "instance_id": instance_id, + "page_number": page_number, + "page_size": page_size, + } + if db_name: + req_params["db_name"] = db_name + + resp = self.client.describe_databases( + models.DescribeDatabasesRequest(**req_params) + ) + return self._to_dict(resp) + + def list_accounts( + self, + instance_id: str, + account_name: Optional[str] = None, + page_number: int = 1, + page_size: int = 10, + ) -> Dict[str, Any]: + """查询实例的账号列表""" + req_params = { + "instance_id": instance_id, + "page_number": page_number, + "page_size": page_size, + } + if account_name: + req_params["account_name"] = account_name + + resp = self.client.describe_db_accounts( + models.DescribeDBAccountsRequest(**req_params) + ) + return self._to_dict(resp) + + def list_parameters( + self, + instance_id: str, + parameter_name: Optional[str] = None, + ) -> Dict[str, Any]: + """查询实例的参数配置""" + req_params = {"instance_id": instance_id} + if parameter_name: + req_params["parameter_name"] = parameter_name + + resp = self.client.describe_db_instance_parameters( + models.DescribeDBInstanceParametersRequest(**req_params) + ) + return self._to_dict(resp) + + def list_parameter_templates( + self, + template_type: str = "PostgreSQL", + template_type_version: Optional[str] = None, + template_source: Optional[str] = None, + template_category: Optional[str] = None, + ) -> Dict[str, Any]: + """查询参数模板列表""" + req_params = { + "template_type": template_type, + } + if template_type_version: + req_params["template_type_version"] = template_type_version + if template_source: + req_params["template_source"] = template_source + if template_category: + req_params["template_category"] = template_category + + resp = self.client.list_parameter_templates( + models.ListParameterTemplatesRequest(**req_params) + ) + return self._to_dict(resp) + + def describe_parameter_template(self, template_id: str) -> Dict[str, Any]: + """查询参数模板详情""" + resp = self.client.describe_parameter_template( + models.DescribeParameterTemplateRequest(template_id=template_id) + ) + return self._to_dict(resp) + + def list_vpcs(self, page_number: int = 1, page_size: int = 10) -> Dict[str, Any]: + """查询 VPC 列表""" + resp = self.vpc_client.describe_vpcs( + DescribeVpcsRequest(page_number=page_number, page_size=page_size) + ) + return self._to_dict(resp) + + def list_subnets( + self, vpc_id: str, zone_id: Optional[str] = None + ) -> Dict[str, Any]: + """查询子网列表""" + req_params = {"vpc_id": vpc_id} + if zone_id: + req_params["zone_id"] = zone_id + + resp = self.vpc_client.describe_subnets(DescribeSubnetsRequest(**req_params)) + return self._to_dict(resp) + + def get_price( + self, + node_spec: str = "rds.postgres.1c2g", + storage_space: int = 20, + storage_type: str = "LocalSSD", + charge_type: str = "PostPaid", + zone_id: str = "cn-beijing-a", + ) -> Dict[str, Any]: + """查询实例价格""" + node_info = [ + {"NodeType": "Primary", "ZoneId": zone_id, "NodeSpec": node_spec}, + {"NodeType": "Secondary", "ZoneId": zone_id, "NodeSpec": node_spec}, + ] + + charge_info = {"ChargeType": charge_type} + + req_params = { + "node_info": node_info, + "storage_type": storage_type, + "storage_space": storage_space, + "charge_info": charge_info, + } + + resp = self.client.describe_db_instance_price_detail( + models.DescribeDBInstancePriceDetailRequest(**req_params) + ) + return self._to_dict(resp) + + +def format_output(data: Any, output_format: str = "json") -> str: + """格式化输出""" + if output_format == "json": + return json.dumps(data, indent=2, ensure_ascii=False, default=str) + else: + # 简单的表格格式 + return json.dumps(data, indent=2, ensure_ascii=False, default=str) + + +def main(): + """命令行入口""" + parser = argparse.ArgumentParser( + description="火山引擎 RDS PostgreSQL 运维助手命令行工具", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +示例: + # 查询实例列表 + python call_rds_postgresql.py list-instances + + # 查询指定实例详情 + python call_rds_postgresql.py describe-instance --instance-id postgres-xxx + + # 查询实例的数据库列表 + python call_rds_postgresql.py list-databases --instance-id postgres-xxx + + # 查询实例的账号列表 + python call_rds_postgresql.py list-accounts --instance-id postgres-xxx + + # 查询实例参数 + python call_rds_postgresql.py list-parameters --instance-id postgres-xxx + + # 查询 VPC 列表 + python call_rds_postgresql.py list-vpcs + + # 查询子网列表 + python call_rds_postgresql.py list-subnets --vpc-id vpc-xxx --zone-id cn-beijing-a + """, + ) + + # 子命令 + subparsers = parser.add_subparsers(dest="action", help="操作类型") + + # list-instances + list_instances_parser = subparsers.add_parser( + "list-instances", help="查询 RDS PostgreSQL 实例列表" + ) + list_instances_parser.add_argument( + "--instance-id", "-i", dest="instance_id", help="实例 ID(可选,用于过滤)" + ) + list_instances_parser.add_argument( + "--instance-name", dest="instance_name", help="实例名称(可选,用于过滤)" + ) + list_instances_parser.add_argument( + "--instance-status", dest="instance_status", help="实例状态(可选,用于过滤)" + ) + list_instances_parser.add_argument( + "--db-engine-version", + dest="db_engine_version", + help="数据库引擎版本(可选,如 PostgreSQL_13)", + ) + + # describe-instance + describe_instance_parser = subparsers.add_parser( + "describe-instance", help="查询指定实例详情" + ) + describe_instance_parser.add_argument( + "--instance-id", "-i", dest="instance_id", required=True, help="实例 ID" + ) + + # list-databases + list_databases_parser = subparsers.add_parser( + "list-databases", help="查询实例的数据库列表" + ) + list_databases_parser.add_argument( + "--instance-id", "-i", dest="instance_id", required=True, help="实例 ID" + ) + list_databases_parser.add_argument( + "--db-name", dest="db_name", help="数据库名称(可选,用于过滤)" + ) + + # list-accounts + list_accounts_parser = subparsers.add_parser( + "list-accounts", help="查询实例的账号列表" + ) + list_accounts_parser.add_argument( + "--instance-id", "-i", dest="instance_id", required=True, help="实例 ID" + ) + list_accounts_parser.add_argument( + "--account-name", dest="account_name", help="账号名称(可选,用于过滤)" + ) + + # list-parameters + list_parameters_parser = subparsers.add_parser( + "list-parameters", help="查询实例的参数配置" + ) + list_parameters_parser.add_argument( + "--instance-id", "-i", dest="instance_id", required=True, help="实例 ID" + ) + list_parameters_parser.add_argument( + "--parameter-name", dest="parameter_name", help="参数名称(可选)" + ) + + # list-parameter-templates + list_templates_parser = subparsers.add_parser( + "list-parameter-templates", help="查询参数模板列表" + ) + list_templates_parser.add_argument( + "--template-type-version", + dest="template_type_version", + help="数据库版本(如 PostgreSQL_13、PostgreSQL_14)", + ) + list_templates_parser.add_argument( + "--template-source", + dest="template_source", + help="模板来源(System 或 User)", + ) + list_templates_parser.add_argument( + "--template-category", + dest="template_category", + help="模板类别(可选)", + ) + + # describe-parameter-template + describe_template_parser = subparsers.add_parser( + "describe-parameter-template", help="查询参数模板详情" + ) + describe_template_parser.add_argument( + "--template-id", dest="template_id", required=True, help="参数模板 ID" + ) + + # list-vpcs + subparsers.add_parser("list-vpcs", help="查询 VPC 列表") + + # list-subnets + list_subnets_parser = subparsers.add_parser("list-subnets", help="查询子网列表") + list_subnets_parser.add_argument( + "--vpc-id", dest="vpc_id", required=True, help="VPC ID" + ) + list_subnets_parser.add_argument( + "--zone-id", dest="zone_id", help="可用区 ID(可选)" + ) + + # get-price + get_price_parser = subparsers.add_parser("get-price", help="查询实例价格") + get_price_parser.add_argument( + "--node-spec", + dest="node_spec", + default="rds.postgres.1c2g", + help="节点规格(默认: rds.postgres.1c2g)", + ) + get_price_parser.add_argument( + "--storage-space", + dest="storage_space", + type=int, + default=20, + help="存储空间 GB(默认: 20)", + ) + get_price_parser.add_argument( + "--charge-type", + dest="charge_type", + default="PostPaid", + help="计费类型(默认: PostPaid)", + ) + get_price_parser.add_argument( + "--zone-id", + dest="zone_id", + default="cn-beijing-a", + help="可用区(默认: cn-beijing-a)", + ) + + # 通用参数 + parser.add_argument( + "--region", + "-r", + dest="region", + default=os.getenv("VOLCENGINE_REGION", "cn-beijing"), + help="火山引擎地域 ID(默认: cn-beijing)", + ) + parser.add_argument("--endpoint", dest="endpoint", help="API 端点(可选)") + parser.add_argument( + "--page-number", + dest="page_number", + type=int, + default=1, + help="分页页码(默认: 1)", + ) + parser.add_argument( + "--page-size", + dest="page_size", + type=int, + default=10, + help="每页记录数(默认: 10)", + ) + parser.add_argument( + "--output", + "-o", + dest="output", + default="json", + choices=["json", "table"], + help="输出格式(默认: json)", + ) + + args = parser.parse_args() + + if not args.action: + parser.print_help() + sys.exit(1) + + # 输出操作信息到 stderr + print(f"[操作] {args.action}", file=sys.stderr) + print(f"[地域] {args.region}", file=sys.stderr) + print("=" * 60, file=sys.stderr) + + try: + client = RDSPostgreSQLClient(region=args.region, endpoint=args.endpoint) + + result = None + + if args.action == "list-instances": + result = client.list_instances( + page_number=args.page_number, + page_size=args.page_size, + instance_id=getattr(args, "instance_id", None), + instance_name=getattr(args, "instance_name", None), + instance_status=getattr(args, "instance_status", None), + db_engine_version=getattr(args, "db_engine_version", None), + ) + elif args.action == "describe-instance": + result = client.describe_instance(instance_id=args.instance_id) + elif args.action == "list-databases": + result = client.list_databases( + instance_id=args.instance_id, + db_name=getattr(args, "db_name", None), + page_number=args.page_number, + page_size=args.page_size, + ) + elif args.action == "list-accounts": + result = client.list_accounts( + instance_id=args.instance_id, + account_name=getattr(args, "account_name", None), + page_number=args.page_number, + page_size=args.page_size, + ) + elif args.action == "list-parameters": + result = client.list_parameters( + instance_id=args.instance_id, + parameter_name=getattr(args, "parameter_name", None), + ) + elif args.action == "list-parameter-templates": + result = client.list_parameter_templates( + template_type_version=getattr(args, "template_type_version", None), + template_source=getattr(args, "template_source", None), + template_category=getattr(args, "template_category", None), + ) + elif args.action == "describe-parameter-template": + result = client.describe_parameter_template(template_id=args.template_id) + elif args.action == "list-vpcs": + result = client.list_vpcs( + page_number=args.page_number, page_size=args.page_size + ) + elif args.action == "list-subnets": + result = client.list_subnets( + vpc_id=args.vpc_id, zone_id=getattr(args, "zone_id", None) + ) + elif args.action == "get-price": + result = client.get_price( + node_spec=args.node_spec, + storage_space=args.storage_space, + charge_type=args.charge_type, + zone_id=args.zone_id, + ) + else: + print(f"未知操作: {args.action}", file=sys.stderr) + sys.exit(1) + + print("[查询结果]", file=sys.stderr) + print(format_output(result, args.output)) + + except ValueError as e: + print(f"\n配置错误: {e}", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"\n调用 RDS PostgreSQL API 时出错: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == "__main__": + main()