Create an Adapter to bridge the APIs between SFTP and FTP libraries
This commit is contained in:
parent
eb5cecc782
commit
80851a887f
|
@ -0,0 +1,107 @@
|
|||
module VagrantPlugins
|
||||
module FTPPush
|
||||
class Adapter
|
||||
attr_reader :host
|
||||
attr_reader :port
|
||||
attr_reader :username
|
||||
attr_reader :password
|
||||
attr_reader :options
|
||||
attr_reader :server
|
||||
|
||||
def initialize(host, username, password, options = {})
|
||||
@host, @port = parse_host(host)
|
||||
@username = username
|
||||
@password = password
|
||||
@options = options
|
||||
@server = nil
|
||||
end
|
||||
|
||||
# Parse the host into it's url and port parts.
|
||||
# @return [Array]
|
||||
def parse_host(host)
|
||||
if host.include?(":")
|
||||
split = host.split(":", 2)
|
||||
[split[0], split[1].to_i]
|
||||
else
|
||||
[host, default_port]
|
||||
end
|
||||
end
|
||||
|
||||
def default_port
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def connect(&block)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def upload(local, remote)
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# The FTP Adapter
|
||||
#
|
||||
class FTPAdapter < Adapter
|
||||
def initialize(*)
|
||||
require "net/ftp"
|
||||
super
|
||||
end
|
||||
|
||||
def default_port
|
||||
20
|
||||
end
|
||||
|
||||
def connect(&block)
|
||||
@server = Net::FTP.new
|
||||
@server.passive = options.fetch(:passive, true)
|
||||
@server.connect(host, port)
|
||||
@server.login(username, password)
|
||||
|
||||
begin
|
||||
yield self
|
||||
ensure
|
||||
@server.close
|
||||
end
|
||||
end
|
||||
|
||||
def upload(local, remote)
|
||||
parent = File.dirname(remote)
|
||||
|
||||
# Create the parent directory if it does not exist
|
||||
if !@server.list("/").any? { |f| f.start_with?(parent) }
|
||||
@server.mkdir(parent)
|
||||
end
|
||||
|
||||
# Upload the file
|
||||
@server.putbinaryfile(local, remote)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# The SFTP Adapter
|
||||
#
|
||||
class SFTPAdapter < Adapter
|
||||
def initialize(*)
|
||||
require "net/sftp"
|
||||
super
|
||||
end
|
||||
|
||||
def default_port
|
||||
22
|
||||
end
|
||||
|
||||
def connect(&block)
|
||||
Net::SFTP.start(@host, @username, password: @password, port: @port) do |server|
|
||||
@server = server
|
||||
yield self
|
||||
end
|
||||
end
|
||||
|
||||
def upload(local, remote)
|
||||
@server.upload!(local, remote, mkdir: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,111 @@
|
|||
require_relative "../../../base"
|
||||
require "fake_ftp"
|
||||
|
||||
require Vagrant.source_root.join("plugins/pushes/ftp/adapter")
|
||||
|
||||
describe VagrantPlugins::FTPPush::Adapter do
|
||||
include_context "unit"
|
||||
|
||||
subject do
|
||||
described_class.new("127.0.0.1:2345", "sethvargo", "bacon",
|
||||
foo: "bar",
|
||||
)
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
it "sets the instance variables" do
|
||||
expect(subject.host).to eq("127.0.0.1")
|
||||
expect(subject.port).to eq(2345)
|
||||
expect(subject.username).to eq("sethvargo")
|
||||
expect(subject.password).to eq("bacon")
|
||||
expect(subject.options).to eq(foo: "bar")
|
||||
expect(subject.server).to be(nil)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#parse_host" do
|
||||
it "has a default value" do
|
||||
allow(subject).to receive(:default_port)
|
||||
.and_return(5555)
|
||||
|
||||
result = subject.parse_host("127.0.0.1")
|
||||
expect(result[0]).to eq("127.0.0.1")
|
||||
expect(result[1]).to eq(5555)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe VagrantPlugins::FTPPush::FTPAdapter do
|
||||
include_context "unit"
|
||||
|
||||
before(:all) do
|
||||
@server = FakeFtp::Server.new(21212, 21213)
|
||||
@server.start
|
||||
end
|
||||
|
||||
after(:all) { @server.stop }
|
||||
|
||||
let(:server) { @server }
|
||||
|
||||
before { server.reset }
|
||||
|
||||
subject do
|
||||
described_class.new("127.0.0.1:#{server.port}", "sethvargo", "bacon")
|
||||
end
|
||||
|
||||
describe "#default_port" do
|
||||
it "is 20" do
|
||||
expect(subject.default_port).to eq(20)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#upload" do
|
||||
before do
|
||||
@dir = Dir.mktmpdir
|
||||
FileUtils.touch("#{@dir}/file")
|
||||
end
|
||||
|
||||
after do
|
||||
FileUtils.rm_rf(@dir)
|
||||
end
|
||||
|
||||
it "uploads the file" do
|
||||
subject.connect do |ftp|
|
||||
ftp.upload("#{@dir}/file", "/file")
|
||||
end
|
||||
|
||||
expect(server.files).to include("file")
|
||||
end
|
||||
|
||||
it "uploads in passive mode" do
|
||||
subject.options[:passive] = true
|
||||
subject.connect do |ftp|
|
||||
ftp.upload("#{@dir}/file", "/file")
|
||||
end
|
||||
|
||||
expect(server.file("file")).to be_passive
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe VagrantPlugins::FTPPush::SFTPAdapter do
|
||||
include_context "unit"
|
||||
|
||||
subject do
|
||||
described_class.new("127.0.0.1:2345", "sethvargo", "bacon",
|
||||
foo: "bar",
|
||||
)
|
||||
end
|
||||
|
||||
describe "#default_port" do
|
||||
it "is 22" do
|
||||
expect(subject.default_port).to eq(22)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#upload" do
|
||||
it "uploads the file" do
|
||||
pending "a way to mock an SFTP server"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue