1use ntex::{io, rt, ws};
2
3use nanocl_error::http_client::HttpClientResult;
4use nanocl_error::io::FromIo;
5
6use nanocl_stubs::generic::{GenericFilterNsp, GenericNspQuery};
7use nanocl_stubs::vm::{Vm, VmInspect, VmSummary};
8use nanocl_stubs::vm_spec::{VmSpecPartial, VmSpecUpdate};
9
10use crate::NanocldClient;
11
12impl NanocldClient {
13 const VM_PATH: &'static str = "/vms";
15
16 pub async fn create_vm(
18 &self,
19 vm: &VmSpecPartial,
20 namespace: Option<&str>,
21 ) -> HttpClientResult<Vm> {
22 let res = self
23 .send_post(
24 Self::VM_PATH,
25 Some(vm),
26 Some(&GenericNspQuery::new(namespace)),
27 )
28 .await?;
29 Self::res_json(res).await
30 }
31
32 pub async fn list_vm(
43 &self,
44 query: Option<&GenericFilterNsp>,
45 ) -> HttpClientResult<Vec<VmSummary>> {
46 let query = Self::convert_query(query)?;
47 let res = self.send_get(Self::VM_PATH, Some(query)).await?;
48 Self::res_json(res).await
49 }
50
51 pub async fn delete_vm(
62 &self,
63 name: &str,
64 namespace: Option<&str>,
65 ) -> HttpClientResult<()> {
66 self
67 .send_delete(
68 &format!("{}/{name}", Self::VM_PATH),
69 Some(&GenericNspQuery::new(namespace)),
70 )
71 .await?;
72 Ok(())
73 }
74
75 pub async fn inspect_vm(
87 &self,
88 name: &str,
89 namespace: Option<&str>,
90 ) -> HttpClientResult<VmInspect> {
91 let res = self
92 .send_get(
93 &format!("{}/{name}/inspect", Self::VM_PATH),
94 Some(&GenericNspQuery::new(namespace)),
95 )
96 .await?;
97 Self::res_json(res).await
98 }
99
100 pub async fn patch_vm(
102 &self,
103 name: &str,
104 vm: &VmSpecUpdate,
105 namespace: Option<&str>,
106 ) -> HttpClientResult<()> {
107 self
108 .send_patch(
109 &format!("{}/{name}", Self::VM_PATH),
110 Some(vm),
111 Some(&GenericNspQuery::new(namespace)),
112 )
113 .await?;
114 Ok(())
115 }
116
117 pub async fn attach_vm(
129 &self,
130 name: &str,
131 namespace: Option<&str>,
132 ) -> HttpClientResult<ws::WsConnection<io::Base>> {
133 let qs = if let Some(namespace) = namespace {
134 format!("?Namespace={}", namespace)
135 } else {
136 "".to_owned()
137 };
138 let url = format!("{}/{}/vms/{name}/attach{qs}", self.url, &self.version);
139 #[cfg(not(target_os = "windows"))]
141 {
142 let con = match &self.unix_socket {
143 Some(path) => ws::WsClient::build(&url)
144 .connector(ntex::service::fn_service(|_| async move {
145 Ok::<_, _>(rt::unix_connect(&path).await?)
146 }))
147 .finish()
148 .map_err(|err| err.map_err_context(|| path))?
149 .connect()
150 .await
151 .map_err(|err| err.map_err_context(|| path))?,
152 None => ws::WsClient::build(&url)
153 .finish()
154 .map_err(|err| err.map_err_context(|| &self.url))?
155 .connect()
156 .await
157 .map_err(|err| err.map_err_context(|| &self.url))?,
158 };
159 Ok(con)
160 }
161 #[cfg(target_os = "windows")]
162 {
163 let con = ws::WsClient::build(&url)
164 .finish()
165 .map_err(|err| err.map_err_context(|| &self.url))?
166 .connect()
167 .await
168 .map_err(|err| err.map_err_context(|| &self.url))?;
169 Ok(con)
170 }
171 }
172}