diff options
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/admin/Cargo.toml | 71 | ||||
-rw-r--r-- | src/api/admin/api_server.rs | 18 | ||||
-rw-r--r-- | src/api/admin/bucket.rs | 10 | ||||
-rw-r--r-- | src/api/admin/cluster.rs | 6 | ||||
-rw-r--r-- | src/api/admin/error.rs | 10 | ||||
-rw-r--r-- | src/api/admin/key.rs | 6 | ||||
-rw-r--r-- | src/api/admin/lib.rs (renamed from src/api/admin/mod.rs) | 3 | ||||
-rw-r--r-- | src/api/admin/router_v0.rs | 4 | ||||
-rw-r--r-- | src/api/admin/router_v1.rs | 6 | ||||
-rw-r--r-- | src/api/common/Cargo.toml (renamed from src/api/Cargo.toml) | 3 | ||||
-rw-r--r-- | src/api/common/common_error.rs (renamed from src/api/common_error.rs) | 4 | ||||
-rw-r--r-- | src/api/common/encoding.rs (renamed from src/api/encoding.rs) | 0 | ||||
-rw-r--r-- | src/api/common/generic_server.rs (renamed from src/api/generic_server.rs) | 6 | ||||
-rw-r--r-- | src/api/common/helpers.rs (renamed from src/api/helpers.rs) | 10 | ||||
-rw-r--r-- | src/api/common/lib.rs (renamed from src/api/lib.rs) | 9 | ||||
-rw-r--r-- | src/api/common/router_macros.rs (renamed from src/api/router_macros.rs) | 6 | ||||
-rw-r--r-- | src/api/common/signature/error.rs (renamed from src/api/signature/error.rs) | 0 | ||||
-rw-r--r-- | src/api/common/signature/mod.rs (renamed from src/api/signature/mod.rs) | 0 | ||||
-rw-r--r-- | src/api/common/signature/payload.rs (renamed from src/api/signature/payload.rs) | 2 | ||||
-rw-r--r-- | src/api/common/signature/streaming.rs (renamed from src/api/signature/streaming.rs) | 0 | ||||
-rw-r--r-- | src/api/k2v/Cargo.toml | 75 | ||||
-rw-r--r-- | src/api/k2v/api_server.rs | 20 | ||||
-rw-r--r-- | src/api/k2v/batch.rs | 2 | ||||
-rw-r--r-- | src/api/k2v/error.rs | 14 | ||||
-rw-r--r-- | src/api/k2v/index.rs | 8 | ||||
-rw-r--r-- | src/api/k2v/item.rs | 6 | ||||
-rw-r--r-- | src/api/k2v/lib.rs (renamed from src/api/k2v/mod.rs) | 3 | ||||
-rw-r--r-- | src/api/k2v/range.rs | 4 | ||||
-rw-r--r-- | src/api/k2v/router.rs | 6 | ||||
-rw-r--r-- | src/api/s3/Cargo.toml | 71 | ||||
-rw-r--r-- | src/api/s3/api_server.rs | 40 | ||||
-rw-r--r-- | src/api/s3/bucket.rs | 12 | ||||
-rw-r--r-- | src/api/s3/checksum.rs | 2 | ||||
-rw-r--r-- | src/api/s3/copy.rs | 18 | ||||
-rw-r--r-- | src/api/s3/cors.rs | 12 | ||||
-rw-r--r-- | src/api/s3/delete.rs | 12 | ||||
-rw-r--r-- | src/api/s3/encryption.rs | 6 | ||||
-rw-r--r-- | src/api/s3/error.rs | 19 | ||||
-rw-r--r-- | src/api/s3/get.rs | 10 | ||||
-rw-r--r-- | src/api/s3/lib.rs (renamed from src/api/s3/mod.rs) | 3 | ||||
-rw-r--r-- | src/api/s3/lifecycle.rs | 10 | ||||
-rw-r--r-- | src/api/s3/list.rs | 14 | ||||
-rw-r--r-- | src/api/s3/multipart.rs | 16 | ||||
-rw-r--r-- | src/api/s3/post_object.rs | 18 | ||||
-rw-r--r-- | src/api/s3/put.rs | 10 | ||||
-rw-r--r-- | src/api/s3/router.rs | 6 | ||||
-rw-r--r-- | src/api/s3/website.rs | 10 | ||||
-rw-r--r-- | src/api/s3/xml.rs | 2 |
48 files changed, 417 insertions, 186 deletions
diff --git a/src/api/admin/Cargo.toml b/src/api/admin/Cargo.toml new file mode 100644 index 00000000..02cbfc3d --- /dev/null +++ b/src/api/admin/Cargo.toml @@ -0,0 +1,71 @@ +[package] +name = "garage_api_admin" +version = "1.0.1" +authors = ["Alex Auvolat <alex@adnab.me>"] +edition = "2018" +license = "AGPL-3.0" +description = "S3 API server crate for the Garage object store" +repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage" +readme = "../../README.md" + +[lib] +path = "lib.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +garage_model.workspace = true +garage_table.workspace = true +garage_block.workspace = true +garage_net.workspace = true +garage_util.workspace = true +garage_rpc.workspace = true +garage_api_common.workspace = true + +aes-gcm.workspace = true +argon2.workspace = true +async-compression.workspace = true +async-trait.workspace = true +base64.workspace = true +bytes.workspace = true +chrono.workspace = true +crc32fast.workspace = true +crc32c.workspace = true +crypto-common.workspace = true +err-derive.workspace = true +hex.workspace = true +hmac.workspace = true +idna.workspace = true +tracing.workspace = true +md-5.workspace = true +nom.workspace = true +pin-project.workspace = true +sha1.workspace = true +sha2.workspace = true + +futures.workspace = true +futures-util.workspace = true +tokio.workspace = true +tokio-stream.workspace = true +tokio-util.workspace = true + +form_urlencoded.workspace = true +http.workspace = true +httpdate.workspace = true +http-range.workspace = true +http-body-util.workspace = true +hyper = { workspace = true, default-features = false, features = ["server", "http1"] } +hyper-util.workspace = true +multer.workspace = true +percent-encoding.workspace = true +roxmltree.workspace = true +url.workspace = true + +serde.workspace = true +serde_bytes.workspace = true +serde_json.workspace = true +quick-xml.workspace = true + +opentelemetry.workspace = true +opentelemetry-prometheus = { workspace = true, optional = true } +prometheus = { workspace = true, optional = true } diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs index 0e4565bb..7f8a51a6 100644 --- a/src/api/admin/api_server.rs +++ b/src/api/admin/api_server.rs @@ -20,15 +20,15 @@ use garage_rpc::system::ClusterHealthStatus; use garage_util::error::Error as GarageError; use garage_util::socket_address::UnixOrTCPSocketAddress; -use crate::generic_server::*; - -use crate::admin::bucket::*; -use crate::admin::cluster::*; -use crate::admin::error::*; -use crate::admin::key::*; -use crate::admin::router_v0; -use crate::admin::router_v1::{Authorization, Endpoint}; -use crate::helpers::*; +use garage_api_common::generic_server::*; + +use crate::bucket::*; +use crate::cluster::*; +use crate::error::*; +use crate::key::*; +use crate::router_v0; +use crate::router_v1::{Authorization, Endpoint}; +use garage_api_common::helpers::*; pub type ResBody = BoxBody<Error>; diff --git a/src/api/admin/bucket.rs b/src/api/admin/bucket.rs index ac3cba00..3afed694 100644 --- a/src/api/admin/bucket.rs +++ b/src/api/admin/bucket.rs @@ -17,11 +17,11 @@ use garage_model::permission::*; use garage_model::s3::mpu_table; use garage_model::s3::object_table::*; -use crate::admin::api_server::ResBody; -use crate::admin::error::*; -use crate::admin::key::ApiBucketKeyPerm; -use crate::common_error::CommonError; -use crate::helpers::*; +use crate::api_server::ResBody; +use crate::error::*; +use crate::key::ApiBucketKeyPerm; +use garage_api_common::common_error::CommonError; +use garage_api_common::helpers::*; pub async fn handle_list_buckets(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> { let buckets = garage diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs index 357ac600..d4a645a2 100644 --- a/src/api/admin/cluster.rs +++ b/src/api/admin/cluster.rs @@ -12,9 +12,9 @@ use garage_rpc::layout; use garage_model::garage::Garage; -use crate::admin::api_server::ResBody; -use crate::admin::error::*; -use crate::helpers::{json_ok_response, parse_json_body}; +use crate::api_server::ResBody; +use crate::error::*; +use garage_api_common::helpers::{json_ok_response, parse_json_body}; pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> { let layout = garage.system.cluster_layout(); diff --git a/src/api/admin/error.rs b/src/api/admin/error.rs index 40d686e3..1c962776 100644 --- a/src/api/admin/error.rs +++ b/src/api/admin/error.rs @@ -6,10 +6,12 @@ use hyper::{HeaderMap, StatusCode}; pub use garage_model::helper::error::Error as HelperError; -use crate::common_error::CommonError; -pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError}; -use crate::generic_server::ApiError; -use crate::helpers::*; +use garage_api_common::common_error::CommonError; +pub use garage_api_common::common_error::{ + CommonErrorDerivative, OkOrBadRequest, OkOrInternalError, +}; +use garage_api_common::generic_server::ApiError; +use garage_api_common::helpers::*; /// Errors of this crate #[derive(Debug, Error)] diff --git a/src/api/admin/key.rs b/src/api/admin/key.rs index 291b6d54..0c017a26 100644 --- a/src/api/admin/key.rs +++ b/src/api/admin/key.rs @@ -9,9 +9,9 @@ use garage_table::*; use garage_model::garage::Garage; use garage_model::key_table::*; -use crate::admin::api_server::ResBody; -use crate::admin::error::*; -use crate::helpers::*; +use crate::api_server::ResBody; +use crate::error::*; +use garage_api_common::helpers::*; pub async fn handle_list_keys(garage: &Arc<Garage>) -> Result<Response<ResBody>, Error> { let res = garage diff --git a/src/api/admin/mod.rs b/src/api/admin/lib.rs index 43a8c59c..599e9b44 100644 --- a/src/api/admin/mod.rs +++ b/src/api/admin/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate tracing; + pub mod api_server; mod error; mod router_v0; diff --git a/src/api/admin/router_v0.rs b/src/api/admin/router_v0.rs index 68676445..0c832fe1 100644 --- a/src/api/admin/router_v0.rs +++ b/src/api/admin/router_v0.rs @@ -2,8 +2,8 @@ use std::borrow::Cow; use hyper::{Method, Request}; -use crate::admin::error::*; -use crate::router_macros::*; +use crate::error::*; +use garage_api_common::router_macros::*; router_match! {@func diff --git a/src/api/admin/router_v1.rs b/src/api/admin/router_v1.rs index cc5ff2ec..d9febd34 100644 --- a/src/api/admin/router_v1.rs +++ b/src/api/admin/router_v1.rs @@ -2,9 +2,9 @@ use std::borrow::Cow; use hyper::{Method, Request}; -use crate::admin::error::*; -use crate::admin::router_v0; -use crate::router_macros::*; +use crate::error::*; +use crate::router_v0; +use garage_api_common::router_macros::*; pub enum Authorization { None, diff --git a/src/api/Cargo.toml b/src/api/common/Cargo.toml index 85b78a5b..e5dc57d4 100644 --- a/src/api/Cargo.toml +++ b/src/api/common/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "garage_api" +name = "garage_api_common" version = "1.0.1" authors = ["Alex Auvolat <alex@adnab.me>"] edition = "2018" @@ -70,5 +70,4 @@ opentelemetry-prometheus = { workspace = true, optional = true } prometheus = { workspace = true, optional = true } [features] -k2v = [ "garage_util/k2v", "garage_model/k2v" ] metrics = [ "opentelemetry-prometheus", "prometheus" ] diff --git a/src/api/common_error.rs b/src/api/common/common_error.rs index 0c8006dc..1e3f9feb 100644 --- a/src/api/common_error.rs +++ b/src/api/common/common_error.rs @@ -118,14 +118,14 @@ impl TryFrom<HelperError> for CommonError { /// This is used for helper functions that might return InvalidBucketName /// or NoSuchBucket for instance, and we want to pass that error /// up to our caller. -pub(crate) fn pass_helper_error(err: HelperError) -> CommonError { +pub fn pass_helper_error(err: HelperError) -> CommonError { match CommonError::try_from(err) { Ok(e) => e, Err(e) => panic!("Helper error `{}` should hot have happenned here", e), } } -pub(crate) fn helper_error_as_internal(err: HelperError) -> CommonError { +pub fn helper_error_as_internal(err: HelperError) -> CommonError { match err { HelperError::Internal(e) => CommonError::InternalError(e), e => CommonError::InternalError(GarageError::Message(e.to_string())), diff --git a/src/api/encoding.rs b/src/api/common/encoding.rs index e286a784..e286a784 100644 --- a/src/api/encoding.rs +++ b/src/api/common/encoding.rs diff --git a/src/api/generic_server.rs b/src/api/common/generic_server.rs index 283abdd4..d92a3465 100644 --- a/src/api/generic_server.rs +++ b/src/api/common/generic_server.rs @@ -36,7 +36,7 @@ use garage_util::socket_address::UnixOrTCPSocketAddress; use crate::helpers::{BoxBody, ErrorBody}; -pub(crate) trait ApiEndpoint: Send + Sync + 'static { +pub trait ApiEndpoint: Send + Sync + 'static { fn name(&self) -> &'static str; fn add_span_attributes(&self, span: SpanRef<'_>); } @@ -48,7 +48,7 @@ pub trait ApiError: std::error::Error + Send + Sync + 'static { } #[async_trait] -pub(crate) trait ApiHandler: Send + Sync + 'static { +pub trait ApiHandler: Send + Sync + 'static { const API_NAME: &'static str; const API_NAME_DISPLAY: &'static str; @@ -63,7 +63,7 @@ pub(crate) trait ApiHandler: Send + Sync + 'static { ) -> Result<Response<BoxBody<Self::Error>>, Self::Error>; } -pub(crate) struct ApiServer<A: ApiHandler> { +pub struct ApiServer<A: ApiHandler> { region: String, api_handler: A, diff --git a/src/api/helpers.rs b/src/api/common/helpers.rs index cf60005d..c8586de4 100644 --- a/src/api/helpers.rs +++ b/src/api/common/helpers.rs @@ -363,9 +363,9 @@ mod tests { } #[derive(Serialize)] -pub(crate) struct CustomApiErrorBody { - pub(crate) code: String, - pub(crate) message: String, - pub(crate) region: String, - pub(crate) path: String, +pub struct CustomApiErrorBody { + pub code: String, + pub message: String, + pub region: String, + pub path: String, } diff --git a/src/api/lib.rs b/src/api/common/lib.rs index 370dfd7a..49d463d7 100644 --- a/src/api/lib.rs +++ b/src/api/common/lib.rs @@ -4,14 +4,9 @@ extern crate tracing; pub mod common_error; -mod encoding; +pub mod encoding; pub mod generic_server; pub mod helpers; -mod router_macros; +pub mod router_macros; /// This mode is public only to help testing. Don't expect stability here pub mod signature; - -pub mod admin; -#[cfg(feature = "k2v")] -pub mod k2v; -pub mod s3; diff --git a/src/api/router_macros.rs b/src/api/common/router_macros.rs index 8f10a4f5..d9fe86db 100644 --- a/src/api/router_macros.rs +++ b/src/api/common/router_macros.rs @@ -1,5 +1,6 @@ /// This macro is used to generate very repetitive match {} blocks in this module /// It is _not_ made to be used anywhere else +#[macro_export] macro_rules! router_match { (@match $enum:expr , [ $($endpoint:ident,)* ]) => {{ // usage: router_match {@match my_enum, [ VariantWithField1, VariantWithField2 ..] } @@ -133,6 +134,7 @@ macro_rules! router_match { /// This macro is used to generate part of the code in this module. It must be called only one, and /// is useless outside of this module. +#[macro_export] macro_rules! generateQueryParameters { ( keywords: [ $($kw_param:expr => $kw_name: ident),* ], @@ -220,5 +222,5 @@ macro_rules! generateQueryParameters { } } -pub(crate) use generateQueryParameters; -pub(crate) use router_match; +pub use generateQueryParameters; +pub use router_match; diff --git a/src/api/signature/error.rs b/src/api/common/signature/error.rs index 2d92a072..2d92a072 100644 --- a/src/api/signature/error.rs +++ b/src/api/common/signature/error.rs diff --git a/src/api/signature/mod.rs b/src/api/common/signature/mod.rs index 6514da43..6514da43 100644 --- a/src/api/signature/mod.rs +++ b/src/api/common/signature/mod.rs diff --git a/src/api/signature/payload.rs b/src/api/common/signature/payload.rs index 9e5a6043..81541e4a 100644 --- a/src/api/signature/payload.rs +++ b/src/api/common/signature/payload.rs @@ -518,7 +518,7 @@ impl Authorization { }) } - pub(crate) fn parse_form(params: &HeaderMap) -> Result<Self, Error> { + pub fn parse_form(params: &HeaderMap) -> Result<Self, Error> { let algorithm = params .get(X_AMZ_ALGORITHM) .ok_or_bad_request("Missing X-Amz-Algorithm header")? diff --git a/src/api/signature/streaming.rs b/src/api/common/signature/streaming.rs index e223d1b1..e223d1b1 100644 --- a/src/api/signature/streaming.rs +++ b/src/api/common/signature/streaming.rs diff --git a/src/api/k2v/Cargo.toml b/src/api/k2v/Cargo.toml new file mode 100644 index 00000000..86d12c2d --- /dev/null +++ b/src/api/k2v/Cargo.toml @@ -0,0 +1,75 @@ +[package] +name = "garage_api_k2v" +version = "1.0.1" +authors = ["Alex Auvolat <alex@adnab.me>"] +edition = "2018" +license = "AGPL-3.0" +description = "S3 API server crate for the Garage object store" +repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage" +readme = "../../README.md" + +[lib] +path = "lib.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +garage_model.workspace = true +garage_table.workspace = true +garage_block.workspace = true +garage_net.workspace = true +garage_util.workspace = true +garage_rpc.workspace = true +garage_api_common.workspace = true +garage_api_s3.workspace = true + +aes-gcm.workspace = true +argon2.workspace = true +async-compression.workspace = true +async-trait.workspace = true +base64.workspace = true +bytes.workspace = true +chrono.workspace = true +crc32fast.workspace = true +crc32c.workspace = true +crypto-common.workspace = true +err-derive.workspace = true +hex.workspace = true +hmac.workspace = true +idna.workspace = true +tracing.workspace = true +md-5.workspace = true +nom.workspace = true +pin-project.workspace = true +sha1.workspace = true +sha2.workspace = true + +futures.workspace = true +futures-util.workspace = true +tokio.workspace = true +tokio-stream.workspace = true +tokio-util.workspace = true + +form_urlencoded.workspace = true +http.workspace = true +httpdate.workspace = true +http-range.workspace = true +http-body-util.workspace = true +hyper = { workspace = true, default-features = false, features = ["server", "http1"] } +hyper-util.workspace = true +multer.workspace = true +percent-encoding.workspace = true +roxmltree.workspace = true +url.workspace = true + +serde.workspace = true +serde_bytes.workspace = true +serde_json.workspace = true +quick-xml.workspace = true + +opentelemetry.workspace = true +opentelemetry-prometheus = { workspace = true, optional = true } +prometheus = { workspace = true, optional = true } + +[features] +default = [ "garage_util/k2v", "garage_model/k2v" ] diff --git a/src/api/k2v/api_server.rs b/src/api/k2v/api_server.rs index de6e5f06..1fc512f9 100644 --- a/src/api/k2v/api_server.rs +++ b/src/api/k2v/api_server.rs @@ -12,19 +12,19 @@ use garage_util::socket_address::UnixOrTCPSocketAddress; use garage_model::garage::Garage; -use crate::generic_server::*; -use crate::k2v::error::*; +use crate::error::*; +use garage_api_common::generic_server::*; -use crate::signature::verify_request; +use garage_api_common::signature::verify_request; -use crate::helpers::*; -use crate::k2v::batch::*; -use crate::k2v::index::*; -use crate::k2v::item::*; -use crate::k2v::router::Endpoint; -use crate::s3::cors::*; +use crate::batch::*; +use crate::index::*; +use crate::item::*; +use crate::router::Endpoint; +use garage_api_common::helpers::*; +use garage_api_s3::cors::*; -pub use crate::signature::streaming::ReqBody; +pub use garage_api_common::signature::streaming::ReqBody; pub type ResBody = BoxBody<Error>; pub struct K2VApiServer { diff --git a/src/api/k2v/batch.rs b/src/api/k2v/batch.rs index e4d0b0e5..1dd90456 100644 --- a/src/api/k2v/batch.rs +++ b/src/api/k2v/batch.rs @@ -6,11 +6,11 @@ use garage_table::{EnumerationOrder, TableSchema}; use garage_model::k2v::item_table::*; -use crate::helpers::*; use crate::k2v::api_server::{ReqBody, ResBody}; use crate::k2v::error::*; use crate::k2v::item::parse_causality_token; use crate::k2v::range::read_range; +use garage_api_common::helpers::*; pub async fn handle_insert_batch( ctx: ReqCtx, diff --git a/src/api/k2v/error.rs b/src/api/k2v/error.rs index dbe4be2c..a4d3be1c 100644 --- a/src/api/k2v/error.rs +++ b/src/api/k2v/error.rs @@ -2,12 +2,14 @@ use err_derive::Error; use hyper::header::HeaderValue; use hyper::{HeaderMap, StatusCode}; -use crate::common_error::CommonError; -pub(crate) use crate::common_error::{helper_error_as_internal, pass_helper_error}; -pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError}; -use crate::generic_server::ApiError; -use crate::helpers::*; -use crate::signature::error::Error as SignatureError; +use garage_api_common::common_error::CommonError; +pub(crate) use garage_api_common::common_error::{helper_error_as_internal, pass_helper_error}; +pub use garage_api_common::common_error::{ + CommonErrorDerivative, OkOrBadRequest, OkOrInternalError, +}; +use garage_api_common::generic_server::ApiError; +use garage_api_common::helpers::*; +use garage_api_common::signature::error::Error as SignatureError; /// Errors of this crate #[derive(Debug, Error)] diff --git a/src/api/k2v/index.rs b/src/api/k2v/index.rs index e3397238..423c1f97 100644 --- a/src/api/k2v/index.rs +++ b/src/api/k2v/index.rs @@ -5,10 +5,10 @@ use garage_table::util::*; use garage_model::k2v::item_table::{BYTES, CONFLICTS, ENTRIES, VALUES}; -use crate::helpers::*; -use crate::k2v::api_server::ResBody; -use crate::k2v::error::*; -use crate::k2v::range::read_range; +use crate::api_server::ResBody; +use crate::error::*; +use crate::range::read_range; +use garage_api_common::helpers::*; pub async fn handle_read_index( ctx: ReqCtx, diff --git a/src/api/k2v/item.rs b/src/api/k2v/item.rs index 87371727..315f647c 100644 --- a/src/api/k2v/item.rs +++ b/src/api/k2v/item.rs @@ -6,9 +6,9 @@ use hyper::{Request, Response, StatusCode}; use garage_model::k2v::causality::*; use garage_model::k2v::item_table::*; -use crate::helpers::*; -use crate::k2v::api_server::{ReqBody, ResBody}; -use crate::k2v::error::*; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use garage_api_common::helpers::*; pub const X_GARAGE_CAUSALITY_TOKEN: &str = "X-Garage-Causality-Token"; diff --git a/src/api/k2v/mod.rs b/src/api/k2v/lib.rs index b6a8c5cf..334ae46b 100644 --- a/src/api/k2v/mod.rs +++ b/src/api/k2v/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate tracing; + pub mod api_server; mod error; mod router; diff --git a/src/api/k2v/range.rs b/src/api/k2v/range.rs index bb9d3be5..fdb17e22 100644 --- a/src/api/k2v/range.rs +++ b/src/api/k2v/range.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use garage_table::replication::TableShardedReplication; use garage_table::*; -use crate::helpers::key_after_prefix; -use crate::k2v::error::*; +use crate::error::*; +use garage_api_common::helpers::key_after_prefix; /// Read range in a Garage table. /// Returns (entries, more?, nextStart) diff --git a/src/api/k2v/router.rs b/src/api/k2v/router.rs index 1cc58be5..a04b0f81 100644 --- a/src/api/k2v/router.rs +++ b/src/api/k2v/router.rs @@ -1,11 +1,11 @@ -use crate::k2v::error::*; +use crate::error::*; use std::borrow::Cow; use hyper::{Method, Request}; -use crate::helpers::Authorization; -use crate::router_macros::{generateQueryParameters, router_match}; +use garage_api_common::helpers::Authorization; +use garage_api_common::router_macros::{generateQueryParameters, router_match}; router_match! {@func diff --git a/src/api/s3/Cargo.toml b/src/api/s3/Cargo.toml new file mode 100644 index 00000000..c610b43a --- /dev/null +++ b/src/api/s3/Cargo.toml @@ -0,0 +1,71 @@ +[package] +name = "garage_api_s3" +version = "1.0.1" +authors = ["Alex Auvolat <alex@adnab.me>"] +edition = "2018" +license = "AGPL-3.0" +description = "S3 API server crate for the Garage object store" +repository = "https://git.deuxfleurs.fr/Deuxfleurs/garage" +readme = "../../README.md" + +[lib] +path = "lib.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +garage_model.workspace = true +garage_table.workspace = true +garage_block.workspace = true +garage_net.workspace = true +garage_util.workspace = true +garage_rpc.workspace = true +garage_api_common.workspace = true + +aes-gcm.workspace = true +argon2.workspace = true +async-compression.workspace = true +async-trait.workspace = true +base64.workspace = true +bytes.workspace = true +chrono.workspace = true +crc32fast.workspace = true +crc32c.workspace = true +crypto-common.workspace = true +err-derive.workspace = true +hex.workspace = true +hmac.workspace = true +idna.workspace = true +tracing.workspace = true +md-5.workspace = true +nom.workspace = true +pin-project.workspace = true +sha1.workspace = true +sha2.workspace = true + +futures.workspace = true +futures-util.workspace = true +tokio.workspace = true +tokio-stream.workspace = true +tokio-util.workspace = true + +form_urlencoded.workspace = true +http.workspace = true +httpdate.workspace = true +http-range.workspace = true +http-body-util.workspace = true +hyper = { workspace = true, default-features = false, features = ["server", "http1"] } +hyper-util.workspace = true +multer.workspace = true +percent-encoding.workspace = true +roxmltree.workspace = true +url.workspace = true + +serde.workspace = true +serde_bytes.workspace = true +serde_json.workspace = true +quick-xml.workspace = true + +opentelemetry.workspace = true +opentelemetry-prometheus = { workspace = true, optional = true } +prometheus = { workspace = true, optional = true } diff --git a/src/api/s3/api_server.rs b/src/api/s3/api_server.rs index f9dafa10..d24f6a0c 100644 --- a/src/api/s3/api_server.rs +++ b/src/api/s3/api_server.rs @@ -14,26 +14,26 @@ use garage_util::socket_address::UnixOrTCPSocketAddress; use garage_model::garage::Garage; use garage_model::key_table::Key; -use crate::generic_server::*; -use crate::s3::error::*; - -use crate::signature::verify_request; - -use crate::helpers::*; -use crate::s3::bucket::*; -use crate::s3::copy::*; -use crate::s3::cors::*; -use crate::s3::delete::*; -use crate::s3::get::*; -use crate::s3::lifecycle::*; -use crate::s3::list::*; -use crate::s3::multipart::*; -use crate::s3::post_object::handle_post_object; -use crate::s3::put::*; -use crate::s3::router::Endpoint; -use crate::s3::website::*; - -pub use crate::signature::streaming::ReqBody; +use crate::error::*; +use garage_api_common::generic_server::*; + +use garage_api_common::signature::verify_request; + +use crate::bucket::*; +use crate::copy::*; +use crate::cors::*; +use crate::delete::*; +use crate::get::*; +use crate::lifecycle::*; +use crate::list::*; +use crate::multipart::*; +use crate::post_object::handle_post_object; +use crate::put::*; +use crate::router::Endpoint; +use crate::website::*; +use garage_api_common::helpers::*; + +pub use garage_api_common::signature::streaming::ReqBody; pub type ResBody = BoxBody<Error>; pub struct S3ApiServer { diff --git a/src/api/s3/bucket.rs b/src/api/s3/bucket.rs index 6a12aa9c..09c5742b 100644 --- a/src/api/s3/bucket.rs +++ b/src/api/s3/bucket.rs @@ -13,12 +13,12 @@ use garage_util::crdt::*; use garage_util::data::*; use garage_util::time::*; -use crate::common_error::CommonError; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::error::*; -use crate::s3::xml as s3_xml; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use crate::xml as s3_xml; +use garage_api_common::common_error::CommonError; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; pub fn handle_get_bucket_location(ctx: ReqCtx) -> Result<Response<ResBody>, Error> { let ReqCtx { garage, .. } = ctx; diff --git a/src/api/s3/checksum.rs b/src/api/s3/checksum.rs index c7527163..02fb55ec 100644 --- a/src/api/s3/checksum.rs +++ b/src/api/s3/checksum.rs @@ -15,7 +15,7 @@ use garage_util::error::OkOrMessage; use garage_model::s3::object_table::*; -use crate::s3::error::*; +use crate::error::*; pub const X_AMZ_CHECKSUM_ALGORITHM: HeaderName = HeaderName::from_static("x-amz-checksum-algorithm"); diff --git a/src/api/s3/copy.rs b/src/api/s3/copy.rs index b67ace88..1a474fd0 100644 --- a/src/api/s3/copy.rs +++ b/src/api/s3/copy.rs @@ -20,15 +20,15 @@ use garage_model::s3::mpu_table::*; use garage_model::s3::object_table::*; use garage_model::s3::version_table::*; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::checksum::*; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; -use crate::s3::get::full_object_byte_stream; -use crate::s3::multipart; -use crate::s3::put::{get_headers, save_stream, ChecksumMode, SaveStreamResult}; -use crate::s3::xml::{self as s3_xml, xmlns_tag}; +use crate::api_server::{ReqBody, ResBody}; +use crate::checksum::*; +use crate::encryption::EncryptionParams; +use crate::error::*; +use crate::get::full_object_byte_stream; +use crate::multipart; +use crate::put::{get_headers, save_stream, ChecksumMode, SaveStreamResult}; +use crate::xml::{self as s3_xml, xmlns_tag}; +use garage_api_common::helpers::*; // -------- CopyObject --------- diff --git a/src/api/s3/cors.rs b/src/api/s3/cors.rs index 32dcc0d5..ae8352c3 100644 --- a/src/api/s3/cors.rs +++ b/src/api/s3/cors.rs @@ -15,12 +15,12 @@ use http_body_util::BodyExt; use serde::{Deserialize, Serialize}; -use crate::common_error::{helper_error_as_internal, CommonError}; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::error::*; -use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; +use garage_api_common::common_error::{helper_error_as_internal, CommonError}; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; use garage_model::bucket_table::{Bucket, BucketParams, CorsRule as GarageCorsRule}; use garage_model::garage::Garage; diff --git a/src/api/s3/delete.rs b/src/api/s3/delete.rs index 57f6f948..1711a9b4 100644 --- a/src/api/s3/delete.rs +++ b/src/api/s3/delete.rs @@ -5,12 +5,12 @@ use garage_util::data::*; use garage_model::s3::object_table::*; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::error::*; -use crate::s3::put::next_timestamp; -use crate::s3::xml as s3_xml; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use crate::put::next_timestamp; +use crate::xml as s3_xml; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; async fn handle_delete_internal(ctx: &ReqCtx, key: &str) -> Result<(Uuid, Uuid), Error> { let ReqCtx { diff --git a/src/api/s3/encryption.rs b/src/api/s3/encryption.rs index 2e6ed65c..c54d487b 100644 --- a/src/api/s3/encryption.rs +++ b/src/api/s3/encryption.rs @@ -28,9 +28,9 @@ use garage_util::migrate::Migrate; use garage_model::garage::Garage; use garage_model::s3::object_table::{ObjectVersionEncryption, ObjectVersionMetaInner}; -use crate::common_error::*; -use crate::s3::checksum::Md5Checksum; -use crate::s3::error::Error; +use crate::checksum::Md5Checksum; +use crate::error::Error; +use garage_api_common::common_error::*; const X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_ALGORITHM: HeaderName = HeaderName::from_static("x-amz-server-side-encryption-customer-algorithm"); diff --git a/src/api/s3/error.rs b/src/api/s3/error.rs index 22d2fe14..77dc07c8 100644 --- a/src/api/s3/error.rs +++ b/src/api/s3/error.rs @@ -6,13 +6,18 @@ use hyper::{HeaderMap, StatusCode}; use garage_model::helper::error::Error as HelperError; -pub(crate) use crate::common_error::pass_helper_error; -use crate::common_error::{helper_error_as_internal, CommonError}; -pub use crate::common_error::{CommonErrorDerivative, OkOrBadRequest, OkOrInternalError}; -use crate::generic_server::ApiError; -use crate::helpers::*; -use crate::s3::xml as s3_xml; -use crate::signature::error::Error as SignatureError; +pub(crate) use garage_api_common::common_error::pass_helper_error; + +use garage_api_common::common_error::{helper_error_as_internal, CommonError}; + +pub use garage_api_common::common_error::{ + CommonErrorDerivative, OkOrBadRequest, OkOrInternalError, +}; + +use crate::xml as s3_xml; +use garage_api_common::generic_server::ApiError; +use garage_api_common::helpers::*; +use garage_api_common::signature::error::Error as SignatureError; /// Errors of this crate #[derive(Debug, Error)] diff --git a/src/api/s3/get.rs b/src/api/s3/get.rs index f61aae11..c4cd9d48 100644 --- a/src/api/s3/get.rs +++ b/src/api/s3/get.rs @@ -25,11 +25,11 @@ use garage_model::garage::Garage; use garage_model::s3::object_table::*; use garage_model::s3::version_table::*; -use crate::helpers::*; -use crate::s3::api_server::ResBody; -use crate::s3::checksum::{add_checksum_response_headers, X_AMZ_CHECKSUM_MODE}; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; +use crate::api_server::ResBody; +use crate::checksum::{add_checksum_response_headers, X_AMZ_CHECKSUM_MODE}; +use crate::encryption::EncryptionParams; +use crate::error::*; +use garage_api_common::helpers::*; const X_AMZ_MP_PARTS_COUNT: &str = "x-amz-mp-parts-count"; diff --git a/src/api/s3/mod.rs b/src/api/s3/lib.rs index b9bb1a6f..fd99b443 100644 --- a/src/api/s3/mod.rs +++ b/src/api/s3/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate tracing; + pub mod api_server; pub mod error; diff --git a/src/api/s3/lifecycle.rs b/src/api/s3/lifecycle.rs index 7eb1c2cb..da211585 100644 --- a/src/api/s3/lifecycle.rs +++ b/src/api/s3/lifecycle.rs @@ -5,11 +5,11 @@ use hyper::{Request, Response, StatusCode}; use serde::{Deserialize, Serialize}; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::error::*; -use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; use garage_model::bucket_table::{ parse_lifecycle_date, Bucket, LifecycleExpiration as GarageLifecycleExpiration, diff --git a/src/api/s3/list.rs b/src/api/s3/list.rs index 68d6cbe6..de808c32 100644 --- a/src/api/s3/list.rs +++ b/src/api/s3/list.rs @@ -13,13 +13,13 @@ use garage_model::s3::object_table::*; use garage_table::EnumerationOrder; -use crate::encoding::*; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; -use crate::s3::multipart as s3_multipart; -use crate::s3::xml as s3_xml; +use crate::api_server::{ReqBody, ResBody}; +use crate::encryption::EncryptionParams; +use crate::error::*; +use crate::multipart as s3_multipart; +use crate::xml as s3_xml; +use garage_api_common::encoding::*; +use garage_api_common::helpers::*; const DUMMY_NAME: &str = "Dummy Key"; const DUMMY_KEY: &str = "GKDummyKey"; diff --git a/src/api/s3/multipart.rs b/src/api/s3/multipart.rs index 3db3e8aa..047ed06a 100644 --- a/src/api/s3/multipart.rs +++ b/src/api/s3/multipart.rs @@ -15,14 +15,14 @@ use garage_model::s3::mpu_table::*; use garage_model::s3::object_table::*; use garage_model::s3::version_table::*; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::checksum::*; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; -use crate::s3::put::*; -use crate::s3::xml as s3_xml; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::checksum::*; +use crate::encryption::EncryptionParams; +use crate::error::*; +use crate::put::*; +use crate::xml as s3_xml; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; // ---- diff --git a/src/api/s3/post_object.rs b/src/api/s3/post_object.rs index 5279ec6a..6416c523 100644 --- a/src/api/s3/post_object.rs +++ b/src/api/s3/post_object.rs @@ -16,15 +16,15 @@ use serde::Deserialize; use garage_model::garage::Garage; use garage_model::s3::object_table::*; -use crate::helpers::*; -use crate::s3::api_server::ResBody; -use crate::s3::checksum::*; -use crate::s3::cors::*; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; -use crate::s3::put::{get_headers, save_stream, ChecksumMode}; -use crate::s3::xml as s3_xml; -use crate::signature::payload::{verify_v4, Authorization}; +use crate::api_server::ResBody; +use crate::checksum::*; +use crate::cors::*; +use crate::encryption::EncryptionParams; +use crate::error::*; +use crate::put::{get_headers, save_stream, ChecksumMode}; +use crate::xml as s3_xml; +use garage_api_common::helpers::*; +use garage_api_common::signature::payload::{verify_v4, Authorization}; pub async fn handle_post_object( garage: Arc<Garage>, diff --git a/src/api/s3/put.rs b/src/api/s3/put.rs index bfb0dc9b..47dcb8f7 100644 --- a/src/api/s3/put.rs +++ b/src/api/s3/put.rs @@ -30,11 +30,11 @@ use garage_model::s3::block_ref_table::*; use garage_model::s3::object_table::*; use garage_model::s3::version_table::*; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::checksum::*; -use crate::s3::encryption::EncryptionParams; -use crate::s3::error::*; +use crate::api_server::{ReqBody, ResBody}; +use crate::checksum::*; +use crate::encryption::EncryptionParams; +use crate::error::*; +use garage_api_common::helpers::*; const PUT_BLOCKS_MAX_PARALLEL: usize = 3; diff --git a/src/api/s3/router.rs b/src/api/s3/router.rs index e7ac1d77..94951e80 100644 --- a/src/api/s3/router.rs +++ b/src/api/s3/router.rs @@ -3,9 +3,9 @@ use std::borrow::Cow; use hyper::header::HeaderValue; use hyper::{HeaderMap, Method, Request}; -use crate::helpers::Authorization; -use crate::router_macros::{generateQueryParameters, router_match}; -use crate::s3::error::*; +use crate::error::*; +use garage_api_common::helpers::Authorization; +use garage_api_common::router_macros::{generateQueryParameters, router_match}; router_match! {@func diff --git a/src/api/s3/website.rs b/src/api/s3/website.rs index fa36bc32..46decccf 100644 --- a/src/api/s3/website.rs +++ b/src/api/s3/website.rs @@ -4,11 +4,11 @@ use http_body_util::BodyExt; use hyper::{Request, Response, StatusCode}; use serde::{Deserialize, Serialize}; -use crate::helpers::*; -use crate::s3::api_server::{ReqBody, ResBody}; -use crate::s3::error::*; -use crate::s3::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; -use crate::signature::verify_signed_content; +use crate::api_server::{ReqBody, ResBody}; +use crate::error::*; +use crate::xml::{to_xml_with_header, xmlns_tag, IntValue, Value}; +use garage_api_common::helpers::*; +use garage_api_common::signature::verify_signed_content; use garage_model::bucket_table::*; use garage_util::data::*; diff --git a/src/api/s3/xml.rs b/src/api/s3/xml.rs index 1e569ade..e8af3ec0 100644 --- a/src/api/s3/xml.rs +++ b/src/api/s3/xml.rs @@ -1,7 +1,7 @@ use quick_xml::se::to_string; use serde::{Deserialize, Serialize, Serializer}; -use crate::s3::error::Error as ApiError; +use crate::error::Error as ApiError; pub fn to_xml_with_header<T: Serialize>(x: &T) -> Result<String, ApiError> { let mut xml = r#"<?xml version="1.0" encoding="UTF-8"?>"#.to_string(); |