Class: SFTPWriter::Remote

Inherits:
Object
  • Object
show all
Defined in:
lib/sftp_writer/remote.rb

Instance Method Summary collapse

Constructor Details

#initialize(config, logger:) ⇒ Remote

Returns a new instance of Remote.



5
6
7
8
# File 'lib/sftp_writer/remote.rb', line 5

def initialize(config, logger:)
  @config = config
  @logger = logger
end

Instance Method Details

#closeObject



23
24
25
26
27
28
29
# File 'lib/sftp_writer/remote.rb', line 23

def close
  return unless @sftp && sftp.open?

  @logger.info('Disconnected from SFTP')
  sftp.session.close
  true
end

#mkdir_safe(path) ⇒ Object (private)

The Net::SFTP library handles making recursive paths really poorly: You can either upload and sync an entire directory, in which case it will make any missing folders… and also raise errors if any folders in the path already exist. Or you can upload files into a single root directory Or you can do something like this.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/sftp_writer/remote.rb', line 56

def mkdir_safe(path)
  dir = Pathname.new(path).dirname
  dirs = Array(dir.descend.to_a)
  # If we're using an absolute path, we can/should trust that the base folder
  # already exists. Remove `/` and `/BASE_FOLDER` from the list of things to
  # create -- they typically won't be our user, and so we'll hit a permission
  # error.
  dirs.shift(2) if dirs[0].to_s == '/'
  dirs.each do |f|
    sftp.mkdir!(f.to_s)
  rescue Net::SFTP::StatusException
    raise if $ERROR_INFO.code != Net::SFTP::Constants::StatusCodes::FX_FILE_ALREADY_EXISTS
  end
end

#sanitize(filename) ⇒ Object (private)



71
72
73
# File 'lib/sftp_writer/remote.rb', line 71

def sanitize(filename)
  filename.tr(':', '_')
end

#sftpObject



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/sftp_writer/remote.rb', line 10

def sftp
  @sftp ||= begin
    key_data = File.read(@config.key_path)
    Net::SFTP.start(
      @config.host,
      @config.user,
      port: @config.port,
      key_data: [key_data]
    )
  end
  @sftp
end

#write(contents, filename) ⇒ Object



41
42
43
44
45
46
# File 'lib/sftp_writer/remote.rb', line 41

def write(contents, filename)
  path = File.join([write_path(filename), sanitize(filename)].compact)
  @logger.info("Writing #{path}")
  mkdir_safe(path)
  sftp.upload!(StringIO.new(contents), path) if ENV['HOSTNAME'].eql?('api.va.gov') # only sftp on production
end

#write_path(filename) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/sftp_writer/remote.rb', line 31

def write_path(filename)
  if filename.starts_with?('307_')
    @config.relative_307_path || @config.relative_path || nil
  elsif filename.starts_with?('351_')
    @config.relative_351_path || @config.relative_path || nil
  else
    @config.relative_path || nil
  end
end