monitoring file system changes over sftp using rust (no ssh access)

183 Views Asked by At

I am trying to monitor filesystem changes over sftp. If anyone uploads a file to directory, or one specific file is modified, i would like to be notified.

I tried inotify-rs. The following code works perfectly on local filesystem, but i don't know how to make it work for sftp.

extern crate inotify;
use std::env;
use inotify::{
    EventMask,
    WatchMask,
    Inotify,
};

fn main() {
    let mut inotify = Inotify::init()
        .expect("Failed to initialize inotify");

    let current_dir = env::current_dir()
        .expect("Failed to determine current directory");

    inotify
        .watches()
        .add(
            current_dir,
            WatchMask::MODIFY | WatchMask::CREATE | WatchMask::DELETE,
        )
        .expect("Failed to add inotify watch");

    println!("Watching current directory for activity...");

    let mut buffer = [0u8; 4096];
    loop {
        let events = inotify
            .read_events_blocking(&mut buffer)
            .expect("Failed to read inotify events");

        for event in events {
            println!("File modified: {:?}", event.name);  
        }
    }
}

In the following code snippets, i have tried to use inotify system to connect over sftp.

  1. passing sftp URI:
    let current_dir = std::path::Path::new("sftp://user@ip:port/path")
        .expect("Failed to determine current directory");

needless to say, this approach did not work.

  1. using an sftp connection object from ssh2 crate:
    let tcp = TcpStream::connect(self.ip_with_port()).unwrap();
    let mut sess = Session::new().unwrap();
    sess.set_tcp_stream(tcp);
    sess.handshake().unwrap();
    sess.userauth_password(&self.user, &self.pwd)?;
    let sftp = sess.sftp().unwrap();
    

    let current_dir = sftp.realpath(std::path::Path::new("<path to sftp file>"))
        .expect("Failed to determine current directory");

I believe one possible direction to look for the solution to this problem is syncing over sftp. Tools like rsync, csync, lftp. Even if any of these tools work, i have to figure out a way to include them inside my rust binary.

XY Problem

Just in case, i am using the wrong X to solve my actual problem Y, i will also mention why do i want to monitor changes to a sftp server.

Y: we have multiple servers of our customers using our product. The only interface we have to each of our customer servers is an sftp server (security reasons). The sftp server is our middle-man. Currently we have engineers, responsible for managing our product deployment for each customer. So there is approx one engineer to monitor our product on every 2-3 customer servers. So lot of wasteful engineer hours.

X: One way we can monitor all customer servers at one place, is by running a service that monitors changes to the middle-man sftp. If we can do this we can have a service sending json files (containing sql queries, etc. to run on each customer DB) to sftp, which then is read by all customer servers, because they are monitoring for changes in middle-man sftp.

0

There are 0 best solutions below