summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-01-14 04:01:46 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-01-14 04:01:46 +0000
commit83906a2b210efd002901897b0ea729ff435ffe51 (patch)
tree64675d023777fc74fc6a7abdc486c75cd3944b93
parentc67fb7b81d2fd69326b1518e0669164dcbf5773c (diff)
downloadpuppet-83906a2b210efd002901897b0ea729ff435ffe51.tar.gz
puppet-83906a2b210efd002901897b0ea729ff435ffe51.tar.xz
puppet-83906a2b210efd002901897b0ea729ff435ffe51.zip
Adding sshkey class plus tests, and adding "aggregatable" methods to type.rb
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@829 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r--lib/puppet/type.rb15
-rwxr-xr-xlib/puppet/type/parsedtype/sshkey.rb129
-rwxr-xr-xtest/types/sshkey.rb121
3 files changed, 265 insertions, 0 deletions
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index 74c163338..75d55c9fe 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -91,6 +91,21 @@ class Type < Puppet::Element
def inspect
"Type(%s)" % self.name
end
+
+ # This class is aggregatable, meaning that instances are defined on
+ # one system but instantiated on another
+ def isaggregatable
+ @aggregatable = true
+ end
+
+ # Is this one aggregatable?
+ def aggregatable?
+ if defined? @aggregatable
+ return @aggregatable
+ else
+ return false
+ end
+ end
end
def inspect
diff --git a/lib/puppet/type/parsedtype/sshkey.rb b/lib/puppet/type/parsedtype/sshkey.rb
new file mode 100755
index 000000000..ff508d8c6
--- /dev/null
+++ b/lib/puppet/type/parsedtype/sshkey.rb
@@ -0,0 +1,129 @@
+require 'etc'
+require 'facter'
+require 'puppet/type/parsedtype'
+require 'puppet/type/state'
+
+module Puppet
+ newtype(:sshkey, Puppet::Type::ParsedType) do
+ isaggregatable
+
+ newstate(:type) do
+ desc "The encryption type used. Probably ssh-dss or ssh-rsa."
+ end
+
+ newstate(:key) do
+ desc "The key itself; generally a long string of hex digits."
+ end
+
+ # FIXME This should automagically check for aliases to the hosts, just
+ # to see if we can automatically glean any aliases.
+ 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."
+
+ # We actually want to return the whole array here, not just the first
+ # value.
+ def should
+ @should
+ end
+
+ validate do |value|
+ if value =~ /\s/
+ raise Puppet::Error, "Aliases cannot include whitespace"
+ end
+ if value =~ /,/
+ raise Puppet::Error, "Aliases cannot include whitespace"
+ end
+ end
+
+ # Make a puppet alias in addition.
+ munge do |value|
+ # Add the :alias metaparam in addition to the state
+ @parent.newmetaparam(@parent.class.metaparamclass(:alias), value)
+ value
+ 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/ssh/ssh_known_hosts"
+ @fields = [:name, :type, :key]
+
+ @filetype = Puppet::FileType.filetype(:flat)
+# case Facter["operatingsystem"].value
+# when "Solaris":
+# @filetype = Puppet::FileType::SunOS
+# else
+# @filetype = Puppet::CronType::Default
+# end
+
+ # 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
+ 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 match = /^(\S+)\s+(\S+)\s*(\S*)$/.match(line)
+ # fields().zip(match.captures).each { |param, value|
+ # hash[param] = value
+ # }
+ #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_s
+ name = self[:name]
+ if @states.include?(:alias)
+ name += "," + @states[:alias].should.join(",")
+ end
+ [name, @states[:type].should, @states[:key].should].join(" ")
+ end
+ end
+end
+
+# $Id$
diff --git a/test/types/sshkey.rb b/test/types/sshkey.rb
new file mode 100755
index 000000000..efde8a0ee
--- /dev/null
+++ b/test/types/sshkey.rb
@@ -0,0 +1,121 @@
+# 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 TestSSHKey < Test::Unit::TestCase
+ include TestPuppet
+ def setup
+ super
+ # god i'm lazy
+ @sshtype = Puppet.type(:sshkey)
+ @oldfiletype = @sshtype.filetype
+ end
+
+ def teardown
+ @sshtype.filetype = @oldfiletype
+ Puppet.type(:file).clear
+ super
+ 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)
+ end
+
+ def mkkey
+ key = nil
+ assert_nothing_raised {
+ key = @sshtype.create(
+ :name => "culain.madstop.com",
+ :key => "AAAAB3NzaC1kc3MAAACBAMnhSiku76y3EGkNCDsUlvpO8tRgS9wL4Eh54WZfQ2lkxqfd2uT/RTT9igJYDtm/+UHuBRdNGpJYW1Nw2i2JUQgQEEuitx4QKALJrBotejGOAWxxVk6xsh9xA0OW8Q3ZfuX2DDitfeC8ZTCl4xodUMD8feLtP+zEf8hxaNamLlt/AAAAFQDYJyf3vMCWRLjTWnlxLtOyj/bFpwAAAIEAmRxxXb4jjbbui9GYlZAHK00689DZuX0EabHNTl2yGO5KKxGC6Esm7AtjBd+onfu4Rduxut3jdI8GyQCIW8WypwpJofCIyDbTUY4ql0AQUr3JpyVytpnMijlEyr41FfIb4tnDqnRWEsh2H7N7peW+8DWZHDFnYopYZJ9Yu4/jHRYAAACAERG50e6aRRb43biDr7Ab9NUCgM9bC0SQscI/xdlFjac0B/kSWJYTGVARWBDWug705hTnlitY9cLC5Ey/t/OYOjylTavTEfd/bh/8FkAYO+pWdW3hx6p97TBffK0b6nrc6OORT2uKySbbKOn0681nNQh4a6ueR3JRppNkRPnTk5c=",
+ :type => "ssh-dss",
+ :alias => ["192.168.0.3"]
+ )
+ }
+
+ return key
+ end
+
+ def test_simplekey
+ mkfaketype
+ assert_nothing_raised {
+ assert_nil(Puppet.type(:sshkey).retrieve)
+ }
+
+ 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
+ }
+ end
+
+ def test_moddingkey
+ mkfaketype
+ key = mkkey()
+
+ assert_events([:sshkey_created], key)
+
+ key.retrieve
+
+ key[:alias] = %w{madstop kirby yayness}
+
+ Puppet.err :mark
+ assert_events([:sshkey_changed], key)
+ end
+
+ def test_aliasisstate
+ assert_equal(:state, @sshtype.attrtype(:alias))
+ end
+
+ def test_multivalues
+ key = mkkey
+ assert_raise(Puppet::Error) {
+ key[:alias] = "puppetmasterd yayness"
+ }
+ end
+
+ def test_puppetalias
+ key = mkkey()
+
+ assert_nothing_raised {
+ key[:alias] = "testing"
+ }
+
+ same = key.class["testing"]
+ assert(same, "Could not retrieve by alias")
+ end
+end
+
+# $Id$