|
1 | | -use crate::{ApiConfig, ApiResponse, Breeder, BreederCreateRequest, BreederSummary, BreederUpdateRequest, Credential}; |
| 1 | +use crate::{ApiConfig, ApiResponse, Breeder, BreederCreateRequest, BreederSummary, BreederUpdateRequest, Credential, Target}; |
2 | 2 | use anyhow::{Context, Result}; |
3 | 3 | use reqwest::Client; |
4 | 4 | use std::time::Duration; |
@@ -387,4 +387,171 @@ impl GodonClient { |
387 | 387 |
|
388 | 388 | self.create_credential(credential_data).await |
389 | 389 | } |
| 390 | + |
| 391 | + pub async fn list_targets(&self) -> ApiResponse<Vec<Target>> { |
| 392 | + let url = format!("{}/targets", self.base_url()); |
| 393 | + |
| 394 | + match self.client.get(&url).send().await { |
| 395 | + Ok(response) => { |
| 396 | + let status = response.status(); |
| 397 | + |
| 398 | + if status.is_success() { |
| 399 | + match response.text().await { |
| 400 | + Ok(body) => { |
| 401 | + let json: serde_json::Value = match serde_json::from_str(&body) { |
| 402 | + Ok(j) => j, |
| 403 | + Err(e) => return ApiResponse::error(format!("JSON parse error: {}", e)), |
| 404 | + }; |
| 405 | + |
| 406 | + let targets: Vec<Target> = if json.is_array() { |
| 407 | + match serde_json::from_value(json) { |
| 408 | + Ok(t) => t, |
| 409 | + Err(e) => return ApiResponse::error(format!("Parse error: {}", e)), |
| 410 | + } |
| 411 | + } else if let Some(arr) = json.get("targets") { |
| 412 | + match serde_json::from_value(arr.clone()) { |
| 413 | + Ok(t) => t, |
| 414 | + Err(e) => return ApiResponse::error(format!("Parse error: {}", e)), |
| 415 | + } |
| 416 | + } else { |
| 417 | + return ApiResponse::error("Unexpected response format"); |
| 418 | + }; |
| 419 | + |
| 420 | + ApiResponse::success(targets) |
| 421 | + } |
| 422 | + Err(e) => ApiResponse::error(e.to_string()), |
| 423 | + } |
| 424 | + } else { |
| 425 | + ApiResponse::error(format!("HTTP Error: {}", status)) |
| 426 | + } |
| 427 | + } |
| 428 | + Err(e) => ApiResponse::error(e.to_string()), |
| 429 | + } |
| 430 | + } |
| 431 | + |
| 432 | + pub async fn create_target(&self, target_data: serde_json::Value) -> ApiResponse<Target> { |
| 433 | + let url = format!("{}/targets", self.base_url()); |
| 434 | + |
| 435 | + match self.client |
| 436 | + .post(&url) |
| 437 | + .json(&target_data) |
| 438 | + .send() |
| 439 | + .await |
| 440 | + { |
| 441 | + Ok(response) => { |
| 442 | + let status = response.status(); |
| 443 | + |
| 444 | + if status.is_success() { |
| 445 | + match response.text().await { |
| 446 | + Ok(body) => { |
| 447 | + match serde_json::from_str::<Target>(&body) { |
| 448 | + Ok(target) => ApiResponse::success(target), |
| 449 | + Err(e) => ApiResponse::error(format!("Parse error: {}", e)), |
| 450 | + } |
| 451 | + } |
| 452 | + Err(e) => ApiResponse::error(e.to_string()), |
| 453 | + } |
| 454 | + } else { |
| 455 | + ApiResponse::error(format!("HTTP Error: {}", status)) |
| 456 | + } |
| 457 | + } |
| 458 | + Err(e) => ApiResponse::error(e.to_string()), |
| 459 | + } |
| 460 | + } |
| 461 | + |
| 462 | + pub async fn get_target(&self, target_id: &str) -> ApiResponse<Target> { |
| 463 | + let url = format!("{}/targets/{}", self.base_url(), urlencoding::encode(target_id)); |
| 464 | + |
| 465 | + match self.client.get(&url).send().await { |
| 466 | + Ok(response) => { |
| 467 | + let status = response.status(); |
| 468 | + |
| 469 | + if status.is_success() { |
| 470 | + match response.text().await { |
| 471 | + Ok(body) => { |
| 472 | + match serde_json::from_str::<Target>(&body) { |
| 473 | + Ok(target) => ApiResponse::success(target), |
| 474 | + Err(e) => ApiResponse::error(format!("Parse error: {}", e)), |
| 475 | + } |
| 476 | + } |
| 477 | + Err(e) => ApiResponse::error(e.to_string()), |
| 478 | + } |
| 479 | + } else { |
| 480 | + ApiResponse::error(format!("HTTP Error: {}", status)) |
| 481 | + } |
| 482 | + } |
| 483 | + Err(e) => ApiResponse::error(e.to_string()), |
| 484 | + } |
| 485 | + } |
| 486 | + |
| 487 | + pub async fn delete_target(&self, target_id: &str) -> ApiResponse<serde_json::Value> { |
| 488 | + let url = format!("{}/targets/{}", self.base_url(), urlencoding::encode(target_id)); |
| 489 | + |
| 490 | + match self.client.delete(&url).send().await { |
| 491 | + Ok(response) => { |
| 492 | + let status = response.status(); |
| 493 | + |
| 494 | + if status.is_success() { |
| 495 | + match response.text().await { |
| 496 | + Ok(body) => { |
| 497 | + match serde_json::from_str(&body) { |
| 498 | + Ok(v) => ApiResponse::success(v), |
| 499 | + Err(e) => ApiResponse::error(format!("Parse error: {}", e)), |
| 500 | + } |
| 501 | + } |
| 502 | + Err(e) => ApiResponse::error(e.to_string()), |
| 503 | + } |
| 504 | + } else { |
| 505 | + ApiResponse::error(format!("HTTP Error: {}", status)) |
| 506 | + } |
| 507 | + } |
| 508 | + Err(e) => ApiResponse::error(e.to_string()), |
| 509 | + } |
| 510 | + } |
| 511 | + |
| 512 | + pub async fn create_target_from_yaml(&self, yaml_content: &str) -> ApiResponse<Target> { |
| 513 | + let yaml_data: std::collections::HashMap<String, serde_yaml::Value> = match serde_yaml::from_str(yaml_content) { |
| 514 | + Ok(d) => d, |
| 515 | + Err(e) => return ApiResponse::error(format!("YAML parse error: {}", e)), |
| 516 | + }; |
| 517 | + |
| 518 | + let name = match yaml_data.get("name").and_then(|v| v.as_str()) { |
| 519 | + Some(n) => n.to_string(), |
| 520 | + None => return ApiResponse::error("Missing required field: name"), |
| 521 | + }; |
| 522 | + |
| 523 | + let target_type = match yaml_data.get("targetType").and_then(|v| v.as_str()) { |
| 524 | + Some(t) => t.to_string(), |
| 525 | + None => return ApiResponse::error("Missing required field: targetType"), |
| 526 | + }; |
| 527 | + |
| 528 | + let address = match yaml_data.get("address").and_then(|v| v.as_str()) { |
| 529 | + Some(a) => a.to_string(), |
| 530 | + None => return ApiResponse::error("Missing required field: address"), |
| 531 | + }; |
| 532 | + |
| 533 | + let mut target_data = serde_json::json!({ |
| 534 | + "name": name, |
| 535 | + "targetType": target_type, |
| 536 | + "address": address |
| 537 | + }); |
| 538 | + |
| 539 | + if let Some(v) = yaml_data.get("username").and_then(|v| v.as_str()) { |
| 540 | + target_data["username"] = serde_json::Value::String(v.to_string()); |
| 541 | + } |
| 542 | + if let Some(v) = yaml_data.get("credentialId").and_then(|v| v.as_str()) { |
| 543 | + target_data["credentialId"] = serde_json::Value::String(v.to_string()); |
| 544 | + } |
| 545 | + if let Some(v) = yaml_data.get("credentialName").and_then(|v| v.as_str()) { |
| 546 | + target_data["credentialName"] = serde_json::Value::String(v.to_string()); |
| 547 | + } |
| 548 | + if let Some(v) = yaml_data.get("description").and_then(|v| v.as_str()) { |
| 549 | + target_data["description"] = serde_json::Value::String(v.to_string()); |
| 550 | + } |
| 551 | + if let Some(v) = yaml_data.get("allowsDowntime").and_then(|v| v.as_bool()) { |
| 552 | + target_data["allowsDowntime"] = serde_json::Value::Bool(v); |
| 553 | + } |
| 554 | + |
| 555 | + self.create_target(target_data).await |
| 556 | + } |
390 | 557 | } |
0 commit comments