generated from Patagia/template-nix
WIP: onboard API #6
6 changed files with 178 additions and 0 deletions
95
Cargo.lock
generated
95
Cargo.lock
generated
|
@ -421,6 +421,41 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "debug-ignore"
|
||||
version = "1.0.5"
|
||||
|
@ -1099,6 +1134,12 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.0.3"
|
||||
|
@ -1590,10 +1631,12 @@ dependencies = [
|
|||
"serde",
|
||||
"slog",
|
||||
"slog-async",
|
||||
"thiserror 2.0.7",
|
||||
"tokio",
|
||||
"trace-request",
|
||||
"tracing",
|
||||
"tracing-slog",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1655,6 +1698,28 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.92"
|
||||
|
@ -3027,6 +3092,36 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0b4a29d8709210980a09379f27ee31549b73292c87ab9899beee1c0d3be6303"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url",
|
||||
"validator_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator_derive"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bac855a2ce6f843beb229757e6e570a42e837bcb15e5f449dd48d5747d41bf77"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"once_cell",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -46,6 +46,7 @@ semver = "1.0.24"
|
|||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
slog = "2.7.0"
|
||||
slog-async = "2.8.0"
|
||||
thiserror = "2"
|
||||
tokio = { version = "1.42.0", features = ["full"] }
|
||||
tonic = "0.12.3"
|
||||
tracing = "0.1.41"
|
||||
|
@ -60,3 +61,4 @@ tracing-subscriber = { version = "0.3.19", default-features = false, features =
|
|||
"fmt",
|
||||
] }
|
||||
uuid = { version = "1", features = [ "serde", "v4" ] }
|
||||
validator = { version = "0.19", features = ["derive"] }
|
||||
|
|
|
@ -15,10 +15,12 @@ schemars.workspace = true
|
|||
serde.workspace = true
|
||||
slog-async.workspace = true
|
||||
slog.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
trace-request = { path = "../trace-request" }
|
||||
tracing-slog.workspace = true
|
||||
tracing.workspace = true
|
||||
validator.workspace = true
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["http"]
|
||||
|
|
|
@ -4,6 +4,7 @@ use dropshot::ApiDescription;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::context::ControllerContext;
|
||||
use crate::onboard;
|
||||
use crate::version;
|
||||
|
||||
type ControllerApiDescription = ApiDescription<Arc<ControllerContext>>;
|
||||
|
@ -11,5 +12,6 @@ type ControllerApiDescription = ApiDescription<Arc<ControllerContext>>;
|
|||
pub fn api() -> Result<ControllerApiDescription> {
|
||||
let mut api = ControllerApiDescription::new();
|
||||
api.register(version::version)?;
|
||||
api.register(onboard::onboard)?;
|
||||
Ok(api)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod api;
|
||||
pub mod context;
|
||||
|
||||
mod onboard;
|
||||
mod version;
|
||||
|
|
76
controller/src/onboard.rs
Normal file
76
controller/src/onboard.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use dropshot::{endpoint, HttpError, HttpResponseOk, RequestContext, TypedBody};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use trace_request::trace_request;
|
||||
use validator::Validate;
|
||||
|
||||
use std::result::Result;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::context::ControllerContext;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Validate)]
|
||||
pub struct OnboardRequest {
|
||||
#[validate(nested)]
|
||||
ownership_voucher: OwnershipVoucher,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Validate)]
|
||||
pub struct OwnershipVoucher {
|
||||
#[validate(length(min = 3, max = 5))]
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||
pub struct OnboardResponse {
|
||||
result: String,
|
||||
}
|
||||
|
||||
impl OnboardRequest {
|
||||
pub fn from(body: TypedBody<OnboardRequest>) -> Result<Self, OnboardError> {
|
||||
let req = body.into_inner();
|
||||
req.validate()?;
|
||||
Ok(req)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub enum OnboardError {
|
||||
#[error("Invalid ownership voucher: {0}")]
|
||||
ValidationError(#[from] validator::ValidationErrors),
|
||||
}
|
||||
|
||||
impl From<OnboardError> for HttpError {
|
||||
fn from(e: OnboardError) -> Self {
|
||||
match e {
|
||||
OnboardError::ValidationError(msg) => HttpError::for_bad_request(
|
||||
Some("ValidationError".to_string()),
|
||||
msg.to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Onboard new device
|
||||
#[endpoint {
|
||||
method = POST,
|
||||
path = "/onboard",
|
||||
}]
|
||||
#[trace_request]
|
||||
pub(crate) async fn onboard(
|
||||
rqctx: RequestContext<Arc<ControllerContext>>,
|
||||
body: TypedBody<OnboardRequest>,
|
||||
) -> Result<HttpResponseOk<OnboardResponse>, HttpError> {
|
||||
tracing::info_span!("Hello, onboard!");
|
||||
|
||||
let req = OnboardRequest::from(body)?;
|
||||
|
||||
tracing::debug!("Got onboarding request: {:?}", req);
|
||||
|
||||
let res = OnboardResponse {
|
||||
result: "Välkommen ombord!".to_string(),
|
||||
};
|
||||
|
||||
Ok(HttpResponseOk(res))
|
||||
}
|
Loading…
Reference in a new issue