tencent_sdk/services/
cvm.rs

1use crate::client::TencentCloudClient;
2use serde_json::{json, Map, Value};
3use std::error::Error;
4
5/// 查看实例列表 - DescribeInstances
6///
7/// **接口描述**:
8/// - 接口请求域名:cvm.tencentcloudapi.com
9/// - 默认接口请求频率限制:40次/秒
10///
11/// **入参说明**:
12///
13/// | 参数    | 类型   | 说明                                       |
14/// |---------|--------|--------------------------------------------|
15/// | Action  | String | 固定为 `"DescribeInstances"`               |
16/// | Version | String | 固定为 `"2017-03-12"`                      |
17/// | Region  | String | 必填,指定区域(例如:"ap-shanghai")       |
18/// | Body    | JSON   | 固定为 `{}`(无业务参数)                  |
19///
20/// **出参说明**:
21///
22/// | 字段         | 类型    | 说明                                               |
23/// |--------------|---------|----------------------------------------------------|
24/// | TotalCount   | Integer | 符合条件的实例数量                                 |
25/// | InstanceSet  | Array   | 实例详细信息列表(具体字段参见腾讯云文档)           |
26/// | RequestId    | String  | 唯一请求ID,用于问题定位                           |
27pub async fn describe_instances(client: &TencentCloudClient) -> Result<serde_json::Value, Box<dyn Error>> {
28    client.request(
29        "cvm",
30        "cvm.tencentcloudapi.com",
31        Some("ap-shanghai"),
32        "2017-03-12",
33        "DescribeInstances",
34        "{}",
35    ).await
36}
37
38/// 重置实例密码 - ResetInstancesPassword
39///
40/// **接口描述**:
41/// - 接口请求域名:cvm.tencentcloudapi.com
42/// - 默认接口请求频率限制:10次/秒
43///
44/// **入参说明**:
45///
46/// | 参数         | 类型    | 说明                                                                               |
47/// |--------------|---------|------------------------------------------------------------------------------------|
48/// | Action       | String  | 固定为 `"ResetInstancesPassword"`                                                 |
49/// | Version      | String  | 固定为 `"2017-03-12"`                                                              |
50/// | Region       | String  | 必填,指定区域(例如:"ap-shanghai")                                               |
51/// | InstanceIds  | Array   | 必填,实例ID数组(每次最多支持100个实例ID)                                         |
52/// | Password     | String  | 必填,重置后的登录密码(需符合系统密码复杂度要求)                                   |
53/// | UserName     | String  | 可选,待重置密码的操作系统用户名(不传则使用默认管理员账号)                          |
54/// | ForceStop    | Boolean | 可选,是否对运行中实例进行强制关机,默认 false                                      |
55/// | Body         | JSON    | 由上述参数构成的 JSON 字符串                                                       |
56///
57/// **出参说明**:
58///
59/// | 字段     | 类型   | 说明           |
60/// |----------|--------|----------------|
61/// | RequestId| String | 唯一请求ID     |
62pub async fn reset_instances_password(
63    client: &TencentCloudClient,
64    region: &str,
65    instance_ids: Vec<&str>,
66    password: &str,
67    username: Option<&str>,
68    force_stop: Option<bool>,
69) -> Result<serde_json::Value, Box<dyn Error>> {
70    let mut payload_map = Map::new();
71    payload_map.insert("InstanceIds".to_string(), json!(instance_ids));
72    payload_map.insert("Password".to_string(), json!(password));
73    if let Some(user) = username {
74        payload_map.insert("UserName".to_string(), json!(user));
75    }
76    if let Some(force) = force_stop {
77        payload_map.insert("ForceStop".to_string(), json!(force));
78    }
79    let payload = Value::Object(payload_map).to_string();
80
81    client.request(
82        "cvm",
83        "cvm.tencentcloudapi.com",
84        Some(region),
85        "2017-03-12",
86        "ResetInstancesPassword",
87        &payload,
88    ).await
89}
90
91/// 查询实例管理终端地址 - DescribeInstanceVncUrl
92///
93/// **接口描述**:
94/// - 接口请求域名:cvm.tencentcloudapi.com
95/// - 默认接口请求频率限制:10次/秒
96///
97/// **入参说明**:
98///
99/// | 参数       | 类型   | 说明                                           |
100/// |------------|--------|------------------------------------------------|
101/// | Action     | String | 固定为 `"DescribeInstanceVncUrl"`               |
102/// | Version    | String | 固定为 `"2017-03-12"`                          |
103/// | Region     | String | 必填,指定区域(例如:"ap-shanghai")           |
104/// | InstanceId | String | 必填,指定单个实例ID                           |
105/// | Body       | JSON   | 固定为 `{"InstanceId": "<实例ID>"}`            |
106///
107/// **出参说明**:
108///
109/// | 字段           | 类型   | 说明                                               |
110/// |----------------|--------|----------------------------------------------------|
111/// | InstanceVncUrl | String | 实例的管理终端地址(VNC 地址)                     |
112/// | RequestId      | String | 唯一请求ID,用于问题定位                           |
113pub async fn describe_instance_vnc_url(
114    client: &TencentCloudClient,
115    region: &str,
116    instance_id: &str,
117) -> Result<serde_json::Value, Box<dyn Error>> {
118    let payload = json!({ "InstanceId": instance_id }).to_string();
119
120    client.request(
121        "cvm",
122        "cvm.tencentcloudapi.com",
123        Some(region),
124        "2017-03-12",
125        "DescribeInstanceVncUrl",
126        &payload,
127    ).await
128}
129
130/// 启动实例 - StartInstances
131///
132/// **接口描述**:
133/// - 接口请求域名:cvm.tencentcloudapi.com
134/// - 默认接口请求频率限制:10次/秒
135///
136/// **入参说明**:
137///
138/// | 参数        | 类型   | 说明                                           |
139/// |-------------|--------|------------------------------------------------|
140/// | Action      | String | 固定为 `"StartInstances"`                       |
141/// | Version     | String | 固定为 `"2017-03-12"`                           |
142/// | Region      | String | 必填,指定区域(例如:"ap-shanghai")            |
143/// | InstanceIds | Array  | 必填,实例ID数组(最多支持100个实例ID)          |
144/// | Body        | JSON   | 由上述参数构成的 JSON 字符串                     |
145///
146/// **出参说明**:
147///
148/// | 字段     | 类型   | 说明           |
149/// |----------|--------|----------------|
150/// | RequestId| String | 唯一请求ID     |
151pub async fn start_instances(
152    client: &TencentCloudClient,
153    region: &str,
154    instance_ids: Vec<&str>,
155) -> Result<serde_json::Value, Box<dyn Error>> {
156    let payload = json!({ "InstanceIds": instance_ids }).to_string();
157
158    client.request(
159        "cvm",
160        "cvm.tencentcloudapi.com",
161        Some(region),
162        "2017-03-12",
163        "StartInstances",
164        &payload,
165    ).await
166}
167
168/// 重启实例 - RebootInstances
169///
170/// **接口描述**:
171/// - 接口请求域名:cvm.tencentcloudapi.com
172/// - 默认接口请求频率限制:10次/秒
173///
174/// **入参说明**:
175///
176/// | 参数        | 类型   | 说明                                               |
177/// |-------------|--------|----------------------------------------------------|
178/// | Action      | String | 固定为 `"RebootInstances"`                         |
179/// | Version     | String | 固定为 `"2017-03-12"`                              |
180/// | Region      | String | 必填,指定区域(例如:"ap-shanghai")               |
181/// | InstanceIds | Array  | 必填,实例ID数组(最多支持100个实例ID)             |
182/// | StopType    | String | 可选,实例关机类型,默认 `"SOFT"`                  |
183/// | Body        | JSON   | 由上述参数构成的 JSON 字符串                       |
184///
185/// **出参说明**:
186///
187/// | 字段     | 类型   | 说明           |
188/// |----------|--------|----------------|
189/// | RequestId| String | 唯一请求ID     |
190pub async fn reboot_instances(
191    client: &TencentCloudClient,
192    region: &str,
193    instance_ids: Vec<&str>,
194    stop_type: Option<&str>,
195) -> Result<serde_json::Value, Box<dyn Error>> {
196    let payload = {
197        let mut map = Map::new();
198        map.insert("InstanceIds".to_string(), json!(instance_ids));
199        map.insert("StopType".to_string(), json!(stop_type.unwrap_or("SOFT")));
200        Value::Object(map).to_string()
201    };
202
203    client.request(
204        "cvm",
205        "cvm.tencentcloudapi.com",
206        Some(region),
207        "2017-03-12",
208        "RebootInstances",
209        &payload,
210    ).await
211}
212
213/// 关闭实例 - StopInstances
214///
215/// **接口描述**:
216/// - 接口请求域名:cvm.tencentcloudapi.com
217/// - 默认接口请求频率限制:10次/秒
218///
219/// **入参说明**:
220///
221/// | 参数         | 类型   | 说明                                                         |
222/// |--------------|--------|--------------------------------------------------------------|
223/// | Action       | String | 固定为 `"StopInstances"`                                     |
224/// | Version      | String | 固定为 `"2017-03-12"`                                        |
225/// | Region       | String | 必填,指定区域(例如:"ap-shanghai")                         |
226/// | InstanceIds  | Array  | 必填,实例ID数组(最多支持100个实例ID)                       |
227/// | StopType     | String | 可选,实例关闭模式,默认 `"SOFT"`                           |
228/// | StoppedMode  | String | 可选,按量计费实例关机收费模式,默认 `"KEEP_CHARGING"`        |
229/// | Body         | JSON   | 由上述参数构成的 JSON 字符串                                  |
230///
231/// **出参说明**:
232///
233/// | 字段     | 类型   | 说明           |
234/// |----------|--------|----------------|
235/// | RequestId| String | 唯一请求ID     |
236pub async fn stop_instances(
237    client: &TencentCloudClient,
238    region: &str,
239    instance_ids: Vec<&str>,
240    stop_type: Option<&str>,
241    stopped_mode: Option<&str>,
242) -> Result<serde_json::Value, Box<dyn Error>> {
243    let payload = {
244        let mut map = Map::new();
245        map.insert("InstanceIds".to_string(), json!(instance_ids));
246        map.insert("StopType".to_string(), json!(stop_type.unwrap_or("SOFT")));
247        map.insert("StoppedMode".to_string(), json!(stopped_mode.unwrap_or("KEEP_CHARGING")));
248        Value::Object(map).to_string()
249    };
250
251    client.request(
252        "cvm",
253        "cvm.tencentcloudapi.com",
254        Some(region),
255        "2017-03-12",
256        "StopInstances",
257        &payload,
258    ).await
259}
260
261/// 修改实例所属项目 - ModifyInstancesProject
262///
263/// **接口描述**:
264/// - 接口请求域名:cvm.tencentcloudapi.com
265/// - 默认接口请求频率限制:10次/秒
266///
267/// **入参说明**:
268///
269/// | 参数        | 类型    | 说明                                                         |
270/// |-------------|---------|--------------------------------------------------------------|
271/// | Action      | String  | 固定为 `"ModifyInstancesProject"`                            |
272/// | Version     | String  | 固定为 `"2017-03-12"`                                         |
273/// | Region      | String  | 必填,指定区域(例如:"ap-shanghai")                          |
274/// | InstanceIds | Array   | 必填,实例ID数组(最多支持100个实例ID)                         |
275/// | ProjectId   | Integer | 必填,目标项目ID                                             |
276/// | Body        | JSON    | 由上述参数构成的 JSON 字符串                                  |
277///
278/// **出参说明**:
279///
280/// | 字段     | 类型   | 说明           |
281/// |----------|--------|----------------|
282/// | RequestId| String | 唯一请求ID     |
283pub async fn modify_instances_project(
284    client: &TencentCloudClient,
285    region: &str,
286    instance_ids: Vec<&str>,
287    project_id: i32,
288) -> Result<serde_json::Value, Box<dyn Error>> {
289    let payload = {
290        let mut map = Map::new();
291        map.insert("InstanceIds".to_string(), json!(instance_ids));
292        map.insert("ProjectId".to_string(), json!(project_id));
293        Value::Object(map).to_string()
294    };
295
296    client.request(
297        "cvm",
298        "cvm.tencentcloudapi.com",
299        Some(region),
300        "2017-03-12",
301        "ModifyInstancesProject",
302        &payload,
303    ).await
304}
305
306#[cfg(test)]
307mod tests {
308    use super::*;
309    use tokio;
310
311    const TEST_SECRET_ID: &str = "YourSecretId";
312    const TEST_SECRET_KEY: &str = "YourSecretKey";
313    const TEST_REGION: &str = "ap-shanghai";
314    // 示例实例ID、项目ID等,请根据实际情况修改
315    const TEST_INSTANCE_ID: &str = "ins-r9hr2upy";
316    const TEST_INSTANCE_IDS: &[&str] = &["ins-r8hr2upy", "ins-5d8a23rs"];
317    const TEST_PROJECT_ID: i32 = 1045;
318
319    #[tokio::test]
320    async fn test_describe_instances() {
321        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
322        match describe_instances(&client).await {
323            Ok(resp) => {
324                println!("DescribeInstances 响应:\n{}", resp);
325                assert!(!resp.is_null());
326            }
327            Err(e) => eprintln!("调用 DescribeInstances 时出错: {}", e),
328        }
329    }
330
331    #[tokio::test]
332    async fn test_reset_instances_password() {
333        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
334        let password = "abc123ABC!@#";
335        let username = Some("root"); // 根据实际系统调整
336        let force_stop = Some(true);
337        match reset_instances_password(
338            &client,
339            TEST_REGION,
340            TEST_INSTANCE_IDS.to_vec(),
341            password,
342            username,
343            force_stop,
344        ).await {
345            Ok(resp) => {
346                println!("ResetInstancesPassword 响应:\n{}", resp);
347                assert!(!resp.is_null());
348            }
349            Err(e) => eprintln!("调用 ResetInstancesPassword 时出错: {}", e),
350        }
351    }
352
353    #[tokio::test]
354    async fn test_describe_instance_vnc_url() {
355        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
356        match describe_instance_vnc_url(&client, TEST_REGION, TEST_INSTANCE_ID).await {
357            Ok(resp) => {
358                println!("DescribeInstanceVncUrl 响应:\n{}", resp);
359                assert!(!resp.is_null());
360            }
361            Err(e) => eprintln!("调用 DescribeInstanceVncUrl 时出错: {}", e),
362        }
363    }
364
365    #[tokio::test]
366    async fn test_start_instances() {
367        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
368        match start_instances(&client, TEST_REGION, TEST_INSTANCE_IDS.to_vec()).await {
369            Ok(resp) => {
370                println!("StartInstances 响应:\n{}", resp);
371                assert!(!resp.is_null());
372            }
373            Err(e) => eprintln!("调用 StartInstances 时出错: {}", e),
374        }
375    }
376
377    #[tokio::test]
378    async fn test_reboot_instances() {
379        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
380        match reboot_instances(&client, TEST_REGION, TEST_INSTANCE_IDS.to_vec(), Some("SOFT")).await {
381            Ok(resp) => {
382                println!("RebootInstances 响应:\n{}", resp);
383                assert!(!resp.is_null());
384            }
385            Err(e) => eprintln!("调用 RebootInstances 时出错: {}", e),
386        }
387    }
388
389    #[tokio::test]
390    async fn test_stop_instances() {
391        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
392        match stop_instances(&client, TEST_REGION, TEST_INSTANCE_IDS.to_vec(), Some("SOFT"), Some("KEEP_CHARGING")).await {
393            Ok(resp) => {
394                println!("StopInstances 响应:\n{}", resp);
395                assert!(!resp.is_null());
396            }
397            Err(e) => eprintln!("调用 StopInstances 时出错: {}", e),
398        }
399    }
400
401    #[tokio::test]
402    async fn test_modify_instances_project() {
403        let client = TencentCloudClient::new(TEST_SECRET_ID, TEST_SECRET_KEY, None);
404        match modify_instances_project(&client, TEST_REGION, TEST_INSTANCE_IDS.to_vec(), TEST_PROJECT_ID).await {
405            Ok(resp) => {
406                println!("ModifyInstancesProject 响应:\n{}", resp);
407                assert!(!resp.is_null());
408            }
409            Err(e) => eprintln!("调用 ModifyInstancesProject 时出错: {}", e),
410        }
411    }
412}