80 lines
2.2 KiB
Rust
80 lines
2.2 KiB
Rust
use ftp::native_tls::TlsConnector;
|
|
use ftp::FtpStream;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::config::RemoteBackupConfig;
|
|
use crate::error;
|
|
use crate::error::AlbatrossError;
|
|
use crate::remote::{PathLocation, RemoteBackupSite};
|
|
|
|
/// FTPS Remote Site
|
|
pub struct FTPSBackup {
|
|
/// FTP command stream
|
|
stream: FtpStream,
|
|
/// Remote target directory
|
|
target_dir: PathBuf,
|
|
/// Number of backups to keep
|
|
backups_to_keep: usize,
|
|
}
|
|
|
|
impl FTPSBackup {
|
|
/// New FTPSBackup
|
|
pub fn new(config: &RemoteBackupConfig) -> error::Result<Self> {
|
|
let ftps_config = config
|
|
.ftps
|
|
.as_ref()
|
|
.ok_or_else(|| AlbatrossError::RemoteConfigError("FTPS".to_string()))?;
|
|
|
|
let ctx = TlsConnector::new().unwrap();
|
|
let (ftp_stream, _) = FtpStream::connect(&ftps_config.server_addr)?;
|
|
|
|
let domain = ftps_config
|
|
.domain
|
|
.as_ref()
|
|
.map_or_else(|| "".to_string(), |s| s.clone());
|
|
let mut ftp_stream = ftp_stream.into_secure(ctx, domain.as_str())?;
|
|
ftp_stream.login(&ftps_config.username, &ftps_config.password)?;
|
|
|
|
Ok(Self {
|
|
stream: ftp_stream,
|
|
target_dir: ftps_config.remote_dir.clone(),
|
|
backups_to_keep: config.backups_to_keep as usize,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Drop for FTPSBackup {
|
|
fn drop(&mut self) {
|
|
self.stream.quit().ok();
|
|
}
|
|
}
|
|
|
|
impl RemoteBackupSite for FTPSBackup {
|
|
type FileType = PathLocation;
|
|
|
|
fn backup_to_remote(&mut self, file: PathBuf) -> error::Result<()> {
|
|
let mut local_file = std::fs::File::open(&file)?;
|
|
let location = self.target_dir.join(file);
|
|
self.stream
|
|
.put(location.to_str().unwrap(), &mut local_file)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn get_backups(&mut self) -> error::Result<Vec<Self::FileType>> {
|
|
let files = self.stream.list(Some(self.target_dir.to_str().unwrap()))?;
|
|
Ok(files
|
|
.into_iter()
|
|
.filter_map(|file| Self::FileType::new(PathBuf::from(file)))
|
|
.collect())
|
|
}
|
|
|
|
fn remove_backup(&mut self, backup: Self::FileType) -> error::Result<()> {
|
|
Ok(self.stream.rm(backup.location.to_str().unwrap())?)
|
|
}
|
|
|
|
fn backups_to_keep(&self) -> usize {
|
|
self.backups_to_keep
|
|
}
|
|
}
|