aboutsummaryrefslogtreecommitdiffstats
path: root/zoned/src/lib.rs
blob: f8c78dbee385fe6db1b353d80f66c917b5e119db (plain)
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
use figment::Provider;
use rocket::{get, post, serde::json::Json, Build, Rocket, State};
use rocket_okapi::{
    openapi, openapi_get_routes,
    rapidoc::{make_rapidoc, GeneralConfig, HideShowConfig, RapiDocConfig},
    settings::UrlObject,
    swagger_ui::{make_swagger_ui, SwaggerUIConfig},
};
use serde::{Deserialize, Serialize};
use zone_core::{Container, PartialEqOrDefault};

#[derive(Default, Serialize, Deserialize)]
pub struct Config {
    pub rocket_config: rocket::Config,

    pub zfs_config: zone_zfs::Config,
}

impl Config {
    pub fn new() -> Result<Config, figment::Error> {
        Config::custom(zone_zfs::Config::figment(), rocket::Config::figment())
    }

    pub fn custom<T: Provider, U: Provider>(
        zfs_provider: T,
        rocket_provider: U,
    ) -> Result<Config, figment::Error> {
        Ok(Config {
            rocket_config: rocket::Config::from(&rocket_provider),
            zfs_config: zone_zfs::Config::from(&zfs_provider)?,
        })
    }
}

/// # Test endpoint
///
/// Returns a list of containers based on the query.
#[openapi(tag = "Testing")]
#[get("/test")]
pub fn test_endpoint(zfs_config: &State<zone_zfs::Config>) -> Json<String> {
    Json(zfs_config.quota.to_owned())
}

/// # List containers
///
/// Returns a list of containers based on the query.
#[openapi(tag = "Container")]
#[get("/container/list?<container..>")]
pub fn container_list(container: Container) -> Json<Vec<Container>> {
    zone_nspawn::get_containers()
        .iter()
        .filter(|c| container.eq_or_default(c))
        .cloned()
        .collect::<Vec<Container>>()
        .into()
}

/// # Create container
#[openapi(tag = "Container")]
#[post("/container", data = "<container>")]
fn create_container(
    container: Json<Container>,
    zfs_config: &State<zone_zfs::Config>,
) -> Json<Container> {
    // let zone_config = ZoneConf::new().unwrap();
    let container = zone_zfs::create_file_system(
        container.template.clone(),
        format!("{}-{}", container.user, container.id),
        zfs_config,
    );

    match container {
        Ok(c) => Json(c.into()),
        Err(_err) => todo!("Respond with error message"),
    }
}

pub fn build_rocket(config: Config) -> Rocket<Build> {
    rocket::custom(config.rocket_config)
        .mount(
            "/",
            openapi_get_routes![test_endpoint, container_list, create_container,],
        )
        .mount(
            "/swagger-ui/",
            make_swagger_ui(&SwaggerUIConfig {
                url: "../openapi.json".to_owned(),
                ..Default::default()
            }),
        )
        .mount(
            "/rapidoc/",
            make_rapidoc(&RapiDocConfig {
                general: GeneralConfig {
                    spec_urls: vec![UrlObject::new("General", "../openapi.json")],
                    ..Default::default()
                },
                hide_show: HideShowConfig {
                    allow_spec_url_load: false,
                    allow_spec_file_load: false,
                    ..Default::default()
                },
                ..Default::default()
            }),
        )
        .manage(config.zfs_config)
}