[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