[pve-devel] [PATCH v3 proxmox 03/66] notify: preparation for the API
Wolfgang Bumiller
w.bumiller at proxmox.com
Tue Jul 18 14:02:04 CEST 2023
FYI: I'm not through the entire series yet, but I think it's fine for
the *API* methods to use `anyhow::Error` instead.
Also:
I'd like to move this here to a separate crate to replace
`proxmox_router::HttpError` (since the router one has no `source`
support atm and we don't want to depend on the router here, since *this*
crate also ends up in perl bindings), along with the `http_bail!` and
`http_err!` macros. To make sure that we don't have any HTTP error types
which might get past our server's automatic "delay on auth issues"
mechanism. Specifically, the rest server code uses `downcast` on an
`anyhow::Error` to check if it's a `HttpError` with status code
`UNAUTHORIZED` and then introduces a delay.
On Mon, Jul 17, 2023 at 04:59:48PM +0200, Lukas Wagner wrote:
> Signed-off-by: Lukas Wagner <l.wagner at proxmox.com>
> ---
> proxmox-notify/src/api/mod.rs | 94 +++++++++++++++++++++++++++++++++++
> proxmox-notify/src/lib.rs | 1 +
> 2 files changed, 95 insertions(+)
> create mode 100644 proxmox-notify/src/api/mod.rs
>
> diff --git a/proxmox-notify/src/api/mod.rs b/proxmox-notify/src/api/mod.rs
> new file mode 100644
> index 00000000..be596b93
> --- /dev/null
> +++ b/proxmox-notify/src/api/mod.rs
> @@ -0,0 +1,94 @@
> +use std::error::Error as StdError;
> +use std::fmt::Display;
> +
> +use crate::Config;
> +use serde::Serialize;
> +
> +#[derive(Debug, Serialize)]
> +pub struct ApiError {
> + /// HTTP Error code
> + code: u16,
> + /// Error message
> + message: String,
> + #[serde(skip_serializing)]
> + /// The underlying cause of the error
> + source: Option<Box<dyn StdError + Send + Sync + 'static>>,
> +}
> +
> +impl ApiError {
> + fn new<S: AsRef<str>>(
> + message: S,
> + code: u16,
> + source: Option<Box<dyn StdError + Send + Sync + 'static>>,
> + ) -> Self {
> + Self {
> + message: message.as_ref().into(),
> + code,
> + source,
> + }
> + }
> +
> + pub fn bad_request<S: AsRef<str>>(
> + message: S,
> + source: Option<Box<dyn StdError + Send + Sync + 'static>>,
> + ) -> Self {
> + Self::new(message, 400, source)
> + }
> +
> + pub fn not_found<S: AsRef<str>>(
> + message: S,
> + source: Option<Box<dyn StdError + Send + Sync + 'static>>,
> + ) -> Self {
> + Self::new(message, 404, source)
> + }
> +
> + pub fn internal_server_error<S: AsRef<str>>(
> + message: S,
> + source: Option<Box<dyn StdError + Send + Sync + 'static>>,
> + ) -> Self {
> + Self::new(message, 500, source)
> + }
> +}
> +
> +impl Display for ApiError {
> + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
> + f.write_str(&format!("{} {}", self.code, self.message))
> + }
> +}
> +
> +impl StdError for ApiError {
> + fn source(&self) -> Option<&(dyn StdError + 'static)> {
> + match &self.source {
> + None => None,
> + Some(source) => Some(&**source),
> + }
> + }
> +}
> +
> +fn verify_digest(config: &Config, digest: Option<&[u8]>) -> Result<(), ApiError> {
> + if let Some(digest) = digest {
> + if config.digest != *digest {
> + return Err(ApiError::bad_request(
> + "detected modified configuration - file changed by other user? Try again.",
> + None,
> + ));
> + }
> + }
> +
> + Ok(())
> +}
> +
> +fn endpoint_exists(config: &Config, name: &str) -> bool {
> + let mut exists = false;
> +
> + exists
> +}
> +
> +#[cfg(test)]
> +mod test_helpers {
> + use crate::Config;
> +
> + pub fn empty_config() -> Config {
> + Config::new("", "").unwrap()
> + }
> +}
> diff --git a/proxmox-notify/src/lib.rs b/proxmox-notify/src/lib.rs
> index 7b90ee15..43feac25 100644
> --- a/proxmox-notify/src/lib.rs
> +++ b/proxmox-notify/src/lib.rs
> @@ -9,6 +9,7 @@ use serde_json::Value;
>
> use std::error::Error as StdError;
>
> +pub mod api;
> mod config;
> pub mod endpoints;
> pub mod schema;
> --
> 2.39.2
More information about the pve-devel
mailing list