diff --git a/spec/fixtures/integration/provider/sshkey/sample b/spec/fixtures/integration/provider/sshkey/sample new file mode 100644 index 000000000..840ed19df --- /dev/null +++ b/spec/fixtures/integration/provider/sshkey/sample @@ -0,0 +1,21 @@ +hosting2.planetargon.com,64.34.164.77 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAy+f2t52cDMrYkgEKQ6juqfMf/a0nDFry3JAzl+SAWQ0gTklVxNcVbfHx2pkZk66EBGQfrK33Bx1BflZ/iEDyiCwmzVtNba0X9A6ELYjB9WSkWdIqZCfPlKZMu9N//aZ6+3SDVuz/BVFsAVmtqQ4Let2QjOFiSIKXrtPqWvVT/MM= +kirby.madstop.com,192.168.0.5 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAw9iHuAa/wepHoUzWqsvhQvSkpE4K7agrdLOWHM9mvyRQ2X3HVq5GqzAvWu4J+f0FvcLPwA9tivpxt1oSt5MOtvDM6HoM+8m3P4daBp0nlNaYR8/vHCAmX6N3RyM8FWfp+VqWyux1SooQwxYxVFy86G78ApTqNsZ+p7cHmnBYqk0= +fedora1,192.168.0.51 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyz1rKcApU4//j8CHYKexq4qnq2WVqLPrZYGnlij1t7FscLiDVKvBuRHVkfyTNIjAM/t7tM1Dj+FuD4iWziCmf7RO9q4wI5y/1zgCiSUegnZVSmH2yxnWGMdHGpXOkN3NXcpy6jylxyBo0M7T22PSezCxyUVfMclesjOEO1jETd0= +kirby ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAw9iHuAa/wepHoUzWqsvhQvSkpE4K7agrdLOWHM9mvyRQ2X3HVq5GqzAvWu4J+f0FvcLPwA9tivpxt1oSt5MOtvDM6HoM+8m3P4daBp0nlNaYR8/vHCAmX6N3RyM8FWfp+VqWyux1SooQwxYxVFy86G78ApTqNsZ+p7cHmnBYqk0= +sol10b,192.168.0.50 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAs37kiDwKxWqi6EfSdKwRaZXBwh2doOARRqZzyitBaPwESy26DwTx+xdQ2rwB4V2k1WIec+1f3bgTS2ArH75dQSPyba2HKqxaSRBd3Zh4z23+uUxpupEyoRdW1HolMOvuoceheSMsruiuYcuiyct41d4c/Qmr51Dv04Doi00k6Ws= +piratehaven.org,64.81.59.88 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA7TYRRkle0wDNohZ0TNZN6R1Zp0svxgX+GJ9umI5yNM1bMxUTgeNRh5nIvZg1HgD1WRXQ57dSxxLzbvRyAqc245g6S8eWWCtenvOFLl0rOF5D3VxbQuw79sOe8/Ac8TC+c8RuWB7aaxpwL5Rv9xfDeazOtoKXj7+uwQW1PUmTaEM= +atalanta,192.168.0.10 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAysniuWiJH6OQLXl63XXcS1b/hP2lAgSz0IutjQ6ZUfBrt1BZ8udEgSh57w5QDLsZ1lNvND61u5cy6iDKXI5TIQY4DvUmsoFZhyr4iYJbtT/h6UJSyaZtEnA7ZMRjGhUIMOn+mjbj7Z3zmJMhxtImK3Xo3O2fJ1hnK4jsBwQPSLc= +pixie,192.168.0.9 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzDp588CvET6w11LB2s/vPjc4tX9+u46iYJgNFfhzxrXYMVv4GF7d30IXB5+Hwyi2FOQIG1+h0kUXVGWEv64rAFBT7pD2KMFX0lcDERV4avqT0TRDIIA5OqFOhq9Ff+kOmHS2cB7eFyR5vqbN4ujOnJGTmru9dcqyL+2AcFekvh0= +culain,192.168.0.3 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvJ/IORhQMdAsJ7LB1sI2LlWUHc7HPTCDiEgJ96ij3jFvqaIiYieRFaNkxbbk75mPkj3vIqWIgAsAtHmKX4wDikNG/gyjs4WM4cWFKtl2jiVhqpoxqqCaVxs6Ex+vpKuKhQR6SzFBFDlBZYP9an6DPu1msTLT8/hZH2WwswVmpyU= +cs312-server.een.orst.edu,128.193.40.66 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA+t3hsOiyp1mztt013bLdJqIAFCo8lxlz86MYEPz/mADHzWLs3Xv7xpAUv/E8pRbhEOzXo84EddORRBXz6DgVyMah8+v/u3IOkpXuZI0Iu1n5hZyf2l5DGEyGecr3oqqjUdMuM9HeXFLnqXJI3hDE7civBtqf5AJSol+TCcipeE8= +freebsd1,192.168.0.52 ssh-dss AAAAB3NzaC1kc3MAAACBAJSiOyQhYlKAi0FDLKy42VzLDq6yJWXGXVCLSfgWyVx7QCq/3+W3C1dtHuAvjbypcjqqvsuGGITgQ1Y6B/+76n5d7FyQnj4SFZ5drOBn/TvslXhrS/Ok5KCcndfNAa+EyMnSZJ21jhoRjZftY4lmb4hy6fEF3RvjuOdf1qBN5FWpAAAAFQDcsWF0zELAW6YUlSjAyO0T0lfPbwAAAIAlOLdOd/WszzVaplCOnH5vF6LWfr6BosZKDkFi0mv6Ec636YGaj4AMxK8sRPusHv6sVByN17ntIJnLo2XD1SuoH28bZ0ZnPIdVnd0l1KqsOCuuow9LZYJUihezoUuYuTvij1jZdrwltuPNJTVLYtsZDnKE5plw+Tjzeb7ImjbXGwAAAIBT40olg3fxhRDiZECle0WK7GitgXCB3njs+4dba8VwveEJb9UuulMc1eR+zQiJR96IUBagC9NiLvUGS1IfiIHpT4FA8O/MK1W9SgxXB9d39Nk/9l8dH3U/fLnbC/hYVo8bN0or/mKxcxQMkdBwpPlWAbELRftod2BkkkvgfQdc+g== +192.168.0.2 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwCZ+qxpMMRJ3otGsjaYeKTKf6tuCZyK1cD+ns9Eu7V0ZJLJ/LLMxduu7n4H/ufGI5rGV5axzgx8yZhjDRzsrGjLAQYsqlomMkf901YQI6UuieSA4MZa5MDkq/Jt6Vx1kEGTpkgrfw9kRMX5BngECt1QKY4xTgC7Ex+WlFvZwk+tRUT3 +openbsd1,192.168.0.54 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvgRVrtJk0fBg9YsLf7rWR1X32ZjFcva5XBvenDlHruObaHzuGXyyr6iOCAEOc7eCZjlPBYrGZ2potqyk8HlBOHXr1cCBf49t4yAt8KgKswtzWlgdbU1UEwllSRVOpzqULAT0smv/jfaIZdvRoN1rLriqtpn4bQL//ZOHiyXCwdlJ+di8Mza2L8KZ5T75hwIFBhrgL12xfymRp3v+Iy21MjjzsF3pROIkZ7icitNqQF55U9vsHaA37vG8FepVkO10bYYP7IHPZaBPBMPx7qPyRgRDJahEUGBnkIkzwJHEmA+7YMiNTZu6MigezD+CIqY1xOi/eXZwObLwLKXo7eRmpw== +192.168.0.60 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAufcvE7s1eRwhUwMBfZ6uFNxkdSdzjSDEn3vjByOjG/eraNhnYAW3rxV7WIf2pEa6JSOMrE1mqsEL75xEtpXlzC949Ysz4+1OSHY52KonoFm/a+FbmbFp81TVuVPYaLoeWN27STiJh+puC5spkIZe0laqT1GU13M4gj6B+j3NLhU= +rh3a,192.168.0.55 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAufcvE7s1eRwhUwMBfZ6uFNxkdSdzjSDEn3vjByOjG/eraNhnYAW3rxV7WIf2pEa6JSOMrE1mqsEL75xEtpXlzC949Ysz4+1OSHY52KonoFm/a+FbmbFp81TVuVPYaLoeWN27STiJh+puC5spkIZe0laqT1GU13M4gj6B+j3NLhU= +tsetse,192.168.0.7 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwCDGn82BEMSCfcE2LZKcwdAoyIBC+u2twVwWNRm3KzyrJMQ+RbTQo4AwGOdyr/QYh6KaxTKTSoDtiBLr132uenMQKwF47gCKMA1T47uiy+TBUehgOGwOxteSYP/pQRpKXFmhOppSPyDPQVq234XvANeJp0iT8ZKEhF2FsWTs6sM= +config.sage.org,131.106.3.205 ssh-dss AAAAB3NzaC1kc3MAAACBAL2akEcIfQsfm3zCd2hD6PgH3kWA/tqX/qbrLhL/ipX7iqK/y282GMClZQSQjc1YNi9virvLzb6u/gdZxicZ8K5O3FaJrULQJOZaP62SOHk5CUSHVnvpMCaCnbwB6gEHa2LeMWStcEfWW+g1CC2hzPJw16/S5GISGXbyanO02MnXAAAAFQDomwx/OCjTmmQljMTU5rgNn2E4gwAAAIBmtMSfcs2Tq5iFFKK5cahluv047vVNfXqYIAkeJniceL0Et16MKfuzadpq0H9ocxQYW/5Ir9nUULrdxBUN9LxNKq15/uWkJC9QCSh8PysgvFnjVZeCODua/dn6eZTZnY9DZ3S6v1pT8CP6uWr5fmZJ8FKJGrC3gYX4y1V1ZTCVewAAAIB6e7RCST6vkTS5rgn5wGbrfLK5ad+PW+2i66k77Zv1pjtfRz+0oejBjwJDPNVSc2YNEl7X0nEEMNjo/a5x8Ls+nVqhzJA+NXIwS1e/moKbXFGewW5HAtxd79gtInC8dEIO7hmnWnqF1dBkRHXg1YffYkHrMVJBxpzagw7nYa0BBQ== +rh3b,192.168.0.56 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAufcvE7s1eRwhUwMBfZ6uFNxkdSdzjSDEn3vjByOjG/eraNhnYAW3rxV7WIf2pEa6JSOMrE1mqsEL75xEtpXlzC949Ysz4+1OSHY52KonoFm/a+FbmbFp81TVuVPYaLoeWN27STiJh+puC5spkIZe0laqT1GU13M4gj6B+j3NLhU= +centos1,192.168.0.57 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA0DXqYF+3Lf68GkWBAjjKBb6UITNnzm4wiDi/AGjv5+DoVXqDcqHvZ8rZFAMgUe1dVob4pWT2ZWLHW0gicoJCdr4UQbPXlWz1F62z8fo2PRRPlG6KN1wmF7pnyml8jr0wBX8lQZJsMqi4InGozf7wFHLH/7DNGRK3MD6tSp3Z4is= +doorstop.cafes.net,205.241.238.186 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApJKeB9/bN5t55zLETHs0MVo/vEkfQ3EzY7178GKLI/yiOFmcn+NvUvUtCQK/xKpod813LBHCODxZPG1Kb0SjlaC/EkFEenb74LNu0o1qXa1GWh3wfaIm0JRNjXqPqxAWTlMs43O2HXwOwmLVhl7SSP3xtTw6h9gREbVKmfBaRdsRfzD0etfz1NCnmGh/1Sh9+j4eeS+IBtwoR5JVhZVhuofHCqs5HZ8gLDgfn8HXP7pMbLkx54cf1R/tmFmn9JGLdTPtEGcSIiu7414XSbfChSC83rGZCDPKHq7ZodiE8GpbWLBnyPXi2AYxTPM7aZMqitIHv3MWf5suV0q0WLGdnQ== +host.domain.com,host1.domain.com,192.168.0.1 dss thisismykey1 diff --git a/spec/integration/provider/sshkey_spec.rb b/spec/integration/provider/sshkey_spec.rb new file mode 100644 index 000000000..f461460ef --- /dev/null +++ b/spec/integration/provider/sshkey_spec.rb @@ -0,0 +1,159 @@ +#!/usr/bin/env ruby + +require 'spec_helper' +require 'puppet/file_bucket/dipper' +require 'puppet_spec/files' +require 'puppet_spec/compiler' + +describe Puppet::Type.type(:sshkey).provider(:parsed), '(integration)', + :unless => Puppet.features.microsoft_windows? do + include PuppetSpec::Files + include PuppetSpec::Compiler + + before :each do + # Don't backup to filebucket + Puppet::FileBucket::Dipper.any_instance.stubs(:backup) + # We don't want to execute anything + described_class.stubs(:filetype). + returns Puppet::Util::FileType::FileTypeFlat + + @sshkey_file = tmpfile('sshkey_integration_specs') + FileUtils.cp(my_fixture('sample'), @sshkey_file) + end + + after :each do + # sshkey provider class + described_class.clear + end + + let(:type_under_test) { 'sshkey' } + + describe "when managing a ssh known hosts file it..." do + + let(:super_unique) { "my.super.unique.host" } + it "should create a new known_hosts file with mode 0644" do + target = tmpfile('ssh_known_hosts') + manifest = "#{type_under_test} { '#{super_unique}': + ensure => 'present', + type => 'rsa', + key => 'TESTKEY', + target => '#{target}' }" + apply_with_error_check(manifest) + expect_file_mode(target, "644") + end + + it "should create an SSH host key entry (ensure present)" do + manifest = "#{type_under_test} { '#{super_unique}': + ensure => 'present', + type => 'rsa', + key => 'mykey', + target => '#{@sshkey_file}' }" + apply_with_error_check(manifest) + expect(File.read(@sshkey_file)).to match(/#{super_unique}.*mykey/) + end + + let(:sshkey_name) { 'kirby.madstop.com' } + it "should delete an entry for an SSH host key" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'absent', + target => '#{@sshkey_file}' }" + apply_with_error_check(manifest) + expect(File.read(@sshkey_file)).not_to match(/#{sshkey_name}.*Yqk0=/) + end + + it "should update an entry for an SSH host key" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'present', + type => 'rsa', + key => 'mynewshinykey', + target => '#{@sshkey_file}' }" + apply_with_error_check(manifest) + expect(File.read(@sshkey_file)).to match(/#{sshkey_name}.*mynewshinykey/) + expect(File.read(@sshkey_file)).not_to match(/#{sshkey_name}.*Yqk0=/) + end + + # test all key types + types = ["ssh-dss", "dsa", + "ssh-ed25519", "ed25519", + "ssh-rsa", "rsa", + "ecdsa-sha2-nistp256", + "ecdsa-sha2-nistp384", + "ecdsa-sha2-nistp521"] + # these types are treated as aliases for sshkey type + # so they are populated as the *values* below + aliases = {"dsa" => "ssh-dss", + "ed25519" => "ssh-ed25519", + "rsa" => "ssh-rsa"} + types.each do |type| + it "should update an entry with #{type} type" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'present', + type => '#{type}', + key => 'mynewshinykey', + target => '#{@sshkey_file}' }" + + apply_with_error_check(manifest) + if aliases.has_key?(type) + full_type = aliases[type] + expect(File.read(@sshkey_file)). + to match(/#{sshkey_name}.*#{full_type}.*mynew/) + else + expect(File.read(@sshkey_file)). + to match(/#{sshkey_name}.*#{type}.*mynew/) + end + end + end + + # test unknown key type fails + let(:invalid_type) { 'ssh-er0ck' } + it "should raise an error with an unknown type" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'present', + type => '#{invalid_type}', + key => 'mynewshinykey', + target => '#{@sshkey_file}' }" + expect { + apply_compiled_manifest(manifest) + }.to raise_error(Puppet::ResourceError, /Invalid value "#{invalid_type}"/) + end + + #single host_alias + let(:host_alias) { 'r0ckdata.com' } + it "should update an entry with new host_alias" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'present', + host_aliases => '#{host_alias}', + target => '#{@sshkey_file}' }" + apply_with_error_check(manifest) + expect(File.read(@sshkey_file)).to match(/#{sshkey_name},#{host_alias}\s/) + expect(File.read(@sshkey_file)).not_to match(/#{sshkey_name}\s/) + end + + #array host_alias + let(:host_aliases) { "r0ckdata.com,erict.net" } + it "should update an entry with new host_alias" do + manifest = "#{type_under_test} { '#{sshkey_name}': + ensure => 'present', + host_aliases => '#{host_alias}', + target => '#{@sshkey_file}' }" + apply_with_error_check(manifest) + expect(File.read(@sshkey_file)).to match(/#{sshkey_name},#{host_alias}\s/) + expect(File.read(@sshkey_file)).not_to match(/#{sshkey_name}\s/) + end + + #puppet resource sshkey + it "should fetch an entry from resources" do + @resource_app = Puppet::Application[:resource] + @resource_app.preinit + @resource_app.command_line.stubs(:args). + returns([type_under_test, sshkey_name, "target=#{@sshkey_file}"]) + + @resource_app.expects(:puts).with do |args| + expect(args).to match(/#{sshkey_name}/) + end + @resource_app.main + end + + end + +end diff --git a/spec/integration/type/sshkey_spec.rb b/spec/integration/type/sshkey_spec.rb deleted file mode 100644 index d1b1e01c7..000000000 --- a/spec/integration/type/sshkey_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env ruby -require 'spec_helper' -require 'puppet_spec/files' -require 'puppet_spec/compiler' - -describe Puppet::Type.type(:sshkey), '(integration)', :unless => Puppet.features.microsoft_windows? do - include PuppetSpec::Files - include PuppetSpec::Compiler - - let(:target) { tmpfile('ssh_known_hosts') } - let(:manifest) { "sshkey { 'test': - ensure => 'present', - type => 'rsa', - key => 'TESTKEY', - target => '#{target}' }" - } - - it "should create a new known_hosts file with mode 0644" do - apply_compiled_manifest(manifest) - expect_file_mode(target, "644") - end -end diff --git a/spec/lib/puppet_spec/files.rb b/spec/lib/puppet_spec/files.rb index 2d0d95275..2b209bc6a 100755 --- a/spec/lib/puppet_spec/files.rb +++ b/spec/lib/puppet_spec/files.rb @@ -1,89 +1,89 @@ require 'fileutils' require 'tempfile' require 'tmpdir' require 'pathname' # A support module for testing files. module PuppetSpec::Files def self.cleanup $global_tempfiles ||= [] while path = $global_tempfiles.pop do begin Dir.unstub(:entries) FileUtils.rm_rf path, :secure => true rescue Errno::ENOENT # nothing to do end end end def make_absolute(path) PuppetSpec::Files.make_absolute(path) end def self.make_absolute(path) path = File.expand_path(path) path[0] = 'c' if Puppet.features.microsoft_windows? path end def tmpfile(name, dir = nil) PuppetSpec::Files.tmpfile(name, dir) end def self.tmpfile(name, dir = nil) # Generate a temporary file, just for the name... source = dir ? Tempfile.new(name, dir) : Tempfile.new(name) path = source.path source.close! record_tmp(File.expand_path(path)) path end def file_containing(name, contents) PuppetSpec::Files.file_containing(name, contents) end def self.file_containing(name, contents) file = tmpfile(name) File.open(file, 'wb') { |f| f.write(contents) } file end def tmpdir(name) PuppetSpec::Files.tmpdir(name) end def self.tmpdir(name) dir = Dir.mktmpdir(name) record_tmp(dir) dir end def dir_containing(name, contents_hash) PuppetSpec::Files.dir_containing(name, contents_hash) end def self.dir_containing(name, contents_hash) dir_contained_in(tmpdir(name), contents_hash) end def dir_contained_in(dir, contents_hash) PuppetSpec::Files.dir_contained_in(dir, contents_hash) end def self.dir_contained_in(dir, contents_hash) contents_hash.each do |k,v| if v.is_a?(Hash) Dir.mkdir(tmp = File.join(dir,k)) dir_contained_in(tmp, v) else file = File.join(dir, k) File.open(file, 'wb') {|f| f.write(v) } end end dir end def self.record_tmp(tmp) # ...record it for cleanup, $global_tempfiles ||= [] $global_tempfiles << tmp end def expect_file_mode(file, mode) actual_mode = "%o" % Puppet::FileSystem.stat(file).mode target_mode = if Puppet.features.microsoft_windows? mode else "10" + "%04i" % mode.to_i end - actual_mode.should == target_mode + expect(actual_mode).to eq(target_mode) end end