fly_sdk/
apps.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::API_BASE_URL;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::error::Error;

#[derive(Serialize, Deserialize, Debug)]
pub struct AppResponse {
    pub id: String,
    pub created_at: u64,
}

#[derive(Serialize, Deserialize, Debug)]
struct AppsResponse {
    pub total_apps: u64,
    pub apps: Vec<App>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct App {
    pub id: String,
    pub name: String,
    pub machine_count: u64,
    pub network: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Organization {
    pub name: String,
    pub slug: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CreateAppRequest {
    pub app_name: String,
    pub org_slug: String,
}

pub struct AppManager {
    client: Client,
    api_token: String,
}

impl AppManager {
    pub fn new(client: Client, api_token: String) -> Self {
        Self { client, api_token }
    }

    pub async fn create(
        &self,
        app_name: &str,
        org_slug: &str,
    ) -> Result<AppResponse, Box<dyn Error>> {
        let url = format!("{}/apps", API_BASE_URL);
        let request_body = CreateAppRequest {
            app_name: app_name.to_string(),
            org_slug: org_slug.to_string(),
        };

        let response = self
            .client
            .post(&url)
            .bearer_auth(&self.api_token)
            .header("Content-Type", "application/json")
            .json(&request_body)
            .send()
            .await?;

        if response.status() == reqwest::StatusCode::CREATED {
            let response_text = response.text().await?;
            let app_response: AppResponse = serde_json::from_str(&response_text)?;
            println!("Created app: {:?}", app_response);
            Ok(app_response)
        } else {
            let error_message = response.text().await?;
            println!("Error response: {}", error_message);
            Err(Box::new(std::io::Error::new(
                std::io::ErrorKind::Other,
                "App creation failed",
            )))
        }
    }

    pub async fn delete(&self, app_name: &str, force: bool) -> Result<(), Box<dyn Error>> {
        let url = if force {
            format!("{}/apps/{}?force=true", API_BASE_URL, app_name)
        } else {
            format!("{}/apps/{}", API_BASE_URL, app_name)
        };

        let response = self
            .client
            .delete(&url)
            .bearer_auth(&self.api_token)
            .send()
            .await?;

        if response.status() == reqwest::StatusCode::ACCEPTED {
            println!("Deleted app {}", app_name);
        } else {
            println!("Failed to delete {}: {:?}", app_name, response.status());
        }

        Ok(())
    }

    pub async fn list(&self, org_slug: &str) -> Result<Vec<App>, Box<dyn Error>> {
        let url = format!("{}/apps?org_slug={}", API_BASE_URL, org_slug);

        let response = self
            .client
            .get(&url)
            .bearer_auth(&self.api_token)
            .send()
            .await?;

        if response.status() == reqwest::StatusCode::OK {
            let response_text = response.text().await?;
            let apps_response: AppsResponse = serde_json::from_str(&response_text)?;
            println!("List of apps: {:?}", apps_response.apps);
            Ok(apps_response.apps)
        } else {
            println!("Failed to list apps: {:?}", response.status());
            Err(Box::new(std::io::Error::new(
                std::io::ErrorKind::Other,
                "Failed to list apps",
            )))
        }
    }
}