From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 52C8570744 for ; Wed, 29 Sep 2021 08:42:58 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 407CDEFE5 for ; Wed, 29 Sep 2021 08:42:28 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 8560CEFD7 for ; Wed, 29 Sep 2021 08:42:27 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 5671744B86 for ; Wed, 29 Sep 2021 08:42:27 +0200 (CEST) Message-ID: <03f68008-c297-51f8-10f0-87d9edfc1da7@proxmox.com> Date: Wed, 29 Sep 2021 08:41:26 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:93.0) Gecko/20100101 Thunderbird/93.0 Content-Language: en-US To: Proxmox Backup Server development discussion , Dominik Csapak References: <20210928091152.2151682-1-d.csapak@proxmox.com> <20210928091152.2151682-4-d.csapak@proxmox.com> From: Thomas Lamprecht In-Reply-To: <20210928091152.2151682-4-d.csapak@proxmox.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 1.559 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment NICE_REPLY_A -3.03 Looks like a legit reply (A) POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes PROLO_LEO1 0.1 Meta Catches all Leo drug variations so far SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: Re: [pbs-devel] [PATCH proxmox-backup v2 3/3] examples: add example for a simple rest server with a small api X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Sep 2021 06:42:58 -0000 On 28.09.21 11:11, Dominik Csapak wrote: > show how to generally start a daemon that serves a rest api + index page > > api calls are: well they are prefixed with `/api2` that's really something that we need to make configurable, for any future project I definitively do not want to use the rather confusing /api2 from the start, that can be rather easily adapted in the client's central HTTP request handling code. > / GET listing > /ping GET returns "pong" > /items GET lists existing items > POST lets user create new items > /items/{id} GET returns the content of a single item > PUT updates an item > DELETE deletes an item > > Contains a small dummy user/authinfo > > Signed-off-by: Dominik Csapak > --- > changes from v1: > * use hyper::server::conn::AddrIncoming::from_listener > > proxmox-rest-server/Cargo.toml | 5 + > proxmox-rest-server/examples/rest_server.rs | 219 ++++++++++++++++++++ > 2 files changed, 224 insertions(+) > create mode 100644 proxmox-rest-server/examples/rest_server.rs > > diff --git a/proxmox-rest-server/Cargo.toml b/proxmox-rest-server/Cargo.toml > index b0e53d19..a6d25b8b 100644 > --- a/proxmox-rest-server/Cargo.toml > +++ b/proxmox-rest-server/Cargo.toml > @@ -5,6 +5,11 @@ authors = ["Proxmox Support Team "] > edition = "2018" > description = "REST server implementation" > > +# for example > +[dev-dependencies] > +proxmox = { version = "0.13.4", features = ["router","api-macro"] } 0.13.4 is already outdated, do we even need tho have that version target so strict as else I'd go with "0.13" for now.. > +pbs-runtime = { path = "../pbs-runtime" } > + > [dependencies] > anyhow = "1.0" > futures = "0.3" > diff --git a/proxmox-rest-server/examples/rest_server.rs b/proxmox-rest-server/examples/rest_server.rs > new file mode 100644 > index 00000000..89efbcb2 > --- /dev/null > +++ b/proxmox-rest-server/examples/rest_server.rs > @@ -0,0 +1,219 @@ > +use std::sync::{Arc, Mutex}; > +use std::collections::HashMap; > + > +use anyhow::{bail, format_err, Error}; > +use futures::{FutureExt, TryFutureExt}; > +use lazy_static::lazy_static; > + > +use proxmox::api::{api, router::SubdirMap, Router, RpcEnvironmentType, UserInformation}; > +use proxmox::list_subdirs_api_method; > +use proxmox_rest_server::{ApiAuth, ApiConfig, AuthError, RestServer}; > + > +// Create a Dummy User info and auth system > +// Normally this would check and authenticate the user > +struct DummyUserInfo; > + > +impl UserInformation for DummyUserInfo { > + fn is_superuser(&self, _userid: &str) -> bool { > + true > + } > + fn is_group_member(&self, _userid: &str, group: &str) -> bool { > + group == "Group" > + } > + fn lookup_privs(&self, _userid: &str, _path: &[&str]) -> u64 { > + u64::MAX > + } > +} > + > +struct DummyAuth; > + > +impl ApiAuth for DummyAuth { > + fn check_auth( > + &self, > + _headers: &http::HeaderMap, > + _method: &hyper::Method, > + ) -> Result<(String, Box), AuthError> { > + // get some global/cached userinfo > + let userinfo = DummyUserInfo; > + // Do some user checks, e.g. cookie/csrf > + Ok(("User".to_string(), Box::new(userinfo))) > + } > +} > + > +// this should return the index page of the webserver > +// iow. what the user browses to above fits in one line even with 80 cc, and in rust we normally go always for 100cc. > +fn get_index( > + _auth_id: Option, > + _language: Option, > + _api: &ApiConfig, > + _parts: http::request::Parts, > +) -> http::Response { > + // build an index page > + http::Response::builder() > + .body("hello world".into()) maybe a mini html thingy with the API description from above + links to the GET calls would be nice to have? > +async fn run() -> Result<(), Error> { > + > + // we first have to configure the api environment (basedir etc.) > + > + let config = ApiConfig::new( > + "/var/tmp/", > + &ROUTER, > + RpcEnvironmentType::PUBLIC, > + Arc::new(DummyAuth {}), > + get_index, > + )?; > + let rest_server = RestServer::new(config); > + > + // then we have to create a daemon that listens, accepts and serves > + // the api to clients > + proxmox_rest_server::daemon::create_daemon( > + ([127, 0, 0, 1], 65000).into(), > + move |listener, ready| { > + let incoming = hyper::server::conn::AddrIncoming::from_listener(listener)?; > + > + Ok(ready > + .and_then(|_| hyper::Server::builder(incoming) > + .serve(rest_server) > + .map_err(Error::from) > + ) > + .map_err(|err| eprintln!("ERR: {}", err)) > + .map(|test| println!("OK: {}", test.is_ok()))) closing parenthesis jungle ^^ Can you at least place the closing one from Ok() one a new line or does rustfmt does not like that? > + }, > + "example_server", > + ).await?; > + > + Ok(()) > +} > + > +fn main() -> Result<(), Error> { > + pbs_runtime::main(run()) here I agree with Dietmar, avoiding that dependency would be nice for the example. > +} >