Skip to content

Commit

Permalink
Added s3 supprt
Browse files Browse the repository at this point in the history
  • Loading branch information
Lol3rrr committed Oct 30, 2023
1 parent 94b2c64 commit 8d52486
Show file tree
Hide file tree
Showing 9 changed files with 509 additions and 12 deletions.
364 changes: 362 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ tracing = { version = "0.1.37", features = ["async-await"] }
tracing-subscriber = "0.3.17"
rust_xlsxwriter = { version = "0.44" }
prometheus = "0.13.3"
aws-creds = {version = "0.36.0", default_features = false, features = ["attohttpc", "http-credentials", "rustls-tls"]}
rust-s3 = { version = "0.33.0", default_features = false, features = ["reqwest", "tokio", "tokio-rustls-tls", "no-verify-ssl"] }
1 change: 1 addition & 0 deletions README-md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Gold-Pass
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Gold-Pass-Bot

## Environment-Variables
* `S3_BUCKET`
* `S3_ACCESS_KEY`
* `S3_SECRET_KEY`
30 changes: 27 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use gold_pass_bot::{
ClanTag, ExcelStats, FileStorage, RaidMember, RaidWeekendStats, Season, Storage, StorageBackend,
ClanTag, ExcelStats, FileStorage, RaidMember, RaidWeekendStats, Replicated, S3Storage, Season,
Storage, StorageBackend,
};
use serenity::async_trait;
use serenity::framework::standard::macros::{command, group};
Expand Down Expand Up @@ -43,6 +44,10 @@ async fn main() {
let store_path = std::env::var("STORE_PATH").unwrap_or_else(|_| "data.json".to_string());
let api_path = std::env::var("API_PATH").unwrap_or_else(|_| "api.key".to_string());

let s3_bucket = std::env::var("S3_BUCKET").unwrap();
let s3_access_key = std::env::var("S3_ACCESS_KEY").unwrap();
let s3_secret_key = std::env::var("S3_SECRET_KEY").unwrap();

#[cfg(not(debug_assertions))]
let prefix = "!";
#[cfg(debug_assertions)]
Expand All @@ -61,8 +66,27 @@ async fn main() {
.await
.expect("Error creating client");

let mut storage_backend: Box<dyn StorageBackend> =
Box::new(FileStorage::new(store_path.clone()));
let mut storage_backend: Box<dyn StorageBackend> = Box::new(Replicated::new(
FileStorage::new(store_path.clone()),
S3Storage::new(
s3::Bucket::new(
&s3_bucket,
s3::Region::Custom {
region: "default".to_string(),
endpoint: "https://ceph-s3.service.aachen.dc.consul:7480".to_string(),
},
s3::creds::Credentials::new(
Some(&s3_access_key),
Some(&s3_secret_key),
None,
None,
None,
)
.unwrap(),
)
.unwrap(),
),
));

let elapsed = SystemTime::now()
.duration_since(UNIX_EPOCH)
Expand Down
12 changes: 8 additions & 4 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ use crate::{ClanTag, ClanWarLeagueSeason, PlayerTag, Time};
mod files;
pub use files::FileStorage;

mod s3;
pub use s3::S3Storage;

mod replicated;
pub use replicated::Replicated;

pub trait StorageBackend: Send {
fn write(
&mut self,
content: Vec<u8>,
) -> Pin<Box<dyn Future<Output = Result<(), ()>> + Send + Sync + 'static>>;
fn load(
&mut self,
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, ()>> + Send + Sync + 'static>>;
) -> Pin<Box<dyn Future<Output = Result<(), ()>> + Send + 'static>>;
fn load(&mut self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, ()>> + Send + 'static>>;
}

#[derive(Debug, Clone, Deserialize, Serialize)]
Expand Down
5 changes: 2 additions & 3 deletions src/storage/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl StorageBackend for FileStorage {
fn write(
&mut self,
content: Vec<u8>,
) -> Pin<Box<dyn std::future::Future<Output = Result<(), ()>> + Send + Sync + 'static>> {
) -> Pin<Box<dyn std::future::Future<Output = Result<(), ()>> + Send + 'static>> {
let path = self.path.clone();

Box::pin(async move {
Expand All @@ -45,8 +45,7 @@ impl StorageBackend for FileStorage {

fn load(
&mut self,
) -> Pin<Box<dyn std::future::Future<Output = Result<Vec<u8>, ()>> + Send + Sync + 'static>>
{
) -> Pin<Box<dyn std::future::Future<Output = Result<Vec<u8>, ()>> + Send + 'static>> {
let path = self.path.clone();

Box::pin(async move { tokio::fs::read(&path).await.map_err(|e| ()) })
Expand Down
49 changes: 49 additions & 0 deletions src/storage/replicated.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::StorageBackend;

pub struct Replicated<P, S> {
primary: P,
secondary: S,
}

impl<P, S> Replicated<P, S> {
pub fn new(primary: P, secondary: S) -> Self {
Self { primary, secondary }
}
}

impl<P, S> StorageBackend for Replicated<P, S>
where
P: StorageBackend,
S: StorageBackend,
{
fn write(
&mut self,
content: Vec<u8>,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), ()>> + Send + 'static>> {
let pfut = self.primary.write(content.clone());
let sfut = self.secondary.write(content);

Box::pin(async move {
let pres = pfut.await;
let sres = sfut.await;

pres.or(sres)
})
}

fn load(
&mut self,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Vec<u8>, ()>> + Send + 'static>>
{
let pfut = self.primary.load();
let sfut = self.secondary.load();

Box::pin(async move {
if let Ok(r) = pfut.await {
return Ok(r);
}

sfut.await
})
}
}
52 changes: 52 additions & 0 deletions src/storage/s3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::StorageBackend;

pub struct S3Storage {
bucket: s3::Bucket,
filename: String,
}

impl S3Storage {
pub fn new(bucket: s3::Bucket) -> Self {
Self {
bucket,
filename: "/storage.json".to_string(),
}
}
}

impl StorageBackend for S3Storage {
fn write(
&mut self,
content: Vec<u8>,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), ()>> + Send + 'static>> {
let bucket = self.bucket.clone();
let filename = self.filename.clone();

Box::pin(async move {
let filename = filename;
let content = content;

let res = bucket.put_object(&filename, &content);

match res.await {
Ok(_) => Ok(()),
Err(e) => Err(()),
}
})
}

fn load(
&mut self,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Vec<u8>, ()>> + Send + 'static>>
{
let bucket = self.bucket.clone();
let filename = self.filename.clone();

Box::pin(async move {
match bucket.get_object(filename).await {
Ok(c) => Ok(c.to_vec()),
Err(e) => Err(()),
}
})
}
}

0 comments on commit 8d52486

Please sign in to comment.