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}