1use std::collections::HashMap;
2use std::sync::Arc;
3
4use crate::errors::VolumeResponse;
5use async_trait::async_trait;
6use axum::extract::State;
7use axum::Json;
8use serde_derive::{Deserialize, Serialize};
9use serde_json::{from_str, Value};
10
11const ACTIVATE_RESPONSE: &str = r#"{"Implements": ["VolumeDriver"]}"#;
12
13#[async_trait]
14pub trait VolumeDriver: Send + Sync + 'static {
15 async fn activate() -> Json<Value> {
16 Json(from_str(ACTIVATE_RESPONSE).unwrap())
17 }
18 async fn create(
19 driver: State<Arc<Self>>,
20 request: Json<CreateRequest>,
21 ) -> VolumeResponse<Json<NullResponse>>;
22 async fn remove(
23 driver: State<Arc<Self>>,
24 request: Json<RemoveRequest>,
25 ) -> VolumeResponse<Json<NullResponse>>;
26 async fn mount(
27 driver: State<Arc<Self>>,
28 request: Json<MountRequest>,
29 ) -> VolumeResponse<Json<MountResponse>>;
30 async fn unmount(
31 driver: State<Arc<Self>>,
32 request: Json<UnmountRequest>,
33 ) -> VolumeResponse<Json<NullResponse>>;
34 async fn path(
35 driver: State<Arc<Self>>,
36 request: Json<PathRequest>,
37 ) -> VolumeResponse<Json<PathResponse>>;
38 async fn get(
39 driver: State<Arc<Self>>,
40 request: Json<GetRequest>,
41 ) -> VolumeResponse<Json<GetResponse>>;
42 async fn list(driver: State<Arc<Self>>) -> VolumeResponse<Json<ListResponse>>;
43 async fn capabilities(driver: State<Arc<Self>>) -> VolumeResponse<Json<CapabilitiesResponse>>;
44}
45
46#[derive(Serialize, Deserialize, Clone, Debug)]
47pub struct CreateRequest {
48 #[serde(alias = "Name")]
49 pub name: String,
50 #[serde(alias = "Opts")]
51 pub options: HashMap<String, String>,
52}
53
54#[derive(Serialize, Deserialize, Clone, Debug)]
55pub struct RemoveRequest {
56 #[serde(alias = "Name")]
57 pub name: String,
58}
59
60#[derive(Serialize, Deserialize, Clone, Debug)]
61pub struct MountRequest {
62 #[serde(alias = "Name")]
63 pub name: String,
64 #[serde(alias = "ID")]
65 pub id: String,
66}
67
68#[derive(Serialize, Deserialize, Clone, Debug)]
69pub struct MountResponse {
70 #[serde(rename = "Mountpoint")]
71 pub mountpoint: String,
72}
73
74#[derive(Serialize, Deserialize, Clone, Debug)]
75pub struct UnmountRequest {
76 #[serde(alias = "Name")]
77 pub name: String,
78 #[serde(alias = "ID")]
79 pub id: String,
80}
81
82#[derive(Serialize, Deserialize, Clone, Debug)]
83pub struct PathRequest {
84 #[serde(alias = "Name")]
85 pub name: String,
86}
87
88#[derive(Serialize, Deserialize, Clone, Debug)]
89pub struct PathResponse {
90 #[serde(rename = "Mountpoint")]
91 pub mountpoint: String,
92}
93
94#[derive(Serialize, Deserialize, Clone, Debug)]
95pub struct GetRequest {
96 #[serde(alias = "Name")]
97 pub name: String,
98}
99
100#[derive(Serialize, Deserialize, Clone, Debug)]
101pub struct GetResponse {
102 #[serde(rename = "Volume")]
103 pub volume: Option<Volume>,
104}
105
106#[derive(Serialize, Deserialize, Clone, Debug)]
107pub struct ListResponse {
108 #[serde(rename = "Volumes")]
109 pub volumes: Vec<Volume>,
110}
111#[derive(Serialize, Deserialize, Clone, Debug)]
112pub struct Volume {
113 #[serde(rename = "Name")]
114 pub name: String,
115 #[serde(rename = "Mountpoint")]
116 pub mountpoint: String,
117 #[serde(rename = "Status")]
118 pub status: HashMap<String, String>,
119}
120
121#[derive(Serialize, Deserialize, Clone, Debug)]
122pub struct CapabilitiesResponse {
123 #[serde(rename = "Capabilities")]
124 pub capabilities: Capability,
125}
126
127#[derive(Serialize, Deserialize, Clone, Debug)]
128pub struct Capability {
129 #[serde(rename = "Scope")]
130 pub scope: Scope,
131}
132
133#[derive(Serialize, Deserialize, Clone, Debug)]
134#[serde(rename_all = "camelCase")]
135pub enum Scope {
136 Local,
137 Global,
138}
139
140#[derive(Serialize, Deserialize, Clone, Debug)]
141pub struct NullResponse {}