Skip to main content

veilid_remote_api/
lib.rs

1//! # veilid-remote-api
2//!
3//! This crate provides the ability to control a Veilid node remotely.
4//!
5//! The [JsonRequestProcessor] is a wrapper around the [VeilidAPI] and provides a way to process requests and send responses.
6
7use veilid_core::tools::*;
8use veilid_core::*;
9
10use parking_lot::Mutex;
11use schemars::{schema_for, JsonSchema};
12use serde::{Deserialize, Serialize};
13use std::collections::HashMap;
14use std::fmt;
15use tracing::*;
16
17mod routing_context;
18pub use routing_context::*;
19
20mod table_db;
21pub use table_db::*;
22
23mod crypto_system;
24pub use crypto_system::*;
25
26mod dht_transaction;
27pub use dht_transaction::*;
28
29mod process;
30pub use process::*;
31
32#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
33pub struct Request {
34    /// Operation Id (pairs with Response, or empty if unidirectional).
35    #[serde(default)]
36    pub id: u32,
37    /// The request operation variant.
38    #[serde(flatten)]
39    pub op: RequestOp,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
43#[serde(tag = "type")]
44pub enum RecvMessage {
45    Response(Response),
46    Update(VeilidUpdate),
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct Response {
51    /// Operation Id (pairs with Request, or empty if unidirectional).
52    #[serde(default)]
53    pub id: u32,
54    /// The response operation variant.
55    #[serde(flatten)]
56    pub op: ResponseOp,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
60#[serde(tag = "op")]
61pub enum RequestOp {
62    Control {
63        args: Vec<String>,
64    },
65    GetState,
66    IsShutdown,
67    Attach,
68    Detach,
69    GenerateMemberId {
70        #[schemars(with = "String")]
71        writer_key: PublicKey,
72    },
73    GetDhtRecordKey {
74        schema: DHTSchema,
75        #[schemars(with = "String")]
76        owner: PublicKey,
77        #[schemars(with = "Option<String>")]
78        encryption_key: Option<SharedSecret>,
79    },
80    NewPrivateRoute,
81    NewCustomPrivateRoute {
82        #[schemars(with = "Vec<String>")]
83        kinds: Vec<CryptoKind>,
84        #[serde(default)]
85        stability: Stability,
86        #[serde(default)]
87        sequencing: Sequencing,
88    },
89    ImportRemotePrivateRoute {
90        #[serde(with = "as_human_base64")]
91        #[schemars(with = "String")]
92        blob: Vec<u8>,
93    },
94    ReleasePrivateRoute {
95        #[schemars(with = "String")]
96        route_id: RouteId,
97    },
98    AppCallReply {
99        #[schemars(with = "String")]
100        call_id: OperationId,
101        #[serde(with = "as_human_base64")]
102        #[schemars(with = "String")]
103        message: Vec<u8>,
104    },
105    // Routing Context
106    NewRoutingContext,
107    RoutingContext(RoutingContextRequest),
108    // DHT Transaction
109    TransactDhtRecords {
110        #[schemars(with = "Vec<String>")]
111        record_keys: Vec<RecordKey>,
112        options: Option<TransactDHTRecordsOptions>,
113    },
114    DhtTransaction(DhtTransactionRequest),
115    // TableDb
116    OpenTableDb {
117        name: String,
118        column_count: u32,
119    },
120    DeleteTableDb {
121        name: String,
122    },
123    TableDb(TableDbRequest),
124    TableDbTransaction(TableDbTransactionRequest),
125    // Crypto
126    GetCryptoSystem {
127        #[schemars(with = "String")]
128        kind: CryptoKind,
129    },
130    CryptoSystem(CryptoSystemRequest),
131    VerifySignatures {
132        #[schemars(with = "Vec<String>")]
133        node_ids: Vec<PublicKey>,
134        #[serde(with = "as_human_base64")]
135        #[schemars(with = "String")]
136        data: Vec<u8>,
137        #[schemars(with = "Vec<String>")]
138        signatures: Vec<Signature>,
139    },
140    GenerateSignatures {
141        #[serde(with = "as_human_base64")]
142        #[schemars(with = "String")]
143        data: Vec<u8>,
144        #[schemars(with = "Vec<String>")]
145        key_pairs: Vec<KeyPair>,
146    },
147    GenerateKeyPair {
148        #[schemars(with = "String")]
149        kind: CryptoKind,
150    },
151    // Misc
152    Now,
153    Debug {
154        command: String,
155    },
156    VeilidVersionString,
157    VeilidVersion,
158    VeilidFeatures,
159    DefaultVeilidConfig,
160    ValidCryptoKinds,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
164#[serde(tag = "op")]
165pub enum ResponseOp {
166    Control {
167        #[serde(flatten)]
168        result: ApiResult<String>,
169    },
170    GetState {
171        #[serde(flatten)]
172        result: ApiResult<Box<VeilidState>>,
173    },
174    IsShutdown {
175        value: bool,
176    },
177    Attach {
178        #[serde(flatten)]
179        result: ApiResult<()>,
180    },
181    Detach {
182        #[serde(flatten)]
183        result: ApiResult<()>,
184    },
185    GenerateMemberId {
186        #[serde(flatten)]
187        #[schemars(with = "ApiResult<String>")]
188        result: ApiResultWithString<MemberId>,
189    },
190    GetDhtRecordKey {
191        #[serde(flatten)]
192        #[schemars(with = "ApiResult<String>")]
193        result: ApiResultWithString<RecordKey>,
194    },
195    NewPrivateRoute {
196        #[serde(flatten)]
197        result: ApiResult<RouteBlob>,
198    },
199    NewCustomPrivateRoute {
200        #[serde(flatten)]
201        result: ApiResult<RouteBlob>,
202    },
203    ImportRemotePrivateRoute {
204        #[serde(flatten)]
205        #[schemars(with = "ApiResult<String>")]
206        result: ApiResultWithString<RouteId>,
207    },
208    ReleasePrivateRoute {
209        #[serde(flatten)]
210        result: ApiResult<()>,
211    },
212    AppCallReply {
213        #[serde(flatten)]
214        result: ApiResult<()>,
215    },
216    // Routing Context
217    NewRoutingContext {
218        #[serde(flatten)]
219        result: ApiResult<u32>,
220    },
221    RoutingContext(Box<RoutingContextResponse>),
222    // DHT Transaction
223    TransactDhtRecords {
224        #[serde(flatten)]
225        result: ApiResult<u32>,
226    },
227    DhtTransaction(Box<DhtTransactionResponse>),
228    // TableDb
229    OpenTableDb {
230        #[serde(flatten)]
231        result: ApiResult<u32>,
232    },
233    DeleteTableDb {
234        #[serde(flatten)]
235        result: ApiResult<bool>,
236    },
237    TableDb(TableDbResponse),
238    TableDbTransaction(TableDbTransactionResponse),
239    // Crypto
240    GetCryptoSystem {
241        #[serde(flatten)]
242        result: ApiResult<u32>,
243    },
244    BestCryptoSystem {
245        #[serde(flatten)]
246        result: ApiResult<u32>,
247    },
248    CryptoSystem(CryptoSystemResponse),
249    VerifySignatures {
250        #[serde(flatten)]
251        #[schemars(with = "ApiResult<Option<Vec<String>>>")]
252        result: ApiResultWithOptVecString<Option<PublicKeyGroup>>,
253    },
254    GenerateSignatures {
255        #[serde(flatten)]
256        #[schemars(with = "ApiResult<Vec<String>>")]
257        result: ApiResultWithVecString<Vec<Signature>>,
258    },
259    GenerateKeyPair {
260        #[serde(flatten)]
261        #[schemars(with = "ApiResult<String>")]
262        result: ApiResultWithString<KeyPair>,
263    },
264    // Misc
265    Now {
266        #[schemars(with = "String")]
267        value: Timestamp,
268    },
269    Debug {
270        #[serde(flatten)]
271        result: ApiResult<String>,
272    },
273    VeilidVersionString {
274        value: String,
275    },
276    VeilidVersion {
277        major: u32,
278        minor: u32,
279        patch: u32,
280    },
281    DefaultVeilidConfig {
282        value: String,
283    },
284    VeilidFeatures {
285        value: Vec<String>,
286    },
287    ValidCryptoKinds {
288        #[schemars(with = "Vec<String>")]
289        value: Vec<CryptoKind>,
290    },
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
294#[serde(untagged)]
295pub enum ApiResult<T>
296where
297    T: Clone + fmt::Debug + JsonSchema,
298{
299    Ok { value: T },
300    Err { error: VeilidAPIError },
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
304#[serde(untagged)]
305pub enum ApiResultWithString<T>
306where
307    T: Clone + fmt::Debug,
308{
309    Ok {
310        #[schemars(with = "String")]
311        value: T,
312    },
313    Err {
314        error: VeilidAPIError,
315    },
316}
317
318#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
319#[serde(untagged)]
320pub enum ApiResultWithVecU8 {
321    Ok {
322        #[serde(with = "as_human_base64")]
323        #[schemars(with = "String")]
324        value: Vec<u8>,
325    },
326    Err {
327        error: VeilidAPIError,
328    },
329}
330#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
331#[serde(transparent)]
332pub struct VecU8 {
333    #[serde(with = "as_human_base64")]
334    #[schemars(with = "String")]
335    value: Vec<u8>,
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
339#[serde(untagged)]
340pub enum ApiResultWithVecVecU8 {
341    Ok {
342        #[schemars(with = "Vec<String>")]
343        value: Vec<VecU8>,
344    },
345    Err {
346        error: VeilidAPIError,
347    },
348}
349
350#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
351#[serde(untagged)]
352pub enum ApiResultWithVecString<T>
353where
354    T: Clone + fmt::Debug,
355{
356    Ok {
357        #[schemars(with = "Vec<String>")]
358        value: T,
359    },
360    Err {
361        error: VeilidAPIError,
362    },
363}
364
365#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
366#[serde(untagged)]
367pub enum ApiResultWithOptVecString<T>
368where
369    T: Clone + fmt::Debug,
370{
371    Ok {
372        #[schemars(with = "Option<Vec<String>>")]
373        value: T,
374    },
375    Err {
376        error: VeilidAPIError,
377    },
378}
379
380pub fn emit_schemas(out: &mut HashMap<String, String>) {
381    let schema_request = schema_for!(Request);
382    let schema_recv_message = schema_for!(RecvMessage);
383
384    out.insert(
385        "Request".to_owned(),
386        serde_json::to_string_pretty(&schema_request).unwrap_or_log(),
387    );
388
389    out.insert(
390        "RecvMessage".to_owned(),
391        serde_json::to_string_pretty(&schema_recv_message).unwrap_or_log(),
392    );
393}