diff options
-rwxr-xr-x | lib/puppet/provider/parsedfile.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/provider/sshkey/parsed.rb | 56 | ||||
-rwxr-xr-x | lib/puppet/type/parsedtype.rb | 6 | ||||
-rwxr-xr-x | lib/puppet/type/parsedtype/host.rb | 156 | ||||
-rwxr-xr-x | lib/puppet/type/sshkey.rb (renamed from lib/puppet/type/parsedtype/sshkey.rb) | 67 | ||||
-rw-r--r-- | test/providers/parsedhost.rb | 1 | ||||
-rwxr-xr-x | test/providers/parsedsshkey.rb | 57 | ||||
-rwxr-xr-x | test/types/sshkey.rb | 81 |
8 files changed, 152 insertions, 276 deletions
diff --git a/lib/puppet/provider/parsedfile.rb b/lib/puppet/provider/parsedfile.rb index 2527edfeb..53c49ef5e 100755 --- a/lib/puppet/provider/parsedfile.rb +++ b/lib/puppet/provider/parsedfile.rb @@ -120,7 +120,6 @@ class Puppet::Provider::ParsedFile < Puppet::Provider o.is_a? Hash and o[:name] == @model[:name] end @me = h - return h else @me = {} if @instances.empty? @@ -128,8 +127,9 @@ class Puppet::Provider::ParsedFile < Puppet::Provider else @instances << @me end - return @me end + + return @me end def initialize(model) diff --git a/lib/puppet/provider/sshkey/parsed.rb b/lib/puppet/provider/sshkey/parsed.rb new file mode 100755 index 000000000..e1dbeaad6 --- /dev/null +++ b/lib/puppet/provider/sshkey/parsed.rb @@ -0,0 +1,56 @@ +require 'puppet/provider/parsedfile' + +Puppet::Type.type(:sshkey).provide :parsed, :parent => Puppet::Provider::ParsedFile do + @filetype = Puppet::FileType.filetype(:flat) + @path = "/etc/ssh/ssh_known_hosts" + @fields = [:name, :type, :key] + + # Parse an sshknownhosts file + # + # This method also stores existing comments, and it stores all host + # jobs in order, mostly so that comments are retained in the order + # they were written and in proximity to the same jobs. + def self.parse(text) + count = 0 + instances = [] + text.chomp.split("\n").each { |line| + hash = {} + case line + when /^#/, /^\s*$/: + # add comments and blank lines to the list as they are + instances << line + else + hash = {} + fields().zip(line.split(" ")).each { |param, value| + hash[param] = value + } + + if hash[:name] =~ /,/ + names = hash[:name].split(",") + hash[:name] = names.shift + hash[:alias] = names + end + + if hash[:alias] == "" + hash.delete(:alias) + end + + instances << hash + count += 1 + end + } + + return instances + end + + # Convert the current object into an entry for a known-hosts file. + def self.to_record(hash) + name = hash[:name] + if hash.include?(:alias) + name += "," + hash[:alias].join(",") + end + [name, hash[:type], hash[:key]].join(" ") + end +end + +# $Id$ diff --git a/lib/puppet/type/parsedtype.rb b/lib/puppet/type/parsedtype.rb index 1b958db4d..58ea44d62 100755 --- a/lib/puppet/type/parsedtype.rb +++ b/lib/puppet/type/parsedtype.rb @@ -59,7 +59,7 @@ module Puppet # first, so I don't need to worry about that. def sync(value) # Just copy the value to our 'is' state; it'll get flushed later - self.is = value + #self.is = value return nil end @@ -152,7 +152,7 @@ module Puppet end def exists? - h = provider.hash + h = self.retrieve if h[:ensure] == :absent return false @@ -187,6 +187,6 @@ end #require 'puppet/type/parsedtype/host' require 'puppet/type/parsedtype/port' require 'puppet/type/parsedtype/mount' -require 'puppet/type/parsedtype/sshkey' +#require 'puppet/type/parsedtype/sshkey' # $Id$ diff --git a/lib/puppet/type/parsedtype/host.rb b/lib/puppet/type/parsedtype/host.rb deleted file mode 100755 index df8ed3df7..000000000 --- a/lib/puppet/type/parsedtype/host.rb +++ /dev/null @@ -1,156 +0,0 @@ -require 'etc' -require 'facter' -require 'puppet/type/parsedtype' -require 'puppet/type/state' - -module Puppet - newtype(:host, Puppet::Type::ParsedType) do - newstate(:ip) do - desc "The host's IP address." - end - - newstate(:alias) do - desc "Any alias the host might have. Multiple values must be - specified as an array. Note that this state has the same name - as one of the metaparams; using this state to set aliases will - make those aliases available in your Puppet scripts and also on - disk." - - # Make sure our "is" value is always an array. - def is - current = super - unless current.is_a? Array - current = [current] - end - current - end - - def is_to_s - self.is.join(" ") - end - - # We have to override the feeding mechanism; it might be nil or - # white-space separated - def is=(value) - # If it's just whitespace, ignore it - case value - when /^\s+$/ - @is = nil - when String - @is = value.split(/\s+/) - else - @is = value - end - end - - # We actually want to return the whole array here, not just the first - # value. - def should - if defined? @should - if @should == [:absent] - return :absent - else - return @should - end - else - return nil - end - end - - def should_to_s - @should.join(" ") - end - - validate do |value| - if value =~ /\s/ - raise Puppet::Error, "Aliases cannot include whitespace" - end - end - - munge do |value| - if value == :absent or value == "absent" - :absent - else - # Add the :alias metaparam in addition to the state - @parent.newmetaparam(@parent.class.metaparamclass(:alias), value) - value - end - end - end - - newparam(:name) do - desc "The host name." - - isnamevar - end - - @doc = "Installs and manages host entries. For most systems, these - entries will just be in /etc/hosts, but some systems (notably OS X) - will have different solutions." - - @instances = [] - - @path = "/etc/hosts" - @fields = [:ip, :name, :alias] - - @filetype = Puppet::FileType.filetype(:flat) - - # Parse a host file - # - # This method also stores existing comments, and it stores all host - # jobs in order, mostly so that comments are retained in the order - # they were written and in proximity to the same jobs. - def self.parse(text) - count = 0 - hash = {} - text.chomp.split("\n").each { |line| - case line - when /^#/, /^\s*$/: - # add comments and blank lines to the list as they are - @instances << line - else - if line.sub!(/^(\S+)\s+(\S+)\s*/, '') - hash[:ip] = $1 - hash[:name] = $2 - - unless line == "" - line.sub!(/\s*/, '') - line.sub!(/^([^#]+)\s*/) do |value| - aliases = $1 - unless aliases =~ /^\s*$/ - hash[:alias] = aliases - end - - "" - end - end - else - raise Puppet::Error, "Could not match '%s'" % line - end - - if hash[:alias] == "" - hash.delete(:alias) - end - - hash2obj(hash) - - hash.clear - count += 1 - end - } - end - - # Convert the current object into a host-style string. - def to_record - str = "%s\t%s" % [self.state(:ip).value, self[:name]] - - if value = self.value(:alias) - str += "\t%s" % value.join("\t") - end - - str - end - end -end - -# $Id$ diff --git a/lib/puppet/type/parsedtype/sshkey.rb b/lib/puppet/type/sshkey.rb index 26c9b4f30..e769199bf 100755 --- a/lib/puppet/type/parsedtype/sshkey.rb +++ b/lib/puppet/type/sshkey.rb @@ -1,10 +1,9 @@ -require 'etc' -require 'facter' -require 'puppet/type/parsedtype' -require 'puppet/type/state' - module Puppet newtype(:sshkey, Puppet::Type::ParsedType) do + @doc = "Installs and manages ssh host keys. At this point, this type + only knows how to install keys into /etc/ssh/ssh_known_hosts, and + it cannot manage user authorized keys yet." + newstate(:type) do desc "The encryption type used. Probably ssh-dss or ssh-rsa." end @@ -53,64 +52,6 @@ module Puppet isnamevar end - - @doc = "Installs and manages ssh host keys. At this point, this type - only knows how to install keys into /etc/ssh/ssh_known_hosts, and - it cannot manage user authorized keys yet." - - @instances = [] - - # FIXME This should be configurable. - @path = "/etc/ssh/ssh_known_hosts" - @fields = [:name, :type, :key] - - @filetype = Puppet::FileType.filetype(:flat) - - # Parse an sshknownhosts file - # - # This method also stores existing comments, and it stores all host - # jobs in order, mostly so that comments are retained in the order - # they were written and in proximity to the same jobs. - def self.parse(text) - count = 0 - hash = {} - text.chomp.split("\n").each { |line| - case line - when /^#/, /^\s*$/: - # add comments and blank lines to the list as they are - @instances << line - else - hash = {} - fields().zip(line.split(" ")).each { |param, value| - hash[param] = value - } - - if hash[:name] =~ /,/ - names = hash[:name].split(",") - hash[:name] = names.shift - hash[:alias] = names - end - - if hash[:alias] == "" - hash.delete(:alias) - end - - hash2obj(hash) - - hash.clear - count += 1 - end - } - end - - # Convert the current object into a host-style string. - def to_record - name = self[:name] - if @states.include?(:alias) - name += "," + @states[:alias].value.join(",") - end - [name, @states[:type].value, @states[:key].value].join(" ") - end end end diff --git a/test/providers/parsedhost.rb b/test/providers/parsedhost.rb index da286d779..1d982c813 100644 --- a/test/providers/parsedhost.rb +++ b/test/providers/parsedhost.rb @@ -196,7 +196,6 @@ class TestParsedHostProvider < Test::Unit::TestCase def test_hostsparse fakedata("data/types/hosts").each { |file| @provider.path = file - Puppet.info "Parsing %s" % file instances = nil assert_nothing_raised { instances = @provider.retrieve diff --git a/test/providers/parsedsshkey.rb b/test/providers/parsedsshkey.rb new file mode 100755 index 000000000..f0295c47a --- /dev/null +++ b/test/providers/parsedsshkey.rb @@ -0,0 +1,57 @@ +# Test key job creation, modification, and destruction + +if __FILE__ == $0 + $:.unshift '..' + $:.unshift '../../lib' + $puppetbase = "../.." +end + +require 'puppettest' +require 'puppet' +require 'puppet/type/parsedtype/sshkey' +require 'test/unit' +require 'facter' + +class TestParsedSSHKey < Test::Unit::TestCase + include TestPuppet + + def setup + super + @provider = Puppet.type(:sshkey).provider(:parsed) + + @oldfiletype = @provider.filetype + end + + def teardown + Puppet::FileType.filetype(:ram).clear + @provider.filetype = @oldfiletype + super + end + + def test_keysparse + fakedata("data/types/sshkey").each { |file| + @provider.path = file + instances = nil + assert_nothing_raised { + instances = @provider.retrieve + } + + text = @provider.fileobj.read + + dest = tempfile() + @provider.path = dest + + # Now write it back out + assert_nothing_raised { + @provider.store(instances) + } + + newtext = @provider.fileobj.read + + # Don't worry about difference in whitespace + assert_equal(text.gsub(/\s+/, ' '), newtext.gsub(/\s+/, ' ')) + } + end +end + +# $Id$ diff --git a/test/types/sshkey.rb b/test/types/sshkey.rb index 1fc4b1f82..cf8313654 100755 --- a/test/types/sshkey.rb +++ b/test/types/sshkey.rb @@ -17,21 +17,22 @@ class TestSSHKey < Test::Unit::TestCase def setup super # god i'm lazy - @sshtype = Puppet.type(:sshkey) - @oldfiletype = @sshtype.filetype - end + @sshkeytype = Puppet.type(:sshkey) - def teardown - Puppet::FileType.filetype(:ram).clear - @sshtype.filetype = @oldfiletype - Puppet.type(:file).clear - super - end + @provider = @sshkeytype.defaultprovider + + # Make sure they aren't using something funky like netinfo + unless @provider.name == :parsed + @sshkeytype.defaultprovider = @sshkeytype.provider(:parsed) + end + + cleanup do @sshkeytype.defaultprovider = nil end - # Here we just create a fake key type that answers to all of the methods - # but does not modify our actual system. - def mkfaketype - @sshtype.filetype = Puppet::FileType.filetype(:ram) + oldpath = @provider.path + cleanup do + @provider.path = oldpath + end + @provider.path = tempfile() end def mkkey @@ -44,7 +45,7 @@ class TestSSHKey < Test::Unit::TestCase end assert_nothing_raised { - key = @sshtype.create( + key = @sshkeytype.create( :name => "host%s.madstop.com" % @kcount, :key => "%sAAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=" % @kcount, :type => "ssh-dss", @@ -56,41 +57,25 @@ class TestSSHKey < Test::Unit::TestCase end def test_simplekey - mkfaketype assert_nothing_raised { - assert_nil(Puppet.type(:sshkey).retrieve) + Puppet.type(:sshkey).defaultprovider.retrieve + + count = 0 + @sshkeytype.each do |h| + count += 1 + end + + assert_equal(0, count, "Found sshkeys in empty file somehow") } key = mkkey assert_apply(key) - assert_nothing_raised { - Puppet.type(:sshkey).store - } - - assert_nothing_raised { - assert( - Puppet.type(:sshkey).to_file.include?( - Puppet.type(:sshkey).fileobj.read - ), - "File does not include all of our objects" - ) - } - end - - def test_keysparse - fakedata("data/types/sshkey").each { |file| - @sshtype.path = file - assert_nothing_raised { - @sshtype.retrieve - } - @sshtype.clear - } + assert(key.exists?, "Key did not get created") end def test_moddingkey - mkfaketype key = mkkey() assert_events([:sshkey_created], key) @@ -99,12 +84,11 @@ class TestSSHKey < Test::Unit::TestCase key[:alias] = %w{madstop kirby yayness} - Puppet.err :mark assert_events([:sshkey_changed], key) end def test_aliasisstate - assert_equal(:state, @sshtype.attrtype(:alias)) + assert_equal(:state, @sshkeytype.attrtype(:alias)) end def test_multivalues @@ -126,28 +110,23 @@ class TestSSHKey < Test::Unit::TestCase end def test_removal - mkfaketype sshkey = mkkey() assert_nothing_raised { sshkey[:ensure] = :present } assert_events([:sshkey_created], sshkey) - sshkey.retrieve - assert(sshkey.insync?) + assert(sshkey.exists?, "key was not created") assert_nothing_raised { sshkey[:ensure] = :absent } assert_events([:sshkey_deleted], sshkey) - sshkey.retrieve + assert(! sshkey.exists?, "Key was not deleted") assert_events([], sshkey) end def test_modifyingfile - keyfile = tempfile() - Puppet.type(:sshkey).path = keyfile - keys = [] names = [] 3.times { @@ -164,7 +143,7 @@ class TestSSHKey < Test::Unit::TestCase #newkey[:ensure] = :present names << newkey.name assert_apply(newkey) - Puppet.type(:sshkey).clear + # Verify we can retrieve that info assert_nothing_raised("Could not retrieve after second write") { newkey.retrieve @@ -172,9 +151,9 @@ class TestSSHKey < Test::Unit::TestCase # And verify that we have data for everything names.each { |name| - key = Puppet.type(:sshkey)[name] + key = Puppet.type(:sshkey)[name] || Puppet.type(:sshkey).create(:name => name) assert(key) - assert(key[:type]) + assert(key.exists?, "key %s is missing" % name) } end end |