diff options
author | Francois Deppierraz <francois.deppierraz@camptocamp.com> | 2008-04-10 19:24:06 +0200 |
---|---|---|
committer | Francois Deppierraz <francois@ctrlaltdel.ch> | 2008-05-07 22:04:07 +0200 |
commit | db8a46c605b8b4a205e65aa35a1442f2de32431b (patch) | |
tree | b3266d73a0fa7af433e096f667ec8a172c8ffb22 | |
parent | 2b185af97882afb4a7feab42de97771ceed80b43 (diff) | |
download | puppet-db8a46c605b8b4a205e65aa35a1442f2de32431b.tar.gz puppet-db8a46c605b8b4a205e65aa35a1442f2de32431b.tar.xz puppet-db8a46c605b8b4a205e65aa35a1442f2de32431b.zip |
New native ssh_authorized_key type
-rw-r--r-- | lib/puppet/provider/ssh_authorized_key/parsed.rb | 50 | ||||
-rw-r--r-- | lib/puppet/type/ssh_authorized_key.rb | 47 | ||||
-rw-r--r-- | spec/unit/ral/provider/ssh_authorized_key/parsed.rb | 74 | ||||
-rw-r--r-- | spec/unit/ral/type/ssh_authorized_key.rb | 80 | ||||
-rw-r--r-- | test/data/providers/ssh_authorized_key/parsed/authorized_keys | 5 | ||||
-rw-r--r-- | test/data/types/ssh_authorized_key/1 | 2 |
6 files changed, 258 insertions, 0 deletions
diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb new file mode 100644 index 000000000..228bbc6fc --- /dev/null +++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb @@ -0,0 +1,50 @@ +require 'puppet/provider/parsedfile' + +Puppet::Type.type(:ssh_authorized_key).provide(:parsed, + :parent => Puppet::Provider::ParsedFile, + :filetype => :flat, + # Ugly but the parameter is required + :default_target => '/proc/NONEXISTANT' +) do + desc "Parse and generate authorized_keys files for SSH." + + text_line :comment, :match => /^#/ + text_line :blank, :match => /^\s+/ + + record_line :parsed, + :fields => %w{options type key name}, + :optional => %w{options}, + :rts => /^\s+/, + :match => /^(?:([^ ]+) )?(ssh-dss|ssh-rsa) ([^ ]+)(?: (.+))?$/, + :post_parse => proc { |record| + if record[:options].nil? + record[:options] = [:absent] + else + record[:options] = record[:options].split(',') + end + }, + :pre_gen => proc { |record| + if record[:options].include?(:absent) + record[:options] = "" + else + record[:options] = record[:options].join(',') + end + } + + def prefetch + if not @resource.should(:target) + # + # Set default target when user is given + if val = @resource.should(:user) + target = File.expand_path("~%s/.ssh/authorized_keys" % val) + Puppet::debug("Setting target to %s" % target) + @resource[:target] = target + else + raise Puppet::Error, "Missing attribute 'user' or 'target'" + end + end + + super + end +end + diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb new file mode 100644 index 000000000..97521ccab --- /dev/null +++ b/lib/puppet/type/ssh_authorized_key.rb @@ -0,0 +1,47 @@ +module Puppet + newtype(:ssh_authorized_key) do + @doc = "Manages ssh authorized keys." + + ensurable + + newparam(:name) do + desc "The ssh key comment." + + isnamevar + end + + newproperty(:type) do + desc "The encryption type used. Probably ssh-dss or ssh-rsa for + ssh version 2. Not used for ssh version 1." + + newvalue("ssh-dss") + newvalue("ssh-rsa") + newvalue("none") + + aliasvalue(:dsa, "ssh-dss") + aliasvalue(:rsa, "ssh-rsa") + + defaultto "none" + end + + newproperty(:key) do + desc "The key itself; generally a long string of hex digits." + end + + newproperty(:user) do + desc "The user account in which the ssh key should be installed." + end + + newproperty(:target) do + desc "The file in which to store the ssh key." + end + + newproperty(:options, :array_matching => :all) do + desc "Key options, see sshd(8) for possible values. Multiple values + should be specified as an array." + + defaultto do :absent end + end + end +end + diff --git a/spec/unit/ral/provider/ssh_authorized_key/parsed.rb b/spec/unit/ral/provider/ssh_authorized_key/parsed.rb new file mode 100644 index 000000000..459001cb5 --- /dev/null +++ b/spec/unit/ral/provider/ssh_authorized_key/parsed.rb @@ -0,0 +1,74 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../../spec_helper' + +require 'puppettest' +require 'puppettest/support/utils' +require 'puppettest/fileparsing' + +provider_class = Puppet::Type.type(:ssh_authorized_key).provider(:parsed) + +describe provider_class do + include PuppetTest + include PuppetTest::FileParsing + + before :each do + @sshauthkey_class = Puppet.type(:ssh_authorized_key) + @provider = @sshauthkey_class.provider(:parsed) + end + + after :each do + @provider.initvars + end + + def mkkey(args) + fakeresource = fakeresource(:ssh_authorized_key, args[:name]) + + key = @provider.new(fakeresource) + args.each do |p,v| + key.send(p.to_s + "=", v) + end + + return key + end + + def genkey(key) + @provider.filetype = :ram + file = @provider.default_target + + key.flush + text = @provider.target_object(file).read + return text + end + + it "should be able to parse each example" do + fakedata("data/providers/ssh_authorized_key/parsed").each { |file| + puts "Parsing %s" % file + fakedataparse(file) + } + end + + it "should be able to generate a basic authorized_keys file" do + key = mkkey({ + :name => "Just Testing", + :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", + :type => "ssh-dss", + :ensure => :present, + :options => [:absent] + }) + + genkey(key).should == "ssh-dss AAAAfsfddsjldjgksdflgkjsfdlgkj Just Testing\n" + end + + it "should be able to generate a authorized_keys file with options" do + key = mkkey({ + :name => "root@localhost", + :key => "AAAAfsfddsjldjgksdflgkjsfdlgkj", + :type => "ssh-rsa", + :ensure => :present, + :options => ['from="192.168.1.1"', "no-pty", "no-X11-forwarding"] + }) + + genkey(key).should == "from=\"192.168.1.1\",no-pty,no-X11-forwarding ssh-rsa AAAAfsfddsjldjgksdflgkjsfdlgkj root@localhost\n" + end +end diff --git a/spec/unit/ral/type/ssh_authorized_key.rb b/spec/unit/ral/type/ssh_authorized_key.rb new file mode 100644 index 000000000..d27cb9f25 --- /dev/null +++ b/spec/unit/ral/type/ssh_authorized_key.rb @@ -0,0 +1,80 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +ssh_authorized_key = Puppet::Type.type(:ssh_authorized_key) + +describe ssh_authorized_key do + before do + @class = Puppet::Type.type(:ssh_authorized_key) + + @provider_class = stub 'provider_class', :name => "fake", :suitable? => true, :supports_parameter? => true + @class.stubs(:defaultprovider).returns(@provider_class) + @class.stubs(:provider).returns(@provider_class) + + @provider = stub 'provider', :class => @provider_class, :file_path => "/tmp/whatever", :clear => nil + @provider_class.stubs(:new).returns(@provider) + end + + it "should have a name parameter" do + @class.attrtype(:name).should == :param + end + + it "should have :name be its namevar" do + @class.namevar.should == :name + end + + it "should have a :provider parameter" do + @class.attrtype(:provider).should == :param + end + + it "should have an ensure property" do + @class.attrtype(:ensure).should == :property + end + + it "should support :present as a value for :ensure" do + proc { @class.create(:name => "whev", :ensure => :present) }.should_not raise_error + end + + it "should support :absent as a value for :ensure" do + proc { @class.create(:name => "whev", :ensure => :absent) }.should_not raise_error + end + + it "should have an type property" do + @class.attrtype(:type).should == :property + end + it "should support ssh-dss as an type value" do + proc { @class.create(:name => "whev", :type => "ssh-dss") }.should_not raise_error + end + it "should support ssh-rsa as an type value" do + proc { @class.create(:name => "whev", :type => "ssh-rsa") }.should_not raise_error + end + it "should support :dsa as an type value" do + proc { @class.create(:name => "whev", :type => :dsa) }.should_not raise_error + end + it "should support :rsa as an type value" do + proc { @class.create(:name => "whev", :type => :rsa) }.should_not raise_error + end + + it "should not support values other than ssh-dss, ssh-rsa, dsa, rsa in the ssh_authorized_key_type" do + proc { @class.create(:name => "whev", :type => :something) }.should raise_error(Puppet::Error) + end + + it "should have an key property" do + @class.attrtype(:key).should == :property + end + + it "should have an user property" do + @class.attrtype(:user).should == :property + end + + it "should have an options property" do + @class.attrtype(:options).should == :property + end + + it "should have a target property" do + @class.attrtype(:target).should == :property + end + + after { @class.clear } +end diff --git a/test/data/providers/ssh_authorized_key/parsed/authorized_keys b/test/data/providers/ssh_authorized_key/parsed/authorized_keys new file mode 100644 index 000000000..033f98b87 --- /dev/null +++ b/test/data/providers/ssh_authorized_key/parsed/authorized_keys @@ -0,0 +1,5 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@nimag.net +ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz <francois@ctrlaltdel.ch> +from="192.168.1.1",command="/bin/false",no-pty,no-port-forwarding ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= Francois Deppierraz +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2Vi+TdC3iOGYcIo5vGTvC9P9rjHl9RxCuZmSfn+YDFQ35RXf0waijtjp9I7GYh6R4hBjA5z0u/Pzi95LET5NfRM0Gdc0DJyvBI7K+ALBxIT383Iz6Yz4iKxe1TEJgHGM2he4+7BHkjc3kdIZqIpZjucCk4VsXSxujO4MKKvtaKK2l+kahlLQHHw/vZkDpIgL52iGVsjW9l8RLJaKHZ4mDHJN/Q/Rzn2W4EvcdHUzwhvGMwZlm8clDwITBrSsawYtnivJrQSYcmTRqJuS8wprNDrLIhTGjrwFg5WpruUuMt6fLuCqwe6TeEL+nh3DQ4g554c5aRp3oU6LGBKTvNZGWQ== francois@korn +ssh-dss AAAAB3NzaC1kc3MAAACBAMPpCYnjywOemd8LqbbmC+bePNR3/H1rXsiFwjSLhYE3bbOpvclvOzN1DruFc34m0FopVnMkP+aubjdIYF8pijl+5hg9ggB7Kno2dl0Dd1rGN/swvmhA8OpLAQv7Qt7UnXKVho3as08zYZsrHxYFu0wlnkdbsv4cy4aXyQKd4MPVAAAAFQDSyQFWg8Qt3wU05buhZ10psoR7tQAAAIEAmAhguXwUnI3P2FF5NAW/mpJUmUERdL4pyZARUyAgpf7ezwrh9TJqrvGTQNBF97Xqaivyncm5JWQdMIsTBxEFaXZGkmBta02KnWcn447qvIh7iv8XpNL6M9flCkBEZOJ4t9El0ytTSHHaiCz8A20Et+E8evWyi1kXkFDt8ML2dGgAAACBAK0X4ympbdEjgV/ZyOc+BU22u7vOnfSOUJmyar4Ax1MIDNnoyNWKnGvxRutydQcQOKQHZEU0fE8MhPFn6nLF6CoVfEl/oz0EYz3hjV4WPFpHrF5DY/rhvNj8iuneKJ5P0dy/rG6m5qey25PnHyGFVoIRlkHJvBCJT40dHs40YEjI francois@korn diff --git a/test/data/types/ssh_authorized_key/1 b/test/data/types/ssh_authorized_key/1 new file mode 100644 index 000000000..69d1af15e --- /dev/null +++ b/test/data/types/ssh_authorized_key/1 @@ -0,0 +1,2 @@ +ssh-dss AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVe+esFfd3qWBseb83PoFX63geZJAg6bjV4/Rdn1zEoa9EO2QyUdYUen4+rpsh3vVKZ6HFNsn3+W5+kPYgE1F/N4INqkbjY3sqCkP/W1BL9+sbVVbuJFAAAAFQCfjWDk5XhvGUkPjNWWVqltBYzHtwAAAIEAg/XL7ky7x9Ad5banzPFAfmM+DGFe0A/JEbLDjKmr5KBM5x4RFohtEvZ8ECuVGUOqBWdgAjyYwsG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4knEl+mNfOLq+FH0011UhecOiqTcESMzQDtgQ1vJh2VchElBLjl3x/ZugAAACAAh5jGQC338t5ObP8trSlOefkx0sXmmEzUbo3Mt8mGUuGJPx8m+X0L8Xd+l5rQxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaLZq7m/RmsWYvoLT3jebBlpvvQE8YlI= francois.deppierraz@camptocamp.com +from="192.168.1.2",command="/usr/local/bin/backup.sh",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1kc3MAAACBAJkupmdsJSDXfUy5EU5NTRBDr9Woo3w0YnB8KmnJW9ghU8C7SkWPB1fIHVesG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4ksG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4ksG4oRVjLnKrf/rgmbNRzSFgEWkcAye3BVwk7Dt6hh4kxytqE3SmV/RD+6REqBuPqHM8RQuqAzfjdOeg/Ajdggx1CRMTVhltZsgQoxO30cz9Qo0SdPoL+Jp1fLuaL Backup system |