diff options
Diffstat (limited to 'src/routes/start.rs')
-rw-r--r-- | src/routes/start.rs | 106 |
1 files changed, 98 insertions, 8 deletions
diff --git a/src/routes/start.rs b/src/routes/start.rs index ef6e8f2..ff3d1be 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs | |||
@@ -2,27 +2,28 @@ use crate::db::Device; | |||
2 | use crate::error::Error; | 2 | use crate::error::Error; |
3 | use crate::services::ping::Value as PingValue; | 3 | use crate::services::ping::Value as PingValue; |
4 | use crate::wol::{create_buffer, send_packet}; | 4 | use crate::wol::{create_buffer, send_packet}; |
5 | use axum::extract::State; | 5 | use axum::extract::{Path, State}; |
6 | use axum::Json; | 6 | use axum::Json; |
7 | use serde::{Deserialize, Serialize}; | 7 | use serde::{Deserialize, Serialize}; |
8 | use serde_json::{json, Value}; | 8 | use serde_json::{json, Value}; |
9 | use utoipa::ToSchema; | ||
10 | use std::sync::Arc; | 9 | use std::sync::Arc; |
11 | use tracing::{debug, info}; | 10 | use tracing::{debug, info}; |
11 | use utoipa::ToSchema; | ||
12 | use uuid::Uuid; | 12 | use uuid::Uuid; |
13 | 13 | ||
14 | #[utoipa::path( | 14 | #[utoipa::path( |
15 | post, | 15 | post, |
16 | path = "/start", | 16 | path = "/start", |
17 | request_body = Payload, | 17 | request_body = PayloadOld, |
18 | responses( | 18 | responses( |
19 | (status = 200, description = "List matching todos by query", body = [Response]) | 19 | (status = 200, description = "DEP", body = [Response]) |
20 | ), | 20 | ), |
21 | security(("api_key" = [])) | 21 | security((), ("api_key" = [])) |
22 | )] | 22 | )] |
23 | pub async fn start( | 23 | #[deprecated] |
24 | pub async fn start_payload( | ||
24 | State(state): State<Arc<crate::AppState>>, | 25 | State(state): State<Arc<crate::AppState>>, |
25 | Json(payload): Json<Payload>, | 26 | Json(payload): Json<PayloadOld>, |
26 | ) -> Result<Json<Value>, Error> { | 27 | ) -> Result<Json<Value>, Error> { |
27 | info!("POST request"); | 28 | info!("POST request"); |
28 | let device = sqlx::query_as!( | 29 | let device = sqlx::query_as!( |
@@ -59,6 +60,89 @@ pub async fn start( | |||
59 | }))) | 60 | }))) |
60 | } | 61 | } |
61 | 62 | ||
63 | #[utoipa::path( | ||
64 | post, | ||
65 | path = "/start/{id}", | ||
66 | request_body = Option<Payload>, | ||
67 | responses( | ||
68 | (status = 200, description = "start the device with the given id", body = [Response]) | ||
69 | ), | ||
70 | params( | ||
71 | ("id" = String, Path, description = "device id") | ||
72 | ), | ||
73 | security((), ("api_key" = [])) | ||
74 | )] | ||
75 | pub async fn post( | ||
76 | State(state): State<Arc<crate::AppState>>, | ||
77 | Path(id): Path<String>, | ||
78 | payload: Option<Json<Payload>>, | ||
79 | ) -> Result<Json<Value>, Error> { | ||
80 | send_wol(state, &id, payload).await | ||
81 | } | ||
82 | |||
83 | #[utoipa::path( | ||
84 | get, | ||
85 | path = "/start/{id}", | ||
86 | responses( | ||
87 | (status = 200, description = "start the device with the given id", body = [Response]) | ||
88 | ), | ||
89 | params( | ||
90 | ("id" = String, Path, description = "device id") | ||
91 | ), | ||
92 | security((), ("api_key" = [])) | ||
93 | )] | ||
94 | pub async fn get( | ||
95 | State(state): State<Arc<crate::AppState>>, | ||
96 | Path(id): Path<String>, | ||
97 | ) -> Result<Json<Value>, Error> { | ||
98 | send_wol(state, &id, None).await | ||
99 | } | ||
100 | |||
101 | async fn send_wol( | ||
102 | state: Arc<crate::AppState>, | ||
103 | id: &str, | ||
104 | payload: Option<Json<Payload>>, | ||
105 | ) -> Result<Json<Value>, Error> { | ||
106 | info!("Start request for {id}"); | ||
107 | let device = sqlx::query_as!( | ||
108 | Device, | ||
109 | r#" | ||
110 | SELECT id, mac, broadcast_addr, ip, times | ||
111 | FROM devices | ||
112 | WHERE id = $1; | ||
113 | "#, | ||
114 | id | ||
115 | ) | ||
116 | .fetch_one(&state.db) | ||
117 | .await?; | ||
118 | |||
119 | info!("starting {}", device.id); | ||
120 | |||
121 | let bind_addr = "0.0.0.0:0"; | ||
122 | |||
123 | let _ = send_packet( | ||
124 | bind_addr, | ||
125 | &device.broadcast_addr, | ||
126 | &create_buffer(&device.mac.to_string())?, | ||
127 | )?; | ||
128 | let dev_id = device.id.clone(); | ||
129 | let uuid = if let Some(pl) = payload { | ||
130 | if pl.ping.is_some_and(|ping| ping) { | ||
131 | Some(setup_ping(state, device)) | ||
132 | } else { | ||
133 | None | ||
134 | } | ||
135 | } else { | ||
136 | None | ||
137 | }; | ||
138 | |||
139 | Ok(Json(json!(Response { | ||
140 | id: dev_id, | ||
141 | boot: true, | ||
142 | uuid | ||
143 | }))) | ||
144 | } | ||
145 | |||
62 | fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { | 146 | fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { |
63 | let mut uuid: Option<String> = None; | 147 | let mut uuid: Option<String> = None; |
64 | for (key, value) in state.ping_map.clone() { | 148 | for (key, value) in state.ping_map.clone() { |
@@ -99,11 +183,17 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { | |||
99 | } | 183 | } |
100 | 184 | ||
101 | #[derive(Deserialize, ToSchema)] | 185 | #[derive(Deserialize, ToSchema)] |
102 | pub struct Payload { | 186 | #[deprecated] |
187 | pub struct PayloadOld { | ||
103 | id: String, | 188 | id: String, |
104 | ping: Option<bool>, | 189 | ping: Option<bool>, |
105 | } | 190 | } |
106 | 191 | ||
192 | #[derive(Deserialize, ToSchema)] | ||
193 | pub struct Payload { | ||
194 | ping: Option<bool>, | ||
195 | } | ||
196 | |||
107 | #[derive(Serialize, ToSchema)] | 197 | #[derive(Serialize, ToSchema)] |
108 | pub struct Response { | 198 | pub struct Response { |
109 | id: String, | 199 | id: String, |