Fix signatures and add basic code that makes a request
(and it crashes yeah yeah yeah)
This commit is contained in:
parent
574d88a02f
commit
cec08a23af
6 changed files with 63 additions and 17 deletions
22
k2v_test.py
Executable file
22
k2v_test.py
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# let's talk to our AWS Elasticsearch cluster
|
||||||
|
#from requests_aws4auth import AWS4Auth
|
||||||
|
#auth = AWS4Auth('GK31c2f218a2e44f485b94239e',
|
||||||
|
# 'b892c0665f0ada8a4755dae98baa3b133590e11dae3bcc1f9d769d67f16c3835',
|
||||||
|
# 'us-east-1',
|
||||||
|
# 's3')
|
||||||
|
|
||||||
|
from aws_requests_auth.aws_auth import AWSRequestsAuth
|
||||||
|
auth = AWSRequestsAuth(aws_access_key='GK31c2f218a2e44f485b94239e',
|
||||||
|
aws_secret_access_key='b892c0665f0ada8a4755dae98baa3b133590e11dae3bcc1f9d769d67f16c3835',
|
||||||
|
aws_host='localhost:3812',
|
||||||
|
aws_region='us-east-1',
|
||||||
|
aws_service='k2v')
|
||||||
|
|
||||||
|
|
||||||
|
response = requests.get('http://localhost:3812/alex',
|
||||||
|
auth=auth)
|
||||||
|
print(response.content)
|
|
@ -42,7 +42,7 @@ pub(crate) trait ApiHandler: Send + Sync + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct ApiServer<A: ApiHandler> {
|
pub(crate) struct ApiServer<A: ApiHandler> {
|
||||||
s3_region: String,
|
region: String,
|
||||||
api_handler: A,
|
api_handler: A,
|
||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
|
@ -52,10 +52,10 @@ pub(crate) struct ApiServer<A: ApiHandler> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: ApiHandler> ApiServer<A> {
|
impl<A: ApiHandler> ApiServer<A> {
|
||||||
pub fn new(s3_region: String, api_handler: A) -> Arc<Self> {
|
pub fn new(region: String, api_handler: A) -> Arc<Self> {
|
||||||
let meter = global::meter("garage/api");
|
let meter = global::meter("garage/api");
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
s3_region,
|
region,
|
||||||
api_handler,
|
api_handler,
|
||||||
request_counter: meter
|
request_counter: meter
|
||||||
.u64_counter(format!("api.{}.request_counter", A::API_NAME))
|
.u64_counter(format!("api.{}.request_counter", A::API_NAME))
|
||||||
|
@ -102,7 +102,7 @@ impl<A: ApiHandler> ApiServer<A> {
|
||||||
let server = Server::bind(&bind_addr).serve(service);
|
let server = Server::bind(&bind_addr).serve(service);
|
||||||
|
|
||||||
let graceful = server.with_graceful_shutdown(shutdown_signal);
|
let graceful = server.with_graceful_shutdown(shutdown_signal);
|
||||||
info!("API server listening on http://{}", bind_addr);
|
info!("{} API server listening on http://{}", A::API_NAME_DISPLAY, bind_addr);
|
||||||
|
|
||||||
graceful.await?;
|
graceful.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -119,7 +119,7 @@ impl<A: ApiHandler> ApiServer<A> {
|
||||||
|
|
||||||
let tracer = opentelemetry::global::tracer("garage");
|
let tracer = opentelemetry::global::tracer("garage");
|
||||||
let span = tracer
|
let span = tracer
|
||||||
.span_builder("S3 API call (unknown)")
|
.span_builder(format!("{} API call (unknown)", A::API_NAME_DISPLAY))
|
||||||
.with_trace_id(gen_trace_id())
|
.with_trace_id(gen_trace_id())
|
||||||
.with_attributes(vec![
|
.with_attributes(vec![
|
||||||
KeyValue::new("method", format!("{}", req.method())),
|
KeyValue::new("method", format!("{}", req.method())),
|
||||||
|
@ -138,7 +138,7 @@ impl<A: ApiHandler> ApiServer<A> {
|
||||||
Ok(x)
|
Ok(x)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let body: Body = Body::from(e.aws_xml(&self.s3_region, uri.path()));
|
let body: Body = Body::from(e.aws_xml(&self.region, uri.path()));
|
||||||
let mut http_error_builder = Response::builder()
|
let mut http_error_builder = Response::builder()
|
||||||
.status(e.http_status_code())
|
.status(e.http_status_code())
|
||||||
.header("Content-Type", "application/xml");
|
.header("Content-Type", "application/xml");
|
||||||
|
|
|
@ -38,14 +38,18 @@ impl K2VApiServer {
|
||||||
garage: Arc<Garage>,
|
garage: Arc<Garage>,
|
||||||
shutdown_signal: impl Future<Output = ()>,
|
shutdown_signal: impl Future<Output = ()>,
|
||||||
) -> Result<(), GarageError> {
|
) -> Result<(), GarageError> {
|
||||||
let addr = garage.config.s3_api.api_bind_addr;
|
if let Some(cfg) = &garage.config.k2v_api {
|
||||||
|
let bind_addr = cfg.api_bind_addr;
|
||||||
|
|
||||||
ApiServer::new(
|
ApiServer::new(
|
||||||
garage.config.s3_api.s3_region.clone(),
|
garage.config.s3_api.s3_region.clone(),
|
||||||
K2VApiServer { garage },
|
K2VApiServer { garage },
|
||||||
)
|
)
|
||||||
.run_server(addr, shutdown_signal)
|
.run_server(bind_addr, shutdown_signal)
|
||||||
.await
|
.await
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +95,7 @@ impl ApiHandler for K2VApiServer {
|
||||||
req,
|
req,
|
||||||
&mut content_sha256,
|
&mut content_sha256,
|
||||||
&garage.config.s3_api.s3_region,
|
&garage.config.s3_api.s3_region,
|
||||||
"s3",
|
"k2v",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let bucket_id = resolve_bucket(&garage, &bucket_name, &api_key).await?;
|
let bucket_id = resolve_bucket(&garage, &bucket_name, &api_key).await?;
|
||||||
|
|
|
@ -308,7 +308,7 @@ pub async fn verify_v4(
|
||||||
date,
|
date,
|
||||||
&key_p.secret_key,
|
&key_p.secret_key,
|
||||||
&garage.config.s3_api.s3_region,
|
&garage.config.s3_api.s3_region,
|
||||||
"s3",
|
service,
|
||||||
)
|
)
|
||||||
.ok_or_internal_error("Unable to build signing HMAC")?;
|
.ok_or_internal_error("Unable to build signing HMAC")?;
|
||||||
hmac.update(payload);
|
hmac.update(payload);
|
||||||
|
|
|
@ -9,6 +9,7 @@ use garage_util::error::Error;
|
||||||
use garage_admin::metrics::*;
|
use garage_admin::metrics::*;
|
||||||
use garage_admin::tracing_setup::*;
|
use garage_admin::tracing_setup::*;
|
||||||
use garage_api::s3::api_server::S3ApiServer;
|
use garage_api::s3::api_server::S3ApiServer;
|
||||||
|
use garage_api::k2v::api_server::K2VApiServer;
|
||||||
use garage_model::garage::Garage;
|
use garage_model::garage::Garage;
|
||||||
use garage_web::run_web_server;
|
use garage_web::run_web_server;
|
||||||
|
|
||||||
|
@ -62,6 +63,12 @@ pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
|
||||||
wait_from(watch_cancel.clone()),
|
wait_from(watch_cancel.clone()),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
info!("Initializing K2V API server...");
|
||||||
|
let k2v_api_server = tokio::spawn(K2VApiServer::run(
|
||||||
|
garage.clone(),
|
||||||
|
wait_from(watch_cancel.clone()),
|
||||||
|
));
|
||||||
|
|
||||||
info!("Initializing web server...");
|
info!("Initializing web server...");
|
||||||
let web_server = tokio::spawn(run_web_server(
|
let web_server = tokio::spawn(run_web_server(
|
||||||
garage.clone(),
|
garage.clone(),
|
||||||
|
@ -83,6 +90,9 @@ pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
|
||||||
if let Err(e) = s3_api_server.await? {
|
if let Err(e) = s3_api_server.await? {
|
||||||
warn!("S3 API server exited with error: {}", e);
|
warn!("S3 API server exited with error: {}", e);
|
||||||
}
|
}
|
||||||
|
if let Err(e) = k2v_api_server.await? {
|
||||||
|
warn!("K2V API server exited with error: {}", e);
|
||||||
|
}
|
||||||
if let Err(e) = web_server.await? {
|
if let Err(e) = web_server.await? {
|
||||||
warn!("Web server exited with error: {}", e);
|
warn!("Web server exited with error: {}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,10 @@ pub struct Config {
|
||||||
pub sled_flush_every_ms: u64,
|
pub sled_flush_every_ms: u64,
|
||||||
|
|
||||||
/// Configuration for S3 api
|
/// Configuration for S3 api
|
||||||
pub s3_api: ApiConfig,
|
pub s3_api: S3ApiConfig,
|
||||||
|
|
||||||
|
/// Configuration for K2V api
|
||||||
|
pub k2v_api: Option<K2VApiConfig>,
|
||||||
|
|
||||||
/// Configuration for serving files as normal web server
|
/// Configuration for serving files as normal web server
|
||||||
pub s3_web: WebConfig,
|
pub s3_web: WebConfig,
|
||||||
|
@ -85,7 +88,7 @@ pub struct Config {
|
||||||
|
|
||||||
/// Configuration for S3 api
|
/// Configuration for S3 api
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct ApiConfig {
|
pub struct S3ApiConfig {
|
||||||
/// Address and port to bind for api serving
|
/// Address and port to bind for api serving
|
||||||
pub api_bind_addr: SocketAddr,
|
pub api_bind_addr: SocketAddr,
|
||||||
/// S3 region to use
|
/// S3 region to use
|
||||||
|
@ -95,6 +98,13 @@ pub struct ApiConfig {
|
||||||
pub root_domain: Option<String>,
|
pub root_domain: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Configuration for K2V api
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct K2VApiConfig {
|
||||||
|
/// Address and port to bind for api serving
|
||||||
|
pub api_bind_addr: SocketAddr,
|
||||||
|
}
|
||||||
|
|
||||||
/// Configuration for serving files as normal web server
|
/// Configuration for serving files as normal web server
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct WebConfig {
|
pub struct WebConfig {
|
||||||
|
|
Loading…
Reference in a new issue