Albatross/src/remote/ftps.rs

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
}
}