diff options
author | John Kerry <jk185160@ncr.com> | 2016-03-23 21:34:46 -0400 |
---|---|---|
committer | John Kerry <jk185160@ncr.com> | 2016-03-23 21:36:47 -0400 |
commit | 360d506c9cdf0e94071f0a656eafbc7d2f302d9a (patch) | |
tree | 6a8dd80bf6ba0c456245805fb338e524f72fa584 | |
parent | 8c8060ed20a6dd0a085a7484ce95a7d4967f407b (diff) | |
download | chef-360d506c9cdf0e94071f0a656eafbc7d2f302d9a.tar.gz |
Adding base implementation and the start of unit test coverage
-rw-r--r-- | lib/chef/provider/remote_file/fetcher.rb | 2 | ||||
-rw-r--r-- | lib/chef/provider/remote_file/sftp.rb | 75 | ||||
-rw-r--r-- | lib/chef/providers.rb | 1 | ||||
-rw-r--r-- | spec/unit/provider/remote_file/sftp_spec.rb | 19 |
4 files changed, 96 insertions, 1 deletions
diff --git a/lib/chef/provider/remote_file/fetcher.rb b/lib/chef/provider/remote_file/fetcher.rb index dad73cf17f..c138ee5d6b 100644 --- a/lib/chef/provider/remote_file/fetcher.rb +++ b/lib/chef/provider/remote_file/fetcher.rb @@ -31,6 +31,8 @@ class Chef Chef::Provider::RemoteFile::HTTP.new(uri, new_resource, current_resource) when "ftp" Chef::Provider::RemoteFile::FTP.new(uri, new_resource, current_resource) + when "sftp" + Chef::Provider::RemoteFile::SFTP.net(uri, new_resource, current_resource) when "file" Chef::Provider::RemoteFile::LocalFile.new(uri, new_resource, current_resource) else diff --git a/lib/chef/provider/remote_file/sftp.rb b/lib/chef/provider/remote_file/sftp.rb index 868ccb982c..4e2c0d2c9a 100644 --- a/lib/chef/provider/remote_file/sftp.rb +++ b/lib/chef/provider/remote_file/sftp.rb @@ -26,6 +26,81 @@ class Chef class Provider class RemoteFile class SFTP + + attr_reader :uri + attr_reader :new_resource + attr_reader :current_resource + + def initialize(uri, new_resource, current_resource) + @uri = uri + @new_resource = new_resource + @current_resource = current_resource + validate_path! + end + + def hostname + @uri.host + end + + def user + if uri.userinfo + URI.unescape(uri.user) + else + 'anonymous' + end + end + + def pass + if uri.userinfo + URI.unescape(uri.password) + else + nil + end + end + + def filename + parse_path if @filename.nil? + @filename + end + + def fetch + get + end + + def sftp + @sftp ||= Net::SFTP.start(hostname, user, :password => pass) + end + + private + + def validate_path! + parse_path + end + + # Fetches using Net::FTP, returns a Tempfile with the content + def get + tempfile = Chef::FileContentManagement::Tempfile.new(@new_resource).tempfile + sftp.download!(uri.path, tempfile.path) + tempfile.close if tempfile + tempfile + end + + def parse_path + path = uri.path.sub(%r{\A/}, '%2F') # re-encode the beginning slash because uri library decodes it. + directories = path.split(%r{/}, -1) + directories.each {|d| + d.gsub!(/%([0-9A-Fa-f][0-9A-Fa-f])/) { [$1].pack("H2") } + } + unless filename = directories.pop + raise ArgumentError, "no filename: #{path.inspect}" + end + if filename.length == 0 || filename.end_with?( "/" ) + raise ArgumentError, "no filename: #{path.inspect}" + end + + @directories, @filename = directories, filename + end + end end end diff --git a/lib/chef/providers.rb b/lib/chef/providers.rb index 6fd67e0068..e5635daed3 100644 --- a/lib/chef/providers.rb +++ b/lib/chef/providers.rb @@ -124,6 +124,7 @@ require "chef/provider/deploy/revision" require "chef/provider/deploy/timestamped" require "chef/provider/remote_file/ftp" +require "chef/provider/remote_file/sftp" require "chef/provider/remote_file/http" require "chef/provider/remote_file/local_file" require "chef/provider/remote_file/network_file" diff --git a/spec/unit/provider/remote_file/sftp_spec.rb b/spec/unit/provider/remote_file/sftp_spec.rb index 1e42b72af5..2cc473ae6b 100644 --- a/spec/unit/provider/remote_file/sftp_spec.rb +++ b/spec/unit/provider/remote_file/sftp_spec.rb @@ -20,7 +20,24 @@ require "spec_helper" describe Chef::Provider::RemoteFile::SFTP do #built out dependencies - let(:uri) { URI.Parse("sftp://opscode.com/seattle.txt") } + let(:enclosing_directory) { + canonicalize_path(File.expand_path(File.join(CHEF_SPEC_DATA, "templates"))) + } + let(:resource_path) { + canonicalize_path(File.expand_path(File.join(enclosing_directory, "seattle.txt"))) + } + + let(:new_resource) do + r = Chef::Resource::RemoteFile.new("remote file ftp backend test (new resource)") + r.path(resource_path) + r + end + + let(:current_resource) do + Chef::Resource::RemoteFile.new("remote file ftp backend test (current resource)'") + end + + let(:uri) { URI.parse("sftp://opscode.com/seattle.txt") } describe "on initialization" do |