diff --git a/.gitignore b/.gitignore index 9683926..4f75a7b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ .DS_Store +.env \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..77f5877 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +include .env +export $(shell sed 's/=.*//' .env) + +.PHONY: seed-mongo seed-mysql seed-postgres + +seed-mongo: + @echo "Seeding MongoDB..." + bash ./scripts/mongo/seed-mongo.sh + +seed-mongo-auth: + @echo "Seeding MongoDB with auth..." + bash ./scripts/mongo/seed-mongo.sh auth + +seed-mysql: + @echo "Seeding MySQL..." + mysql -h 127.0.0.1 -P "$$MYSQL_PORT" -u "$$MYSQL_USER" -p"$$MYSQL_PASSWORD" "$$MYSQL_DB" < ./scripts/mysql/seed-mysql.sql + + +seed-postgres: + @echo "Seeding Postgres..." + docker exec -i -e PGPASSWORD=$$PG_PASSWORD $$PG_CONTAINER \ + psql -U $$PG_USER -d $$PG_DB < ./scripts/postgres/seed.sql + +seed-postgres-1gb: + @echo "Seeding Postgres..." + docker exec -i -e PGPASSWORD=$$PG_PASSWORD $$PG_CONTAINER \ + psql -U $$PG_USER -d $$PG_DB < ./scripts/postgres/seed-1gb.sql + +seed-all: seed-mongo seed-mysql seed-postgres seed-postgres-1gb diff --git a/databases.json b/databases.json index 1fee13d..7b83c99 100644 --- a/databases.json +++ b/databases.json @@ -1,53 +1,43 @@ { "databases": [ { - "name": "Test database 1 - rust", + "name": "Test database 1 - PostgreSQL", "database": "devdb", "type": "postgresql", "username": "devuser", "password": "changeme", "port": 5432, - "host": "db", + "host": "db-postgres", "generated_id": "16678159-ff7e-4c97-8c83-0adeff214681" }, { - "name": "Test database 2 - rust", - "database": "devdb", - "type": "postgresql", - "username": "devuser", - "password": "changeme", - "port": 5432, - "host": "db", - "generated_id": "16678156-ff7e-4c97-8c83-0adeff214681" - }, - { - "name": "Test database 3 - rust", + "name": "Test database 2 - MariaDB", "database": "mariadb", "type": "mysql", "username": "mariadb", "password": "changeme", "port": 3306, - "host": "db2", + "host": "db-mariadb", "generated_id": "16678124-ff7e-4c97-8c83-0adeff214681" }, { - "name": "Test database 4 - rust", + "name": "Test database 4 - MongoDB Auth", "database": "testdbauth", "type": "mongodb", "username": "root", "password": "rootpassword", "port": 27017, - "host": "mongodb-auth", + "host": "db-mongodb-auth", "generated_id": "16678145-ff7e-4c97-8c83-0adeff214681" }, { - "name": "Test database 5 - rust", + "name": "Test database 5 - MongoDB", "database": "testdb", "type": "mongodb", "username": "", "password": "", "port": 27017, - "host": "mongodb", + "host": "db-mongodb", "generated_id": "16678147-ff7e-4c97-8c83-0adeff214681" } ] diff --git a/databases.toml b/databases.toml index a970784..635b343 100644 --- a/databases.toml +++ b/databases.toml @@ -1,29 +1,39 @@ [[databases]] -name = "Test database 1 - rust" +name = "Test database 1 - PostgreSQL" database = "devdb" type = "postgresql" username = "devuser" password = "changeme" port = 5432 -host = "db" +host = "db-postgres" generated_id = "16678159-ff7e-4c97-8c83-0adeff214689" [[databases]] -name = "Test database 2 - rust" -database = "devdb" -type = "postgresql" -username = "devuser" -password = "changeme" -port = 5432 -host = "db" -generated_id = "16678156-ff7e-4c97-8c83-0adeff214654" - -[[databases]] -name = "Test database 3 - rust" +name = "Test database 2 - MariaDB" database = "mariadb" type = "mysql" username = "mariadb" password = "changeme" port = 3306 -host = "db1" +host = "db-mariadb" generated_id = "16678124-ff7e-4c97-8c83-0adeff214667" + +[[databases]] +name = "Test database 3 - MongoDB Auth" +database = "testdbauth" +type = "mongodb" +username = "root" +password = "rootpassword" +port = 27017 +host = "db-mongodb-auth" +generated_id = "16678145-ff7e-4c97-8c83-0adeff214681" + +[[databases]] +name = "Test database 3 - MongoDB" +database = "testdb" +type = "mongodb" +username = "" +password = "" +port = 27017 +host = "db-mongodb" +generated_id = "16678147-ff7e-4c97-8c83-0adeff214681" diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 4be6eb4..194dae1 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -19,36 +19,6 @@ services: networks: - portabase - db: - image: postgres:17-alpine - ports: - - "5413:5432" - volumes: - - postgres-data:/var/lib/postgresql/data - environment: - - POSTGRES_DB=devdb - - POSTGRES_USER=devuser - - POSTGRES_PASSWORD=changeme - networks: - - portabase - - db2: - image: mariadb:latest - ports: - - "3313:3306" - environment: - - MYSQL_DATABASE=mariadb - - MYSQL_USER=mariadb - - MYSQL_PASSWORD=changeme - - MYSQL_RANDOM_ROOT_PASSWORD=yes - volumes: - - mariadb-data:/var/lib/mysql - networks: - - portabase - -volumes: - postgres-data: - mariadb-data: networks: diff --git a/docker-compose.yml b/docker-compose.yml index bdf86d6..998557c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,7 +15,7 @@ services: APP_ENV: development LOG: debug TZ: "Europe/Paris" - EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiMDEwZTM2MTQtNmMxMy00ZDMwLWE4YTItOTZjNjUyN2JmYzM3IiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ" + EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiM2Y4ZDBiMmMtYThjYi00MWIzLTk0NjAtZGMxMGE0N2E2NzlmIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ" #POOLING: 1 #DATABASES_CONFIG_FILE: "config.toml" extra_hosts: @@ -23,7 +23,8 @@ services: networks: - portabase - db: + db-postgres: + container_name: db-postgres image: postgres:17-alpine ports: - "5436:5432" @@ -36,7 +37,8 @@ services: networks: - portabase - db2: + db-mariadb: + container_name: db-mariadb image: mariadb:latest ports: - "3311:3306" @@ -51,8 +53,9 @@ services: - portabase - mongodb-auth: - image: mongo:8.2.3-noble + db-mongodb-auth: + container_name: db-mongodb-auth + image: mongo:latest ports: - "27082:27017" environment: @@ -64,26 +67,28 @@ services: - portabase volumes: - mongodb-data-auth:/data/db -# healthcheck: -# test: ["CMD", "mongosh", "-u", "root", "-p", "rootpassword", "--authenticationDatabase", "admin", "--eval", "db.adminCommand('ping')"] -# interval: 5s -# timeout: 5s -# retries: 10 + healthcheck: + test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ] + interval: 5s + timeout: 5s + retries: 10 -# mongodb: -# image: mongo:latest -# container_name: mongodb -# ports: -# - "27083:27017" -# volumes: -# - mongodb-data:/data/db -# healthcheck: -# test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')" ] -# interval: 5s -# timeout: 5s -# retries: 10 -# environment: -# MONGO_INITDB_DATABASE: testdb + db-mongodb: + container_name: db-mongodb + image: mongo:latest + ports: + - "27083:27017" + volumes: + - mongodb-data:/data/db + healthcheck: + test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')" ] + interval: 5s + timeout: 5s + retries: 10 + environment: + MONGO_INITDB_DATABASE: testdb + networks: + - portabase volumes: cargo-registry: @@ -91,10 +96,12 @@ volumes: postgres-data: mariadb-data: -# mongodb-data: + mongodb-data: mongodb-data-auth: networks: portabase: name: portabase_network - external: true \ No newline at end of file + external: true + +# docker network create portabase_network \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..b931fa8 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,12 @@ +# Seed instructions + +## MongoDB + +```bash +make seed-mongo +make seed-mongo-auth +make seed-mysql +make seed-postgres +make seed-postgres-1gb +make seed-all +``` diff --git a/scripts/mongo/seed-mongo.sh b/scripts/mongo/seed-mongo.sh new file mode 100644 index 0000000..5e98bb2 --- /dev/null +++ b/scripts/mongo/seed-mongo.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +# Usage: +# ./seed-mongo.sh -> no auth +# ./seed-mongo.sh auth -> with auth + +MODE=${1:-noauth} # default: noauth + +# Default values (can be overridden via .env) +MONGO_DB=${MONGO_DB:-testdb} +MONGO_PORT=${MONGO_PORT:-27017} + +# Auth variables +MONGO_AUTH_USERNAME=${MONGO_AUTH_USERNAME:-root} +MONGO_AUTH_PASSWORD=${MONGO_AUTH_PASSWORD:-rootpassword} +MONGO_AUTH_DB=${MONGO_AUTH_DB:-testdbauth} + +NUM_USERS=${NUM_USERS:-5000} + +# Build connection string +if [ "$MODE" = "auth" ]; then + MONGO_CONTAINER=${MONGO_AUTH_CONTAINER:-db-mongodb-auth} + URI="mongodb://$MONGO_AUTH_USERNAME:$MONGO_AUTH_PASSWORD@localhost:$MONGO_PORT/$MONGO_AUTH_DB?authSource=admin" + echo "Using authenticated MongoDB..." +else + MONGO_CONTAINER=${MONGO_CONTAINER:-db-mongodb} + URI="mongodb://localhost:$MONGO_PORT/$MONGO_DB" + echo "Using non-authenticated MongoDB..." +fi + +# Create temp JS seed file +SEED_FILE=$(mktemp /tmp/seed.XXXX.js) + +cat < "$SEED_FILE" +db = connect("$URI"); + +// Drop collections if exist +if (db.users) db.users.drop(); +if (db.products) db.products.drop(); + +// Generate users +const users = []; +for (let i = 1; i <= $NUM_USERS; i++) { + users.push({ + username: "user" + i, + email: "user" + i + "@example.com", + age: Math.floor(Math.random() * 60) + 18, + active: Math.random() > 0.5, + createdAt: new Date() + }); +} +db.users.insertMany(users); + +// Generate products +const products = []; +for (let i = 1; i <= Math.floor($NUM_USERS/10); i++) { + products.push({ + name: "Product " + i, + price: parseFloat((Math.random()*100).toFixed(2)), + stock: Math.floor(Math.random()*500), + createdAt: new Date() + }); +} +db.products.insertMany(products); + +print("Seed complete: " + users.length + " users, " + products.length + " products."); +EOF + +docker cp "$SEED_FILE" "$MONGO_CONTAINER:/seed.js" +docker exec -it "$MONGO_CONTAINER" mongosh /seed.js +rm "$SEED_FILE" diff --git a/scripts/seed-mysql.sql b/scripts/mysql/seed-mysql.sql similarity index 100% rename from scripts/seed-mysql.sql rename to scripts/mysql/seed-mysql.sql diff --git a/scripts/seed-1gb.sql b/scripts/postgres/seed-1gb.sql similarity index 100% rename from scripts/seed-1gb.sql rename to scripts/postgres/seed-1gb.sql diff --git a/scripts/seed.sql b/scripts/postgres/seed.sql similarity index 100% rename from scripts/seed.sql rename to scripts/postgres/seed.sql diff --git a/src/domain/factory.rs b/src/domain/factory.rs index 0d96c1f..b43fd74 100644 --- a/src/domain/factory.rs +++ b/src/domain/factory.rs @@ -1,5 +1,3 @@ -#![allow(dead_code)] - use crate::domain::mogodb::database::MongoDatabase; use crate::domain::mysql::database::MySQLDatabase; use crate::domain::postgres::database::PostgresDatabase; diff --git a/src/domain/mogodb/backup.rs b/src/domain/mogodb/backup.rs index cf8cd69..14556f9 100644 --- a/src/domain/mogodb/backup.rs +++ b/src/domain/mogodb/backup.rs @@ -1,7 +1,6 @@ -use crate::domain::mogodb::connection::select_mongo_path; +use crate::domain::mogodb::connection::{get_mongo_uri, select_mongo_path}; use crate::services::config::DatabaseConfig; use anyhow::{Context, Result}; -use std::collections::HashMap; use std::path::PathBuf; use std::process::Command; use tracing::{debug, error, info}; @@ -9,136 +8,27 @@ use tracing::{debug, error, info}; pub async fn run( cfg: DatabaseConfig, backup_dir: PathBuf, - env: HashMap, file_extension: &'static str, ) -> Result { tokio::task::spawn_blocking(move || -> Result { debug!("Starting MongoDB backup for database {}", cfg.name); let file_path = backup_dir.join(format!("{}{}", cfg.generated_id, file_extension)); - let mongodump = select_mongo_path().join("mongodump"); - - // let output = Command::new(mongodump) - // .arg("--host") - // .arg(&cfg.host) - // .arg("--port") - // .arg(cfg.port.to_string()) - // .arg("--username") - // .arg(&cfg.username) - // .arg("--password") - // .arg(&cfg.password) - // .arg("--db") - // .arg(&cfg.database) - // // .arg("--authenticationDatabase") - // // .arg("admin") - // .arg("--archive") - // .arg(&file_path) - // .arg("--gzip") - // .envs(env) - // .output() - // .with_context(|| format!("Failed to run mongodump for {}", cfg.name))?; - - // let uri = format!( - // "mongodb://{}:{}@{}:{}/{}", - // cfg.username, cfg.password, cfg.host, cfg.port, cfg.database - // ); - // - // info!("MongoDB backup URL: {}", uri); - // - // let output = Command::new(mongodump) - // .arg("--uri") - // .arg(&uri) - // .arg("--archive") - // .arg(&file_path) - // .arg("--gzip") - // .envs(env) - // .output() - // .with_context(|| format!("Failed to run mongodump for {}", cfg.name))?; - - // let uri = format!( - // "mongodb://root:rootpassword@mongodb-auth:27017/testdbauth?authSource=admin" - // ); - // - // let output = Command::new(select_mongo_path().join(mongodump)) - // .arg("--uri") - // .arg(&uri) - // .arg("--archive") - // .arg(&file_path) - // .arg("--gzip") - // // .envs(env) - // .output() - // .with_context(|| format!("Failed to run mongodump for {}", cfg.name))?; - // let mut output = Command::new(mongodump); - // - // output.env_remove("MONGODB_URI"); - // output.env_remove("MONGO_URL"); - // - // // let output = Command::new(select_mongo_path().join(mongodump)) - // output.arg("--host") - // .arg(&cfg.host) - // .arg("--port") - // .arg(cfg.port.to_string()) - // .arg("--username") - // .arg(&cfg.username) - // .arg("--password") - // .arg(&cfg.password) - // .arg("--authenticationDatabase") - // .arg("admin") - // .arg("--db") - // .arg(&cfg.database) - // .arg("--archive") - // .arg(&file_path) - // .arg("--gzip") - // // .envs(env) - // .output()?; - - // let mut cmd = Command::new(mongodump); - // - // // Neutralisation explicite de toute URI Mongo héritée - // cmd.env_remove("MONGODB_URI"); - // cmd.env_remove("MONGO_URL"); - // - // // Commande mongodump en mode flags (une seule source de connexion) - // cmd - // .arg("--host") - // .arg(&cfg.host) - // .arg("--port") - // .arg(cfg.port.to_string()) - // .arg("--username") - // .arg(&cfg.username) - // .arg("--password") - // .arg(&cfg.password) - // .arg("--authenticationDatabase") - // .arg("admin") - // .arg("--db") - // .arg(&cfg.database) - // .arg("--archive") - // .arg(&file_path) - // .arg("--gzip") - // .envs(env); - let uri = format!( - "mongodb://{}:{}@{}:{}/{}?authSource=admin", - cfg.username, - cfg.password, - cfg.host, - cfg.port, - cfg.database - ); + let uri = get_mongo_uri(cfg.clone()); let output = Command::new(mongodump) .arg(format!("--uri={}", uri)) .arg(format!("--archive={}", file_path.display())) + .arg("--gzip") .output() .context("MongoDB backup failed")?; - // let output = cmd.output()?; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); error!("MongoDB backup failed for {}: {}", cfg.name, stderr); anyhow::bail!("MongoDB backup failed for {}: {}", cfg.name, stderr); } - info!("MongoDB backup completed for {}", cfg.name); Ok(file_path) }) diff --git a/src/domain/mogodb/connection.rs b/src/domain/mogodb/connection.rs index fe6b789..ef760f2 100644 --- a/src/domain/mogodb/connection.rs +++ b/src/domain/mogodb/connection.rs @@ -1,32 +1,28 @@ use crate::services::config::DatabaseConfig; -use anyhow::{Context, Result}; -use mongodb::{Client}; +use anyhow::Result; +use mongodb::Client; pub async fn connect(cfg: DatabaseConfig) -> Result { - let uri = if cfg.username.is_empty() && cfg.password.is_empty() { - // MongoDB sans auth - format!("mongodb://{}:{}", cfg.host, cfg.port) - } else { - // MongoDB avec auth - format!( - "mongodb://{}:{}@{}:{}/?authSource=admin", - cfg.username, cfg.password, cfg.host, cfg.port - ) - }; - - let mut options = mongodb::options::ClientOptions::parse(&uri) - .await - .with_context(|| format!("Failed to parse MongoDB URI for {}", cfg.name))?; - - options.app_name = Some("my-rust-app".to_string()); - - let client = Client::with_options(options) - .with_context(|| format!("Failed to create MongoDB client for {}", cfg.name))?; - + let uri = get_mongo_uri(cfg); + let mut options = mongodb::options::ClientOptions::parse(&uri).await?; + options.server_selection_timeout = Some(std::time::Duration::from_secs(3)); + options.connect_timeout = Some(std::time::Duration::from_secs(3)); + let client = Client::with_options(options)?; Ok(client) } - pub fn select_mongo_path() -> std::path::PathBuf { "/usr/local/mongodb/bin".to_string().into() -} \ No newline at end of file +} + +pub fn get_mongo_uri(cfg: DatabaseConfig) -> String { + if cfg.username.is_empty() { + format!("mongodb://{}:{}/{}", cfg.host, cfg.port, cfg.database) + + } else { + format!( + "mongodb://{}:{}@{}:{}/{}?authSource=admin", + cfg.username, cfg.password, cfg.host, cfg.port, cfg.database + ) + } +} diff --git a/src/domain/mogodb/database.rs b/src/domain/mogodb/database.rs index b88e037..4e31ac1 100644 --- a/src/domain/mogodb/database.rs +++ b/src/domain/mogodb/database.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use anyhow::Result; use async_trait::async_trait; use std::path::{Path, PathBuf}; @@ -16,10 +15,6 @@ impl MongoDatabase { pub fn new(cfg: DatabaseConfig) -> Self { Self { cfg } } - - fn build_env(&self) -> HashMap { - std::env::vars().collect() - } } #[async_trait] @@ -29,7 +24,7 @@ impl Database for MongoDatabase { } async fn ping(&self) -> Result { - ping::run(self.cfg.clone(), self.build_env()).await + ping::run(self.cfg.clone()).await } async fn backup(&self, dir: &Path) -> Result { @@ -37,7 +32,6 @@ impl Database for MongoDatabase { let res = backup::run( self.cfg.clone(), dir.to_path_buf(), - self.build_env(), self.file_extension(), ) .await; diff --git a/src/domain/mogodb/ping.rs b/src/domain/mogodb/ping.rs index 5e1fc98..865455b 100644 --- a/src/domain/mogodb/ping.rs +++ b/src/domain/mogodb/ping.rs @@ -1,25 +1,24 @@ #![allow(dead_code)] -// use crate::domain::mogodb::connection::connect; use crate::services::config::DatabaseConfig; use anyhow::Result; -// use mongodb::bson::doc; -use std::collections::HashMap; +use mongodb::bson::doc; +use tracing::{error}; +use crate::domain::mogodb::connection::connect; -pub async fn run(cfg: DatabaseConfig, _env: HashMap) -> Result { - // let client = connect(cfg.clone()).await?; - - // - // let db_name = if cfg.username.is_empty() { &cfg.database } else { "admin" }; - // let result = client.database(db_name).run_command(doc! { "ping": 1 }).await; - // - // match result { - // Ok(_) => Ok(true), - // Err(e) => Err(anyhow::anyhow!( - // "Failed to ping MongoDB server {}: {}", - // cfg.name, - // e - // )), - // } - Ok(true) +pub async fn run(cfg: DatabaseConfig) -> Result { + let client = connect(cfg.clone()).await?; + let db_name = if cfg.username.is_empty() { &cfg.database } else { "admin" }; + match client.database(db_name).run_command(doc! {"ping": 1}).await { + Ok(_) => Ok(true), + Err(e) => { + error!("--- MongoDB Connection Error Details ---"); + error!("Target Host: {}:{}", cfg.host, cfg.port); + error!("Error Kind: {:?}", e.kind); + error!("Full Error: {}", e); + error!("Check you database network connectivity"); + error!("----------------------------------------"); + Err(anyhow::anyhow!("Ping failed for {}: {}", cfg.name, e)) + } + } } diff --git a/src/domain/mogodb/restore.rs b/src/domain/mogodb/restore.rs index aa2e6bb..ba6b4d1 100644 --- a/src/domain/mogodb/restore.rs +++ b/src/domain/mogodb/restore.rs @@ -1,4 +1,4 @@ -use crate::domain::mogodb::connection::select_mongo_path; +use crate::domain::mogodb::connection::{get_mongo_uri, select_mongo_path}; use crate::services::config::DatabaseConfig; use anyhow::{Context, Result}; use std::path::PathBuf; @@ -10,22 +10,13 @@ pub async fn run(cfg: DatabaseConfig, restore_file: PathBuf) -> Result<()> { debug!("Starting MongoDB restore for database {}", cfg.name); let mongorestore = select_mongo_path().join("mongorestore"); + let uri = get_mongo_uri(cfg.clone()); let output = Command::new(mongorestore) - .arg("--host") - .arg(&cfg.host) - .arg("--port") - .arg(cfg.port.to_string()) - .arg("--username") - .arg(&cfg.username) - .arg("--password") - .arg(&cfg.password) - .arg("--db") - .arg(&cfg.database) - .arg("--drop") - .arg("--archive") - .arg(&restore_file) + .arg(format!("--uri={}", uri)) + .arg(format!("--archive={}", restore_file.display())) .arg("--gzip") + .arg("--drop") .output() .with_context(|| format!("Failed to run mongorestore for {}", cfg.name))?; diff --git a/src/services/backup.rs b/src/services/backup.rs index f618976..f049751 100644 --- a/src/services/backup.rs +++ b/src/services/backup.rs @@ -7,7 +7,6 @@ use crate::utils::common::BackupMethod; use crate::utils::file::full_extension; use anyhow::Result; use hex; -use tracing::{error, info}; use openssl::encrypt::Encrypter; use openssl::hash::MessageDigest; use openssl::pkey::PKey; @@ -19,6 +18,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use tempfile::TempDir; use tokio::fs; +use tracing::{error, info}; #[derive(Debug)] pub struct BackupResult { diff --git a/src/services/restore.rs b/src/services/restore.rs index abef77f..4d37fce 100644 --- a/src/services/restore.rs +++ b/src/services/restore.rs @@ -101,6 +101,7 @@ impl RestoreService { let db_instance = DatabaseFactory::create_for_restore(cfg.clone(), &backup_file_path).await; let reachable = db_instance.ping().await.unwrap_or(false); + info!("Reachable: {}", reachable); if !reachable { return Ok(RestoreResult { generated_id,