From c398db1e6f9eb3e0f7c9296116564b0a6ffb7777 Mon Sep 17 00:00:00 2001 From: Andrew Shafer Date: Tue, 2 Dec 2008 13:57:33 -0700 Subject: Bug #1780 Fixing meaningless test Gave meaning to test dependent on feature for role property --- spec/unit/type/user.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spec/unit/type/user.rb b/spec/unit/type/user.rb index e40837635..de04371ed 100755 --- a/spec/unit/type/user.rb +++ b/spec/unit/type/user.rb @@ -241,12 +241,20 @@ describe user do describe "when user has roles" do it "should autorequire roles" do - testuser = Puppet.type(:user).create(:name => "testuser", :roles => "testrole") + #this is a little funky because the autorequire depends on a property with a feature + testuser = Puppet.type(:user).create(:name => "testuser") + testuser.provider.class.expects(:feature?).with(:manages_solaris_rbac).returns(true) + testuser[:roles] = "testrole" + testrole = Puppet.type(:user).create(:name => "testrole") + config = Puppet::Node::Catalog.new :testing do |conf| [testuser, testrole].each { |resource| conf.add_resource resource } end - testuser.autorequire + + rel = testuser.autorequire[0] + rel.source.ref.should == testrole.ref + rel.target.ref.should == testuser.ref end end end -- cgit From 9384a4ab1ec902487bb0b4d329e554283a147529 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Wed, 29 Oct 2008 10:50:54 +1100 Subject: Added git changelog task --- Rakefile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Rakefile b/Rakefile index f9e349afc..7175c3eb8 100644 --- a/Rakefile +++ b/Rakefile @@ -208,3 +208,22 @@ task :mail_patches do # Finally, clean up the patches sh "rm 00*.patch" end + + desc "Create a changelog based on your git commits." + task :changelog do + + CHANGELOG_DIR = "#{Dir.pwd}" + + mkdir(CHANGELOG_DIR) unless File.directory?(CHANGELOG_DIR) + + change_body=`git log --pretty=format:'%aD%n%an <%ae>%n%s%n'` + version = version + "\n" + + File.open(File.join(CHANGELOG_DIR, "CHANGELOG.git"), 'w') do |f| + f << version << change_body + end + + # Changelog commit + `git add #{CHANGELOG_DIR}/CHANGELOG.git` + `git commit -m "Update CHANGELOG.git"` + end -- cgit From edef064ee2a2fe50113cbd2dde8e2bf45b500c55 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Wed, 3 Dec 2008 19:25:12 -0800 Subject: Make ralsh behave more sanely for non-existent objects and property values --- bin/ralsh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/ralsh b/bin/ralsh index 3cbfcad41..5dae8f130 100755 --- a/bin/ralsh +++ b/bin/ralsh @@ -192,7 +192,9 @@ properties = typeobj.properties.collect { |s| s.name } format = proc {|trans| trans.dup.collect do |param, value| - if value == "" or value == [] + if value.nil? or value.to_s.empty? + trans.delete(param) + elsif value.to_s == "absent" and param.to_s != "ensure" trans.delete(param) end -- cgit From 7de82c387b29b0c9202e35d680f109407c07faa7 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Thu, 4 Dec 2008 10:26:00 -0800 Subject: add support for stdin to Puppet::Util.execute --- lib/puppet/util.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index 09c94c3c9..b07b2dfec 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -268,7 +268,7 @@ module Util # Execute the desired command, and return the status and output. # def execute(command, failonfail = true, uid = nil, gid = nil) - def execute(command, arguments = {:failonfail => true, :combine => true}) + def execute(command, arguments = {:failonfail => true, :combine => true, :stdin => "/dev/null"}) if command.is_a?(Array) command = command.flatten.collect { |i| i.to_s } str = command.join(" ") @@ -321,7 +321,7 @@ module Util # Child process executes this Process.setsid begin - $stdin.reopen("/dev/null") + $stdin.reopen(arguments[:stdin]) $stdout.reopen(output_file) $stderr.reopen(error_file) -- cgit From c4412ec90c7ac4fecc49bbb632a0c4e84efb2ad4 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Thu, 4 Dec 2008 13:08:16 -0800 Subject: add some more sanity checks around stdin --- lib/puppet/util.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index b07b2dfec..a5f3c5b1a 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -268,7 +268,10 @@ module Util # Execute the desired command, and return the status and output. # def execute(command, failonfail = true, uid = nil, gid = nil) - def execute(command, arguments = {:failonfail => true, :combine => true, :stdin => "/dev/null"}) + # :combine sets whether or not to combine stdout/stderr in the output + # :stdinfile sets a file that can be used for stdin. Passing a string + # for stdin is not currently supported. + def execute(command, arguments = {:failonfail => true, :combine => true}) if command.is_a?(Array) command = command.flatten.collect { |i| i.to_s } str = command.join(" ") @@ -321,7 +324,11 @@ module Util # Child process executes this Process.setsid begin - $stdin.reopen(arguments[:stdin]) + if arguments[:stdinfile] + $stdin.reopen(arguments[:stdinfile]) + else + $stdin.reopen("/dev/null") + end $stdout.reopen(output_file) $stderr.reopen(error_file) @@ -466,4 +473,3 @@ require 'puppet/util/execution' require 'puppet/util/logging' require 'puppet/util/package' require 'puppet/util/warnings' - -- cgit From 99ab9405fa51266d639f477f96fefe2e7229968f Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Tue, 2 Dec 2008 06:58:01 -0800 Subject: Warn that the NetInfo nameservice provider is deprecated. Use directoryservice instead --- lib/puppet/provider/nameservice/netinfo.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/puppet/provider/nameservice/netinfo.rb b/lib/puppet/provider/nameservice/netinfo.rb index ac7bc94b1..70491da57 100644 --- a/lib/puppet/provider/nameservice/netinfo.rb +++ b/lib/puppet/provider/nameservice/netinfo.rb @@ -1,5 +1,7 @@ -# Manage NetInfo POSIX objects. Probably only used on OS X, but I suppose -# it could be used elsewhere. +# Manage NetInfo POSIX objects. +# +# This provider has been deprecated. You should be using the directoryservice +# nameservice provider instead. require 'puppet' require 'puppet/provider/nameservice' @@ -46,6 +48,7 @@ class NetInfo < Puppet::Provider::NameService end def self.instances + warnonce "The NetInfo provider is deprecated; use directoryservice instead" report(@resource_type.validproperties).collect do |hash| self.new(hash) end @@ -131,6 +134,7 @@ class NetInfo < Puppet::Provider::NameService end def ensure=(arg) + warnonce "The NetInfo provider is deprecated; use directoryservice instead" super # Because our stupid type can't create the whole thing at once, @@ -202,6 +206,7 @@ class NetInfo < Puppet::Provider::NameService # Get a report for a single resource, not the whole table def single_report(*properties) + warnonce "The NetInfo provider is deprecated; use directoryservice instead" self.class.report(*properties).find do |hash| hash[:name] == self.name end end -- cgit From 5d32cd9ad011ee3771e42837f9c6d5bde6462909 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Tue, 2 Dec 2008 09:12:40 -0800 Subject: add NetInfo deprecation notice to user and group providers, make the directoryservice user provider the default, remove default for darwin from NetInfo providers --- lib/puppet/provider/group/netinfo.rb | 8 +++++--- lib/puppet/provider/user/directoryservice.rb | 1 + lib/puppet/provider/user/netinfo.rb | 12 +++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/puppet/provider/group/netinfo.rb b/lib/puppet/provider/group/netinfo.rb index b2174778f..7c3539eae 100644 --- a/lib/puppet/provider/group/netinfo.rb +++ b/lib/puppet/provider/group/netinfo.rb @@ -1,11 +1,13 @@ -# Manage NetInfo POSIX objects. Probably only used on OS X, but I suppose -# it could be used elsewhere. +# Manage NetInfo POSIX objects. +# +# This provider has been deprecated. You should be using the directoryservice +# nameservice provider instead. + require 'puppet/provider/nameservice/netinfo' Puppet::Type.type(:group).provide :netinfo, :parent => Puppet::Provider::NameService::NetInfo do desc "Group management using NetInfo." commands :nireport => "nireport", :niutil => "niutil" - defaultfor :operatingsystem => :darwin end diff --git a/lib/puppet/provider/user/directoryservice.rb b/lib/puppet/provider/user/directoryservice.rb index 68cb79852..4d6bf7d29 100644 --- a/lib/puppet/provider/user/directoryservice.rb +++ b/lib/puppet/provider/user/directoryservice.rb @@ -19,6 +19,7 @@ Puppet::Type.type(:user).provide :directoryservice, :parent => Puppet::Provider: commands :dscl => "/usr/bin/dscl" confine :operatingsystem => :darwin + defaultfor :operatingsystem => :darwin # JJM: DirectoryService can manage passwords. # This needs to be a special option to dscl though (-passwd) diff --git a/lib/puppet/provider/user/netinfo.rb b/lib/puppet/provider/user/netinfo.rb index fccc6c294..067017258 100644 --- a/lib/puppet/provider/user/netinfo.rb +++ b/lib/puppet/provider/user/netinfo.rb @@ -1,5 +1,8 @@ -# Manage NetInfo POSIX objects. Probably only used on OS X, but I suppose -# it could be used elsewhere. +# Manage NetInfo POSIX objects. +# +# This provider has been deprecated. You should be using the directoryservice +# nameservice provider instead. + require 'puppet/provider/nameservice/netinfo' Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameService::NetInfo do @@ -15,7 +18,6 @@ Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameServ options :comment, :key => "realname" options :password, :key => "passwd" - defaultfor :operatingsystem => :darwin autogen_defaults :home => "/var/empty", :shell => "/usr/bin/false", :password => '********' @@ -36,6 +38,8 @@ Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameServ # The list of all groups the user is a member of. Different # user mgmt systems will need to override this method. def groups + warnonce "The NetInfo provider is deprecated; use directoryservice instead" + groups = [] user = @resource[:name] @@ -59,6 +63,8 @@ Puppet::Type.type(:user).provide :netinfo, :parent => Puppet::Provider::NameServ # This is really lame. We have to iterate over each # of the groups and add us to them. def groups=(groups) + warnonce "The NetInfo provider is deprecated; use directoryservice instead" + case groups when Fixnum: groups = [groups.to_s] -- cgit From 4ed73efa94408aba6344cdc0412715acf2014412 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Tue, 2 Dec 2008 12:28:19 -0800 Subject: reset macauthorization tree. Initial checkin of new type/provider --- .../provider/macauthorization/macauthorization.rb | 280 +++++++++++++++++++++ lib/puppet/type/macauthorization.rb | 115 +++++++++ lib/rake | 1 + 3 files changed, 396 insertions(+) create mode 100644 lib/puppet/provider/macauthorization/macauthorization.rb create mode 100644 lib/puppet/type/macauthorization.rb create mode 120000 lib/rake diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb new file mode 100644 index 000000000..a9ce628fe --- /dev/null +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -0,0 +1,280 @@ +require 'facter/util/plist' +require 'puppet' + +Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do +# Puppet::Type.type(:macauthorization).provide :macauth do + desc "Manage Mac OS X authorization database." + + commands :security => "/usr/bin/security" + + confine :operatingsystem => :darwin + defaultfor :operatingsystem => :darwin + + AuthorizationDB = "/etc/authorization" + @rights = {} + @rules = {} + @parsed_auth_db = {} + @comment = "" + + PuppetToNativeAttributeMap = { :allow_root => "allow-root", + :authenticate_user => "authenticate-user", + :authclass => "class", + :k_of_n => "k-of-n", + :comment => "comment", + # :group => "group," + :shared => "shared", + :mechanisms => "mechanisms"} + + NativeToPuppetAttributeMap = { "allow-root" => :allow_root, + "authenticate-user" => :authenticate_user, + "class" => :authclass, + "comment" => :comment, + "shared" => :shared, + "mechanisms" => :mechanisms, } + + mk_resource_methods + + class << self + attr_accessor :parsed_auth_db + attr_accessor :rights + attr_accessor :rules + attr_accessor :comments + end + + def self.prefetch(resources) + # Puppet.notice("self.prefetch.") + self.populate_rules_rights + end + + def self.instances + # Puppet.notice("self.instances") + self.populate_rules_rights + self.parsed_auth_db.collect do |k,v| + new(:name => k) # doesn't seem to matter if I fill them in? + end + end + + def self.populate_rules_rights + # Puppet.notice("self.populate_rules_rights") + auth_plist = Plist::parse_xml("/etc/authorization") + if not auth_plist + Puppet.notice("This should be an error nigel") + end + self.rights = auth_plist["rights"] + self.rules = auth_plist["rules"] + self.parsed_auth_db = self.rights + self.parsed_auth_db.merge(self.rules) + end + + def initialize(resource) + Puppet.notice "initialize" + super + end + + def flush + # Puppet.notice("flush called") + case resource[:auth_type] + when :right + flush_right + when :rule + flush_rule + else + raise Puppet::Error("flushing something that isn't a right or a rule.") + end + @property_hash.clear # huh? do I have to? + end + + def flush_right + # first we re-read the right just to make sure we're in sync for values + # that weren't specified in the manifest. As we're supplying the whole + # plist when specifying the right it seems safest to be paranoid. + cmds = [] << :security << "authorizationdb" << "read" << resource[:name] + output = execute(cmds, :combine => false) + current_values = Plist::parse_xml(output) + specified_values = convert_plist_to_native_attributes(@property_hash) + + # specified_values.each_pair do |k,v| + # Puppet.notice "specified_values: #{k} => #{v}" + # end + # current_values.each_pair do |k,v| + # Puppet.notice "current values: #{k} => #{v}" + # end + + # take the current values, merge the specified values to obtain a complete + # description of the new values. + new_values = current_values.merge(specified_values) + new_values.each_pair do |k,v| + Puppet.notice "new values: #{k} => #{v}" + end + end + + def flush_rule + + end + + def convert_plist_to_native_attributes(propertylist) + propertylist.each_pair do |key, value| + if PuppetToNativeAttributeMap.has_key?(key) + new_key = PuppetToNativeAttributeMap[key] + propertylist[new_key] = value + propertylist.delete(key) + end + end + propertylist + end + + # # Look up the current status. + # def properties + # if @property_hash.empty? + # @property_hash = status || {} + # if @property_hash.empty? + # @property_hash[:ensure] = :absent + # else + # @resource.class.validproperties.each do |name| + # @property_hash[name] ||= :absent + # end + # end + # + # end + # @property_hash.dup + # end + + def create + Puppet.notice "creating #{resource[:name]}" + return :true + end + + def destroy + Puppet.notice "destroying #{resource[:name]}" + end + + def exists? + if self.class.parsed_auth_db.has_key?(resource[:name]) + :true + else + :false + end + end + + def retrieve_value(resource_name, attribute) + # Puppet.notice "retrieve #{attribute} from #{resource_name}" + + return nil if not self.class.parsed_auth_db.has_key?(resource_name) # error!! + + if PuppetToNativeAttributeMap.has_key?(attribute) + native_attribute = PuppetToNativeAttributeMap[attribute] + # Puppet.notice "attribute set from: #{attribute} to #{PuppetToNativeAttributeMap[attribute]}" + else + native_attribute = attribute + end + + if self.class.parsed_auth_db[resource_name].has_key?(native_attribute) + value = self.class.parsed_auth_db[resource_name][native_attribute] + # Puppet.notice "retrieve value has found: #{value} of kind #{value.class}" + if value == "true" or value == true or value == :true + value = :true + elsif value == "false" or value == false or value == :false + value = :false + end + @property_hash[attribute] = value + # @property_hash.each_pair do |k,v| + # next if k == :ensure + # Puppet.notice "NBK: prop hash for #{k} is #{v}" + # end + return value + else + @property_hash.delete(attribute) # do I do this here? + return + end + + end + + def allow_root + retrieve_value(resource[:name], :allow_root) + end + + def allow_root=(value) + @property_hash[:allow_root] = value + end + + def authenticate_user + retrieve_value(resource[:name], :authenticate_user) + end + + def authenticate_user= (dosync) + @property_hash[:authenticate_user] = value + end + + def auth_class + retrieve_value(resource[:name], :authclass) + end + + def auth_class=(value) + @property_hash[:auth_class] = value + end + + def comment + retrieve_value(resource[:name], :comment) + end + + def comment=(value) + @property_hash[:comment] = value + end + + def group + retrieve_value(resource[:name], :group) + end + + def group=(value) + @property_hash[:group] = value + end + + def k_of_n + retrieve_value(resource[:name], :k_of_n) + end + + def k_of_n=(value) + @property_hash[:k_of_n] = value + end + + def mechanisms + retrieve_value(resource[:name], :mechanisms) + end + + def mechanisms=(value) + @property_hash[:mechanisms] = value + end + + def rule + retrieve_value(resource[:name], :rule) + end + + def rule=(value) + @property_hash[:rule] = value + end + + def shared + retrieve_value(resource[:name], :shared) + end + + def shared=(value) + Puppet.notice "setting shared to: #{value} of kind #{value.class}" + @property_hash[:shared] = value + end + + def auth_type + if self.class.rights.has_key?(resource[:name]) + return :right + elsif self.class.rules.has_key?(resource[:name]) + return :rule + else + raise Puppet::Error.new("wtf mate?") + end + end + + def auth_type=(value) + Puppet.notice "set auth_type=" + @property_hash[:auth_type] = value + end + +end \ No newline at end of file diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb new file mode 100644 index 000000000..c17471aa4 --- /dev/null +++ b/lib/puppet/type/macauthorization.rb @@ -0,0 +1,115 @@ +Puppet::Type.newtype(:macauthorization) do + + @doc = "Manage authorization databases" + + ensurable + + autorequire(:file) do + ["/etc/authorization"] + end + + def munge_boolean(value) + case value + when true, "true", :true: + true + when false, "false", :false + false + else + raise Puppet::Error("munge_boolean only takes booleans") + end + end + + newparam(:name) do + desc "The name of the right or rule to be managed." + isnamevar + end + + # did I have to make this a property not a param so the provider can set it with ralsh? + newproperty(:auth_type) do + desc "type - can be a right a rule or a comment" + newvalue(:right) + newvalue(:rule) + newvalue(:comment) + end + + # I wish I could use hyphens here... look into quoting + newproperty(:allow_root, :boolean => true) do + desc "Corresponds to 'allow-root' in the authorization store. hyphens not allowed..." + newvalue(:true) + newvalue(:false) + + munge do |value| + # case value + # when true, "true", :true: + # true + # when false, "false", :false + # false + # else + # raise Puppet::Error("allow_root only takes booleans") + # end + munge_boolean(value) + end + end + + newproperty(:authenticate_user, :boolean => true) do + # desc "authenticate-user" + newvalue(:true) + newvalue(:false) + + munge do |value| + case value + when true, "true", :true: + true + when false, "false", :false + false + else + raise Puppet::Error("munge_boolean only takes booleans") + end + end + end + + newproperty(:auth_class) do + desc "Corresponds to 'class' in the authorization store. class is + a reserved word in Puppet syntax, so we use 'authclass'." + newvalue(:user) + newvalue(:'evaluate-mechanisms') + end + + newproperty(:comment) do + desc "Comment. simple enough eh?" + end + + newproperty(:group) do + desc "group" + end + + newproperty(:k_of_n) do + desc "k-of-n. odd." + end + + newproperty(:mechanisms, :array_match => :all) do + desc "mechanisms" + end + + newproperty(:rule, :array_match => :all) do + desc "rule" + end + + newproperty(:shared, :boolean => true) do + desc "shared" + newvalue(:true) + newvalue(:false) + + munge do |value| + case value + when true, "true", :true: + :true + when false, "false", :false + :false + else + raise Puppet::Error("munge_boolean only takes booleans") + end + end + end + +end diff --git a/lib/rake b/lib/rake new file mode 120000 index 000000000..0ac8c7681 --- /dev/null +++ b/lib/rake @@ -0,0 +1 @@ +/Qualia/Repos/github/reductive-build/lib/rake \ No newline at end of file -- cgit From 1e37230c8d34fb2c19a0025a222464dc97c1ee06 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Wed, 3 Dec 2008 17:45:04 -0800 Subject: macauthorization type --- .../provider/macauthorization/macauthorization.rb | 89 +++++++++------------- lib/puppet/type/macauthorization.rb | 40 +++------- 2 files changed, 46 insertions(+), 83 deletions(-) diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index a9ce628fe..ababb35cc 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -11,6 +11,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe defaultfor :operatingsystem => :darwin AuthorizationDB = "/etc/authorization" + @rights = {} @rules = {} @parsed_auth_db = {} @@ -20,17 +21,19 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe :authenticate_user => "authenticate-user", :authclass => "class", :k_of_n => "k-of-n", - :comment => "comment", + # :comment => "comment", # :group => "group," - :shared => "shared", - :mechanisms => "mechanisms"} + # :shared => "shared", + # :mechanisms => "mechanisms" + } NativeToPuppetAttributeMap = { "allow-root" => :allow_root, "authenticate-user" => :authenticate_user, - "class" => :authclass, - "comment" => :comment, - "shared" => :shared, - "mechanisms" => :mechanisms, } + # "class" => :authclass, + # "comment" => :comment, + # "shared" => :shared, + # "mechanisms" => :mechanisms, + } mk_resource_methods @@ -42,12 +45,12 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def self.prefetch(resources) - # Puppet.notice("self.prefetch.") + Puppet.notice("self.prefetch.") self.populate_rules_rights end def self.instances - # Puppet.notice("self.instances") + Puppet.notice("self.instances") self.populate_rules_rights self.parsed_auth_db.collect do |k,v| new(:name => k) # doesn't seem to matter if I fill them in? @@ -55,7 +58,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def self.populate_rules_rights - # Puppet.notice("self.populate_rules_rights") + Puppet.notice("self.populate_rules_rights") auth_plist = Plist::parse_xml("/etc/authorization") if not auth_plist Puppet.notice("This should be an error nigel") @@ -68,11 +71,11 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe def initialize(resource) Puppet.notice "initialize" + self.class.populate_rules_rights super end def flush - # Puppet.notice("flush called") case resource[:auth_type] when :right flush_right @@ -93,52 +96,34 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe current_values = Plist::parse_xml(output) specified_values = convert_plist_to_native_attributes(@property_hash) - # specified_values.each_pair do |k,v| - # Puppet.notice "specified_values: #{k} => #{v}" - # end - # current_values.each_pair do |k,v| - # Puppet.notice "current values: #{k} => #{v}" - # end - # take the current values, merge the specified values to obtain a complete # description of the new values. new_values = current_values.merge(specified_values) - new_values.each_pair do |k,v| - Puppet.notice "new values: #{k} => #{v}" - end end def flush_rule end + # This mainly converts the keys from the puppet attributes to the 'native' + # ones, but also enforces that the keys are all Strings rather than Symbols + # so that any merges of the resultant Hash are sane. def convert_plist_to_native_attributes(propertylist) propertylist.each_pair do |key, value| + new_key = nil if PuppetToNativeAttributeMap.has_key?(key) - new_key = PuppetToNativeAttributeMap[key] - propertylist[new_key] = value + new_key = PuppetToNativeAttributeMap[key].to_s + elsif not key.is_a?(String) + new_key = key.to_s + end + if not new_key.nil? propertylist.delete(key) + propertylist[new_key] = value end end propertylist end - # # Look up the current status. - # def properties - # if @property_hash.empty? - # @property_hash = status || {} - # if @property_hash.empty? - # @property_hash[:ensure] = :absent - # else - # @resource.class.validproperties.each do |name| - # @property_hash[name] ||= :absent - # end - # end - # - # end - # @property_hash.dup - # end - def create Puppet.notice "creating #{resource[:name]}" return :true @@ -159,34 +144,30 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe def retrieve_value(resource_name, attribute) # Puppet.notice "retrieve #{attribute} from #{resource_name}" - return nil if not self.class.parsed_auth_db.has_key?(resource_name) # error!! + if not self.class.parsed_auth_db.has_key?(resource_name) + raise Puppet::Error("Unable to find resource #{resource_name} in authorization db.") + end if PuppetToNativeAttributeMap.has_key?(attribute) - native_attribute = PuppetToNativeAttributeMap[attribute] - # Puppet.notice "attribute set from: #{attribute} to #{PuppetToNativeAttributeMap[attribute]}" + native_attribute = PuppetToNativeAttributeMap[attribute] else - native_attribute = attribute + native_attribute = attribute.to_s end if self.class.parsed_auth_db[resource_name].has_key?(native_attribute) value = self.class.parsed_auth_db[resource_name][native_attribute] - # Puppet.notice "retrieve value has found: #{value} of kind #{value.class}" - if value == "true" or value == true or value == :true + case value + when true, "true", :true value = :true - elsif value == "false" or value == false or value == :false + when false, "false", :false value = :false end @property_hash[attribute] = value - # @property_hash.each_pair do |k,v| - # next if k == :ensure - # Puppet.notice "NBK: prop hash for #{k} is #{v}" - # end return value else - @property_hash.delete(attribute) # do I do this here? - return + @property_hash.delete(attribute) + return "" end - end def allow_root @@ -268,6 +249,8 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe elsif self.class.rules.has_key?(resource[:name]) return :rule else + Puppet.notice "self.class.rights.keys #{self.class.rights.keys}" + Puppet.notice "self.class.rules.keys #{self.class.rules.keys}" raise Puppet::Error.new("wtf mate?") end end diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb index c17471aa4..5e05d22a4 100644 --- a/lib/puppet/type/macauthorization.rb +++ b/lib/puppet/type/macauthorization.rb @@ -1,3 +1,5 @@ +require 'ruby-debug' + Puppet::Type.newtype(:macauthorization) do @doc = "Manage authorization databases" @@ -8,12 +10,14 @@ Puppet::Type.newtype(:macauthorization) do ["/etc/authorization"] end + # This probably shouldn't be necessary for properties that have declared + # themselves to be booleans already. def munge_boolean(value) case value when true, "true", :true: - true + :true when false, "false", :false - false + :false else raise Puppet::Error("munge_boolean only takes booleans") end @@ -24,7 +28,6 @@ Puppet::Type.newtype(:macauthorization) do isnamevar end - # did I have to make this a property not a param so the provider can set it with ralsh? newproperty(:auth_type) do desc "type - can be a right a rule or a comment" newvalue(:right) @@ -32,39 +35,23 @@ Puppet::Type.newtype(:macauthorization) do newvalue(:comment) end - # I wish I could use hyphens here... look into quoting newproperty(:allow_root, :boolean => true) do desc "Corresponds to 'allow-root' in the authorization store. hyphens not allowed..." newvalue(:true) newvalue(:false) munge do |value| - # case value - # when true, "true", :true: - # true - # when false, "false", :false - # false - # else - # raise Puppet::Error("allow_root only takes booleans") - # end - munge_boolean(value) + @resource.munge_boolean(value) end end newproperty(:authenticate_user, :boolean => true) do - # desc "authenticate-user" + desc "authenticate-user" newvalue(:true) newvalue(:false) munge do |value| - case value - when true, "true", :true: - true - when false, "false", :false - false - else - raise Puppet::Error("munge_boolean only takes booleans") - end + @resource.munge_boolean(value) end end @@ -101,14 +88,7 @@ Puppet::Type.newtype(:macauthorization) do newvalue(:false) munge do |value| - case value - when true, "true", :true: - :true - when false, "false", :false - :false - else - raise Puppet::Error("munge_boolean only takes booleans") - end + @resource.munge_boolean(value) end end -- cgit From 05e05bb70a2eb6b57b59340c15f4c205a4803b3e Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Thu, 4 Dec 2008 12:41:59 -0800 Subject: finished rights flush, working on rules --- .../provider/macauthorization/macauthorization.rb | 44 ++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index ababb35cc..9d4886e90 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -1,5 +1,6 @@ require 'facter/util/plist' require 'puppet' +require 'tempfile' Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do # Puppet::Type.type(:macauthorization).provide :macauth do @@ -63,10 +64,10 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe if not auth_plist Puppet.notice("This should be an error nigel") end - self.rights = auth_plist["rights"] - self.rules = auth_plist["rules"] - self.parsed_auth_db = self.rights - self.parsed_auth_db.merge(self.rules) + self.rights = auth_plist["rights"].dup + self.rules = auth_plist["rules"].dup + self.parsed_auth_db = self.rights.dup + self.parsed_auth_db.merge!(self.rules.dup) end def initialize(resource) @@ -95,14 +96,43 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe output = execute(cmds, :combine => false) current_values = Plist::parse_xml(output) specified_values = convert_plist_to_native_attributes(@property_hash) - + # take the current values, merge the specified values to obtain a complete # description of the new values. new_values = current_values.merge(specified_values) + + # the security binary only allows for writes using stdin, so we dump this + # to a tempfile. + tmp = Tempfile.new('puppet_macauthorization') + begin + tmp.flush + Plist::Emit.save_plist(new_values, tmp.path) + tmp.flush + cmds = [] << :security << "authorizationdb" << "write" << resource[:name] + output = execute(cmds, :combine => false, :stdin => tmp.path) + ensure + tmp.close + tmp.unlink + end end def flush_rule - + # unfortunately the security binary doesn't support modifying rules at all + # so we have to twiddle the whole plist... :( See Apple Bug #6386000 + authdb = Plist::parse_xml(AuthorizationDB) + authdb_rules = authdb["rules"].dup + current_values = [] + if authdb_rules[resource[:name]] + current_values = authdb_rules[resource[:name]] + end + specified_values = convert_plist_to_native_attributes(@property_hash) + new_values = current_values.merge(specified_values) + authdb["rules"][resource[:name]] = new_values + begin + Plist::Emit.save_plist(authdb, AuthorizationDB) + rescue # what do I rescue here? TODO + raise Puppet::Error.new("couldn't write to authorizationdb") + end end # This mainly converts the keys from the puppet attributes to the 'native' @@ -145,7 +175,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe # Puppet.notice "retrieve #{attribute} from #{resource_name}" if not self.class.parsed_auth_db.has_key?(resource_name) - raise Puppet::Error("Unable to find resource #{resource_name} in authorization db.") + raise Puppet::Error.new("Unable to find resource #{resource_name} in authorization db.") end if PuppetToNativeAttributeMap.has_key?(attribute) -- cgit From ed49153c28a640c941fb9e1d70f196a454ecf151 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Thu, 4 Dec 2008 13:07:02 -0800 Subject: new better way of doing stdin --- lib/puppet/provider/macauthorization/macauthorization.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index 9d4886e90..8d20f0819 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -100,6 +100,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe # take the current values, merge the specified values to obtain a complete # description of the new values. new_values = current_values.merge(specified_values) + Puppet.notice "new values: #{new_values}" # the security binary only allows for writes using stdin, so we dump this # to a tempfile. @@ -107,9 +108,9 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe begin tmp.flush Plist::Emit.save_plist(new_values, tmp.path) - tmp.flush + # tmp.flush cmds = [] << :security << "authorizationdb" << "write" << resource[:name] - output = execute(cmds, :combine => false, :stdin => tmp.path) + output = execute(cmds, :stdinfile => tmp.path.to_s) ensure tmp.close tmp.unlink -- cgit From 0f2fc88a392fd0c28a914d6914f447ecce51701c Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Thu, 4 Dec 2008 17:26:06 -0800 Subject: Finished work on rules creation and deletion --- .../provider/macauthorization/macauthorization.rb | 212 ++++++++++++--------- lib/puppet/type/macauthorization.rb | 6 +- 2 files changed, 129 insertions(+), 89 deletions(-) diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index 8d20f0819..40051bae5 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -16,24 +16,14 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe @rights = {} @rules = {} @parsed_auth_db = {} - @comment = "" + @comment = "" # Not implemented yet. Is there any real need to? + # This map exists due to the use of hyphens and reserved words in + # the authorization schema. PuppetToNativeAttributeMap = { :allow_root => "allow-root", :authenticate_user => "authenticate-user", - :authclass => "class", + :auth_class => "class", :k_of_n => "k-of-n", - # :comment => "comment", - # :group => "group," - # :shared => "shared", - # :mechanisms => "mechanisms" - } - - NativeToPuppetAttributeMap = { "allow-root" => :allow_root, - "authenticate-user" => :authenticate_user, - # "class" => :authclass, - # "comment" => :comment, - # "shared" => :shared, - # "mechanisms" => :mechanisms, } mk_resource_methods @@ -42,27 +32,24 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe attr_accessor :parsed_auth_db attr_accessor :rights attr_accessor :rules - attr_accessor :comments + attr_accessor :comments # Not implemented yet. Is there any real need to? end def self.prefetch(resources) - Puppet.notice("self.prefetch.") self.populate_rules_rights end def self.instances - Puppet.notice("self.instances") self.populate_rules_rights self.parsed_auth_db.collect do |k,v| - new(:name => k) # doesn't seem to matter if I fill them in? + new(:name => k) end end def self.populate_rules_rights - Puppet.notice("self.populate_rules_rights") - auth_plist = Plist::parse_xml("/etc/authorization") + auth_plist = Plist::parse_xml(AuthorizationDB) if not auth_plist - Puppet.notice("This should be an error nigel") + raise Puppet::Error.new("Unable to parse authorization db at #{AuthorizationDB}") end self.rights = auth_plist["rights"].dup self.rules = auth_plist["rules"].dup @@ -71,21 +58,72 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def initialize(resource) - Puppet.notice "initialize" - self.class.populate_rules_rights + if self.class.parsed_auth_db.nil? + self.class.prefetch + end super end - def flush + + def create + # we just fill the @property_hash in here and let the flush method deal with it + new_values = {} + Puppet::Type.type(resource.class.name).validproperties.each do |property| + next if property == :ensure + if value = resource.should(property) and value != "" + new_values[property] = value + end + end + @property_hash = new_values.dup + end + + def destroy + # We explicitly delete here rather than in the flush method. case resource[:auth_type] when :right - flush_right + destroy_right when :rule - flush_rule + destroy_rule + else + raise Puppet::Error("You must specify the auth_type when removing macauthorization resources.") + end + end + + def destroy_right + security :authorizationdb, :remove, resource[:name] + end + + def destroy_rule + authdb = Plist::parse_xml(AuthorizationDB) + authdb_rules = authdb["rules"].dup + if authdb_rules[resource[:name]] + authdb["rules"].delete(resource[:name]) + Plist::Emit.save_plist(authdb, AuthorizationDB) + end + end + + def exists? + if self.class.parsed_auth_db.has_key?(resource[:name]) + # return :present + return true else - raise Puppet::Error("flushing something that isn't a right or a rule.") + return false + end + end + + + def flush + if resource[:ensure] != :absent # deletion happens in the destroy methods + case resource[:auth_type] + when :right + flush_right + when :rule + flush_rule + else + raise Puppet::Error.new("flushing something that isn't a right or a rule.") + end + @property_hash.clear end - @property_hash.clear # huh? do I have to? end def flush_right @@ -95,85 +133,83 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe cmds = [] << :security << "authorizationdb" << "read" << resource[:name] output = execute(cmds, :combine => false) current_values = Plist::parse_xml(output) + if current_values.nil? + current_values = {} + end specified_values = convert_plist_to_native_attributes(@property_hash) # take the current values, merge the specified values to obtain a complete # description of the new values. new_values = current_values.merge(specified_values) - Puppet.notice "new values: #{new_values}" - - # the security binary only allows for writes using stdin, so we dump this - # to a tempfile. + set_right(resource[:name], new_values) + end + + def flush_rule + authdb = Plist::parse_xml(AuthorizationDB) + authdb_rules = authdb["rules"].dup + current_values = {} + if authdb_rules[resource[:name]] + current_values = authdb_rules[resource[:name]] + end + specified_values = convert_plist_to_native_attributes(@property_hash) + new_values = current_values.merge(specified_values) + set_rule(resource[:name], new_values) + end + + def set_right(name, values) + # Both creates and modifies rights as it simply overwrites them. + # The security binary only allows for writes using stdin, so we + # dump the values to a tempfile. + values = convert_plist_to_native_attributes(values) tmp = Tempfile.new('puppet_macauthorization') begin - tmp.flush - Plist::Emit.save_plist(new_values, tmp.path) # tmp.flush - cmds = [] << :security << "authorizationdb" << "write" << resource[:name] - output = execute(cmds, :stdinfile => tmp.path.to_s) + Plist::Emit.save_plist(values, tmp.path) + # tmp.flush + cmds = [] << :security << "authorizationdb" << "write" << name + output = execute(cmds, :combine => false, :stdinfile => tmp.path.to_s) ensure tmp.close tmp.unlink end end - def flush_rule - # unfortunately the security binary doesn't support modifying rules at all + def set_rule(name, values) + # Both creates and modifies rules as it overwrites the entry in the rules + # dictionary. + # Unfortunately the security binary doesn't support modifying rules at all # so we have to twiddle the whole plist... :( See Apple Bug #6386000 + values = convert_plist_to_native_attributes(values) authdb = Plist::parse_xml(AuthorizationDB) - authdb_rules = authdb["rules"].dup - current_values = [] - if authdb_rules[resource[:name]] - current_values = authdb_rules[resource[:name]] - end - specified_values = convert_plist_to_native_attributes(@property_hash) - new_values = current_values.merge(specified_values) - authdb["rules"][resource[:name]] = new_values + authdb["rules"][name] = values + begin Plist::Emit.save_plist(authdb, AuthorizationDB) - rescue # what do I rescue here? TODO - raise Puppet::Error.new("couldn't write to authorizationdb") + rescue + raise Puppet::Error.new("Couldn't write to authorization db at #{AuthorizationDB}") end end - # This mainly converts the keys from the puppet attributes to the 'native' - # ones, but also enforces that the keys are all Strings rather than Symbols - # so that any merges of the resultant Hash are sane. def convert_plist_to_native_attributes(propertylist) + # This mainly converts the keys from the puppet attributes to the 'native' + # ones, but also enforces that the keys are all Strings rather than Symbols + # so that any merges of the resultant Hash are sane. + newplist = {} propertylist.each_pair do |key, value| - new_key = nil + next if key == :ensure + next if key == :auth_type + new_key = key if PuppetToNativeAttributeMap.has_key?(key) new_key = PuppetToNativeAttributeMap[key].to_s elsif not key.is_a?(String) new_key = key.to_s end - if not new_key.nil? - propertylist.delete(key) - propertylist[new_key] = value - end - end - propertylist - end - - def create - Puppet.notice "creating #{resource[:name]}" - return :true - end - - def destroy - Puppet.notice "destroying #{resource[:name]}" - end - - def exists? - if self.class.parsed_auth_db.has_key?(resource[:name]) - :true - else - :false + newplist[new_key] = value end + newplist end def retrieve_value(resource_name, attribute) - # Puppet.notice "retrieve #{attribute} from #{resource_name}" if not self.class.parsed_auth_db.has_key?(resource_name) raise Puppet::Error.new("Unable to find resource #{resource_name} in authorization db.") @@ -184,7 +220,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe else native_attribute = attribute.to_s end - + if self.class.parsed_auth_db[resource_name].has_key?(native_attribute) value = self.class.parsed_auth_db[resource_name][native_attribute] case value @@ -193,6 +229,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe when false, "false", :false value = :false end + @property_hash[attribute] = value return value else @@ -218,7 +255,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def auth_class - retrieve_value(resource[:name], :authclass) + retrieve_value(resource[:name], :auth_class) end def auth_class=(value) @@ -270,24 +307,27 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def shared=(value) - Puppet.notice "setting shared to: #{value} of kind #{value.class}" @property_hash[:shared] = value end def auth_type - if self.class.rights.has_key?(resource[:name]) - return :right - elsif self.class.rules.has_key?(resource[:name]) - return :rule + if resource.should(:auth_type) != nil + return resource.should(:auth_type) + elsif self.exists? + # this is here just for ralsh, so it can work out what type it is. + if self.class.rights.has_key?(resource[:name]) + return :right + elsif self.class.rules.has_key?(resource[:name]) + return :rule + else + raise Puppet::Error.new("Unable to determine if macauthorization type: #{resource[:name]} is a right or a rule.") + end else - Puppet.notice "self.class.rights.keys #{self.class.rights.keys}" - Puppet.notice "self.class.rules.keys #{self.class.rules.keys}" - raise Puppet::Error.new("wtf mate?") + raise Puppet::Error.new("You must specify the auth_type for new macauthorization resources.") end end def auth_type=(value) - Puppet.notice "set auth_type=" @property_hash[:auth_type] = value end diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb index 5e05d22a4..0fae8aba0 100644 --- a/lib/puppet/type/macauthorization.rb +++ b/lib/puppet/type/macauthorization.rb @@ -58,8 +58,8 @@ Puppet::Type.newtype(:macauthorization) do newproperty(:auth_class) do desc "Corresponds to 'class' in the authorization store. class is a reserved word in Puppet syntax, so we use 'authclass'." - newvalue(:user) - newvalue(:'evaluate-mechanisms') + # newvalue(:user) + # newvalue(:'evaluate-mechanisms') end newproperty(:comment) do @@ -74,7 +74,7 @@ Puppet::Type.newtype(:macauthorization) do desc "k-of-n. odd." end - newproperty(:mechanisms, :array_match => :all) do + newproperty(:mechanisms, :array_matching => :all) do desc "mechanisms" end -- cgit From 0caa9c57c67005871c46e160de318044ffb65375 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Fri, 5 Dec 2008 13:28:55 -0800 Subject: spec tests for type and provider and some code cleanup to adhere to DRY --- .../provider/macauthorization/macauthorization.rb | 254 ++++++++++----------- lib/puppet/type/macauthorization.rb | 89 ++++++-- spec/unit/provider/macauthorization.rb | 153 +++++++++++++ spec/unit/type/macauthorization.rb | 80 +++++++ 4 files changed, 416 insertions(+), 160 deletions(-) create mode 100644 spec/unit/provider/macauthorization.rb create mode 100644 spec/unit/type/macauthorization.rb diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index 40051bae5..d29c1d294 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -1,17 +1,26 @@ +require 'facter' require 'facter/util/plist' require 'puppet' require 'tempfile' Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do -# Puppet::Type.type(:macauthorization).provide :macauth do - desc "Manage Mac OS X authorization database." + + desc "Manage Mac OS X authorization database rules and rights." commands :security => "/usr/bin/security" + commands :sw_vers => "/usr/bin/sw_vers" confine :operatingsystem => :darwin + + product_version = sw_vers "-productVersion" + + confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version) + true + end + defaultfor :operatingsystem => :darwin - AuthorizationDB = "/etc/authorization" + AuthDB = "/etc/authorization" @rights = {} @rules = {} @@ -24,7 +33,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe :authenticate_user => "authenticate-user", :auth_class => "class", :k_of_n => "k-of-n", - } + :session_owner => "session-owner", } mk_resource_methods @@ -32,46 +41,53 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe attr_accessor :parsed_auth_db attr_accessor :rights attr_accessor :rules - attr_accessor :comments # Not implemented yet. Is there any real need to? - end + attr_accessor :comments # Not implemented yet. - def self.prefetch(resources) - self.populate_rules_rights - end + def prefetch(resources) + self.populate_rules_rights + end - def self.instances - self.populate_rules_rights - self.parsed_auth_db.collect do |k,v| - new(:name => k) + def instances + if self.parsed_auth_db == {} + self.prefetch(nil) + end + self.parsed_auth_db.collect do |k,v| + new(:name => k) + end end - end - def self.populate_rules_rights - auth_plist = Plist::parse_xml(AuthorizationDB) - if not auth_plist - raise Puppet::Error.new("Unable to parse authorization db at #{AuthorizationDB}") + def populate_rules_rights + auth_plist = Plist::parse_xml(AuthDB) + if not auth_plist + raise Puppet::Error.new("Cannot parse: #{AuthDB}") + end + self.rights = auth_plist["rights"].dup + self.rules = auth_plist["rules"].dup + self.parsed_auth_db = self.rights.dup + self.parsed_auth_db.merge!(self.rules.dup) end - self.rights = auth_plist["rights"].dup - self.rules = auth_plist["rules"].dup - self.parsed_auth_db = self.rights.dup - self.parsed_auth_db.merge!(self.rules.dup) + end + # standard required provider instance methods + def initialize(resource) - if self.class.parsed_auth_db.nil? - self.class.prefetch + if self.class.parsed_auth_db == {} + self.class.prefetch(resource) end super end def create - # we just fill the @property_hash in here and let the flush method deal with it + # we just fill the @property_hash in here and let the flush method + # deal with it rather than repeating code. new_values = {} - Puppet::Type.type(resource.class.name).validproperties.each do |property| - next if property == :ensure - if value = resource.should(property) and value != "" - new_values[property] = value + validprops = Puppet::Type.type(resource.class.name).validproperties + validprops.each do |prop| + next if prop == :ensure + if value = resource.should(prop) and value != "" + new_values[prop] = value end end @property_hash = new_values.dup @@ -85,26 +101,12 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe when :rule destroy_rule else - raise Puppet::Error("You must specify the auth_type when removing macauthorization resources.") - end - end - - def destroy_right - security :authorizationdb, :remove, resource[:name] - end - - def destroy_rule - authdb = Plist::parse_xml(AuthorizationDB) - authdb_rules = authdb["rules"].dup - if authdb_rules[resource[:name]] - authdb["rules"].delete(resource[:name]) - Plist::Emit.save_plist(authdb, AuthorizationDB) + raise Puppet::Error.new("Must specify auth_type when destroying.") end end def exists? if self.class.parsed_auth_db.has_key?(resource[:name]) - # return :present return true else return false @@ -113,24 +115,47 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe def flush - if resource[:ensure] != :absent # deletion happens in the destroy methods + # deletion happens in the destroy methods + if resource[:ensure] != :absent case resource[:auth_type] when :right flush_right when :rule flush_rule else - raise Puppet::Error.new("flushing something that isn't a right or a rule.") + raise Puppet::Error.new("flush requested for unknown type.") end @property_hash.clear end end + + # utility methods below + + def destroy_right + security "authorizationdb", :remove, resource[:name] + end + + def destroy_rule + authdb = Plist::parse_xml(AuthDB) + authdb_rules = authdb["rules"].dup + if authdb_rules[resource[:name]] + begin + authdb["rules"].delete(resource[:name]) + Plist::Emit.save_plist(authdb, AuthDB) + rescue Errno::EACCES => e + raise Puppet::Error.new("Error saving #{AuthDB}: #{e}") + end + end + end + def flush_right - # first we re-read the right just to make sure we're in sync for values - # that weren't specified in the manifest. As we're supplying the whole - # plist when specifying the right it seems safest to be paranoid. - cmds = [] << :security << "authorizationdb" << "read" << resource[:name] + # first we re-read the right just to make sure we're in sync for + # values that weren't specified in the manifest. As we're supplying + # the whole plist when specifying the right it seems safest to be + # paranoid given the low cost of quering the db once more. + cmds = [] + cmds << :security << "authorizationdb" << "read" << resource[:name] output = execute(cmds, :combine => false) current_values = Plist::parse_xml(output) if current_values.nil? @@ -138,14 +163,14 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end specified_values = convert_plist_to_native_attributes(@property_hash) - # take the current values, merge the specified values to obtain a complete - # description of the new values. + # take the current values, merge the specified values to obtain a + # complete description of the new values. new_values = current_values.merge(specified_values) set_right(resource[:name], new_values) end def flush_rule - authdb = Plist::parse_xml(AuthorizationDB) + authdb = Plist::parse_xml(AuthDB) authdb_rules = authdb["rules"].dup current_values = {} if authdb_rules[resource[:name]] @@ -163,11 +188,13 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe values = convert_plist_to_native_attributes(values) tmp = Tempfile.new('puppet_macauthorization') begin - # tmp.flush Plist::Emit.save_plist(values, tmp.path) - # tmp.flush - cmds = [] << :security << "authorizationdb" << "write" << name - output = execute(cmds, :combine => false, :stdinfile => tmp.path.to_s) + cmds = [] + cmds << :security << "authorizationdb" << "write" << name + output = execute(cmds, :combine => false, + :stdinfile => tmp.path.to_s) + rescue Errno::EACCES => e + raise Puppet::Error.new("Cannot save right to #{tmp.path}: #{e}") ensure tmp.close tmp.unlink @@ -175,29 +202,30 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe end def set_rule(name, values) - # Both creates and modifies rules as it overwrites the entry in the rules - # dictionary. - # Unfortunately the security binary doesn't support modifying rules at all - # so we have to twiddle the whole plist... :( See Apple Bug #6386000 + # Both creates and modifies rules as it overwrites the entry in the + # rules dictionary. Unfortunately the security binary doesn't + # support modifying rules at all so we have to twiddle the whole + # plist... :( See Apple Bug #6386000 values = convert_plist_to_native_attributes(values) - authdb = Plist::parse_xml(AuthorizationDB) + authdb = Plist::parse_xml(AuthDB) authdb["rules"][name] = values begin - Plist::Emit.save_plist(authdb, AuthorizationDB) + Plist::Emit.save_plist(authdb, AuthDB) rescue - raise Puppet::Error.new("Couldn't write to authorization db at #{AuthorizationDB}") + raise Puppet::Error.new("Error writing to: #{AuthDB}") end end def convert_plist_to_native_attributes(propertylist) - # This mainly converts the keys from the puppet attributes to the 'native' - # ones, but also enforces that the keys are all Strings rather than Symbols - # so that any merges of the resultant Hash are sane. + # This mainly converts the keys from the puppet attributes to the + # 'native' ones, but also enforces that the keys are all Strings + # rather than Symbols so that any merges of the resultant Hash are + # sane. newplist = {} propertylist.each_pair do |key, value| - next if key == :ensure - next if key == :auth_type + next if key == :ensure # not part of the auth db schema. + next if key == :auth_type # not part of the auth db schema. new_key = key if PuppetToNativeAttributeMap.has_key?(key) new_key = PuppetToNativeAttributeMap[key].to_s @@ -212,7 +240,7 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe def retrieve_value(resource_name, attribute) if not self.class.parsed_auth_db.has_key?(resource_name) - raise Puppet::Error.new("Unable to find resource #{resource_name} in authorization db.") + raise Puppet::Error.new("Cannot find #{resource_name} in auth db") end if PuppetToNativeAttributeMap.has_key?(attribute) @@ -234,80 +262,28 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe return value else @property_hash.delete(attribute) - return "" + return "" # so ralsh doesn't display it. end end - def allow_root - retrieve_value(resource[:name], :allow_root) - end - def allow_root=(value) - @property_hash[:allow_root] = value - end - - def authenticate_user - retrieve_value(resource[:name], :authenticate_user) - end - - def authenticate_user= (dosync) - @property_hash[:authenticate_user] = value - end - - def auth_class - retrieve_value(resource[:name], :auth_class) - end - - def auth_class=(value) - @property_hash[:auth_class] = value - end - - def comment - retrieve_value(resource[:name], :comment) - end - - def comment=(value) - @property_hash[:comment] = value - end - - def group - retrieve_value(resource[:name], :group) - end + # property methods below + # + # We define them all dynamically apart from auth_type which is a special + # case due to not being in the actual authorization db schema. - def group=(value) - @property_hash[:group] = value - end - - def k_of_n - retrieve_value(resource[:name], :k_of_n) - end - - def k_of_n=(value) - @property_hash[:k_of_n] = value - end - - def mechanisms - retrieve_value(resource[:name], :mechanisms) - end + properties = [ :allow_root, :authenticate_user, :auth_class, :comment, + :group, :k_of_n, :mechanisms, :rule, :session_owner, + :shared, :timeout, :tries ] - def mechanisms=(value) - @property_hash[:mechanisms] = value - end - - def rule - retrieve_value(resource[:name], :rule) - end + properties.each do |field| + define_method(field.to_s) do + retrieve_value(resource[:name], field) + end - def rule=(value) - @property_hash[:rule] = value - end - - def shared - retrieve_value(resource[:name], :shared) - end - - def shared=(value) - @property_hash[:shared] = value + define_method(field.to_s + "=") do |value| + @property_hash[field] = value + end end def auth_type @@ -320,10 +296,10 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe elsif self.class.rules.has_key?(resource[:name]) return :rule else - raise Puppet::Error.new("Unable to determine if macauthorization type: #{resource[:name]} is a right or a rule.") + raise Puppet::Error.new("#{resource[:name]} is unknown type.") end else - raise Puppet::Error.new("You must specify the auth_type for new macauthorization resources.") + raise Puppet::Error.new("auth_type required for new resources.") end end diff --git a/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb index 0fae8aba0..46e02ddae 100644 --- a/lib/puppet/type/macauthorization.rb +++ b/lib/puppet/type/macauthorization.rb @@ -1,8 +1,9 @@ -require 'ruby-debug' - Puppet::Type.newtype(:macauthorization) do - @doc = "Manage authorization databases" + @doc = "Manage the Mac OS X authorization database. + + See: http://developer.apple.com/documentation/Security/Conceptual/Security_Overview/Security_Services/chapter_4_section_5.html + for more information." ensurable @@ -10,8 +11,6 @@ Puppet::Type.newtype(:macauthorization) do ["/etc/authorization"] end - # This probably shouldn't be necessary for properties that have declared - # themselves to be booleans already. def munge_boolean(value) case value when true, "true", :true: @@ -24,19 +23,32 @@ Puppet::Type.newtype(:macauthorization) do end newparam(:name) do - desc "The name of the right or rule to be managed." + desc "The name of the right or rule to be managed. + Corresponds to 'key' in Authorization Services. The key is the name + of a rule. A key uses the same naming conventions as a right. The + Security Server uses a rule’s key to match the rule with a right. + Wildcard keys end with a ‘.’. The generic rule has an empty key value. + Any rights that do not match a specific rule use the generic rule." + isnamevar end newproperty(:auth_type) do - desc "type - can be a right a rule or a comment" + desc "type - can be a 'right' or a 'rule'. 'comment' has not yet been + implemented." + newvalue(:right) newvalue(:rule) - newvalue(:comment) + # newvalue(:comment) # not yet implemented. end newproperty(:allow_root, :boolean => true) do - desc "Corresponds to 'allow-root' in the authorization store. hyphens not allowed..." + desc "Corresponds to 'allow-root' in the authorization store, renamed + due to hyphens being problematic. Specifies whether a right should be + allowed automatically if the requesting process is running with + uid == 0. AuthorizationServices defaults this attribute to false if + not specified" + newvalue(:true) newvalue(:false) @@ -46,7 +58,9 @@ Puppet::Type.newtype(:macauthorization) do end newproperty(:authenticate_user, :boolean => true) do - desc "authenticate-user" + desc "Corresponds to 'authenticate-user' in the authorization store, + renamed due to hyphens being problematic." + newvalue(:true) newvalue(:false) @@ -56,34 +70,55 @@ Puppet::Type.newtype(:macauthorization) do end newproperty(:auth_class) do - desc "Corresponds to 'class' in the authorization store. class is - a reserved word in Puppet syntax, so we use 'authclass'." - # newvalue(:user) - # newvalue(:'evaluate-mechanisms') + desc "Corresponds to 'class' in the authorization store, renamed due + to 'class' being a reserved word." + + newvalue(:user) + newvalue(:'evaluate-mechanisms') end newproperty(:comment) do - desc "Comment. simple enough eh?" + desc "The 'comment' attribute for authorization resources." end newproperty(:group) do - desc "group" + desc "The user must authenticate as a member of this group. This + attribute can be set to any one group." end newproperty(:k_of_n) do - desc "k-of-n. odd." + desc "k-of-n. Built-in rights only show a value of '1' or absent, + other values may be acceptable. Undocumented." end newproperty(:mechanisms, :array_matching => :all) do - desc "mechanisms" + desc "an array of suitable mechanisms." end newproperty(:rule, :array_match => :all) do - desc "rule" - end + desc "The rule(s) that this right refers to." + end + + newproperty(:session_owner, :boolean => true) do + desc "Corresponds to 'session-owner' in the authorization store, + renamed due to hyphens being problematic. Whether the session owner + automatically matches this rule or right." + + newvalue(:true) + newvalue(:false) + + munge do |value| + @resource.munge_boolean(value) + end + end newproperty(:shared, :boolean => true) do - desc "shared" + desc "If this is set to true, then the Security Server marks the + credentials used to gain this right as shared. The Security Server + may use any shared credentials to authorize this right. For maximum + security, set sharing to false so credentials stored by the Security + Server for one application may not be used by another application." + newvalue(:true) newvalue(:false) @@ -92,4 +127,16 @@ Puppet::Type.newtype(:macauthorization) do end end + newproperty(:timeout) do + desc "The credential used by this rule expires in the specified + number of seconds. For maximum security where the user must + authenticate every time, set the timeout to 0. For minimum security, + remove the timeout attribute so the user authenticates only once per + session." + end + + newproperty(:tries) do + desc "The number of tries allowed." + end + end diff --git a/spec/unit/provider/macauthorization.rb b/spec/unit/provider/macauthorization.rb new file mode 100644 index 000000000..4754b11c7 --- /dev/null +++ b/spec/unit/provider/macauthorization.rb @@ -0,0 +1,153 @@ +#!/usr/bin/env ruby +# +# Unit testing for the macauthorization provider +# + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet' +require 'facter/util/plist' + +provider_class = Puppet::Type.type(:macauthorization).provider(:macauthorization) + +describe provider_class do + + before :each do + # Create a mock resource + @resource = stub 'resource' + + @provider = provider_class.new(@resource) + + @authname = "foo.spam.eggs.puppettest" + @authplist = {} + + @rules = {@authname => @authplist} + @authdb = {} + @authdb["rules"] = @rules + + # A catch all; no parameters set + @resource.stubs(:[]).returns(nil) + + # But set name, ensure + @resource.stubs(:[]).with(:name).returns @authname + + @resource.stubs(:[]).with(:ensure).returns :present + + @resource.stubs(:ref).returns "MacAuthorization[#{@authname}]" + + # stub out the provider methods that actually touch the filesystem + # or execute commands + @provider.stubs(:populate_rules_rights).returns("") + + # Stub out Plist::parse_xml + Plist.stubs("parse_xml").returns(@authdb) + end + + it "should have a create method" do + @provider.should respond_to(:create) + end + + it "should have a destroy method" do + @provider.should respond_to(:destroy) + end + + it "should have an exists? method" do + @provider.should respond_to(:exists?) + end + + it "should have a flush method" do + @provider.should respond_to(:flush) + end + + properties = [ :allow_root, :authenticate_user, :auth_class, :comment, + :group, :k_of_n, :mechanisms, :rule, :session_owner, + :shared, :timeout, :tries, :auth_type ] + + properties.each do |prop| + it "should have a #{prop.to_s} method" do + @provider.should respond_to(prop.to_s) + end + + it "should have a #{prop.to_s}= method" do + @provider.should respond_to(prop.to_s + "=") + end + end + + describe "when destroying a right" do + before :each do + @resource.stubs(:[]).with(:auth_type).returns(:right) + end + + it "should call the internal method destroy_right" do + @provider.expects("destroy_right") + @provider.destroy + end + it "should call the external command 'security authorizationdb remove @authname" do + @provider.expects(:security).with("authorizationdb", :remove, @authname) + @provider.destroy + end + end + + describe "when destroying a rule" do + before :each do + @resource.stubs(:[]).with(:auth_type).returns(:rule) + end + + it "should call the internal method destroy_rule" do + @provider.expects("destroy_rule") + @provider.destroy + end + end + + describe "when flushing a right" do + before :each do + @resource.stubs(:[]).with(:auth_type).returns(:right) + end + + it "should call the internal method flush_right" do + @provider.expects("flush_right") + @provider.flush + end + + it "should call the internal method set_right" do + @provider.expects("set_right") + @provider.flush + end + + it "should read and write to the auth database with the right arguments" do + @provider.expects(:execute).with() { |cmds, args| + cmds.include?("read") and + cmds.include?(@authname) and + args[:combine] == false + }.once + + @provider.expects(:execute).with() { |cmds, args| + cmds.include?("write") and + cmds.include?(@authname) and + args[:combine] == false and + args[:stdinfile] != nil + }.once + @provider.flush + end + + end + + describe "when flushing a rule" do + before :each do + @resource.stubs(:[]).with(:auth_type).returns(:rule) + end + + it "should call the internal method flush_rule" do + @provider.expects("flush_rule") + @provider.flush + end + + it "should call the internal method set_rule" do + @provider.expects("set_rule") + @provider.flush + end + end + + + +end \ No newline at end of file diff --git a/spec/unit/type/macauthorization.rb b/spec/unit/type/macauthorization.rb new file mode 100644 index 000000000..a27841c82 --- /dev/null +++ b/spec/unit/type/macauthorization.rb @@ -0,0 +1,80 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +macauth_type = Puppet::Type.type(:macauthorization) + + +describe macauth_type, "when validating attributes" do + + parameters = [:name,] + properties = [:auth_type, :allow_root, :authenticate_user, :auth_class, + :comment, :group, :k_of_n, :mechanisms, :rule, + :session_owner, :shared, :timeout, :tries] + + parameters.each do |parameter| + it "should have a %s parameter" % parameter do + macauth_type.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) + end + + it "should have documentation for its %s parameter" % parameter do + macauth_type.attrclass(parameter).doc.should be_instance_of(String) + end + end + + properties.each do |property| + it "should have a %s property" % property do + macauth_type.attrclass(property).ancestors.should be_include(Puppet::Property) + end + + it "should have documentation for its %s property" % property do + macauth_type.attrclass(property).doc.should be_instance_of(String) + end + end + +end + +describe macauth_type, "when validating properties" do + + before do + @provider = stub 'provider' + @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil + end + + after do + macauth_type.clear + end + + it "should have a default provider inheriting from Puppet::Provider" do + macauth_type.defaultprovider.ancestors.should be_include(Puppet::Provider) + end + + it "should be able to create a instance" do + macauth_type.create(:name => "foo").should_not be_nil + end + + it "should be able to create an instance" do + lambda { + macauth_type.create(:name => 'foo') + }.should_not raise_error + end + + it "should support :present as a value to :ensure" do + lambda { + macauth_type.create(:name => "foo", :ensure => :present) + }.should_not raise_error + end + + it "should support :absent as a value to :ensure" do + lambda { + macauth_type.create(:name => "foo", :ensure => :absent) + }.should_not raise_error + end + +end + +describe "instances" do + it "should have a valid provider" do + macauth_type.create(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider) + end +end \ No newline at end of file -- cgit From b22303e31654b44c300c713426d7f16ef37f4210 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Sun, 7 Dec 2008 11:32:51 +0100 Subject: Fix rake abort when there is a matching confine Signed-off-by: Brice Figureau --- test/lib/puppettest/runnable_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/puppettest/runnable_test.rb b/test/lib/puppettest/runnable_test.rb index 6dab1b743..977dba47a 100644 --- a/test/lib/puppettest/runnable_test.rb +++ b/test/lib/puppettest/runnable_test.rb @@ -17,10 +17,10 @@ module PuppetTest # Evaluate all of our tests to see if any of them are false # and thus whether this test is considered not runnable. def runnable? + @messages ||= [] if superclass.respond_to?(:runnable?) and ! superclass.runnable? return false end - @messages ||= [] return false unless @messages.empty? return true unless defined? @confines @confines.find_all do |message, result| -- cgit From 18fe5c3ac2ad4c42afd30ba2effad28607fe746d Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Sun, 7 Dec 2008 18:04:14 -0600 Subject: Fixing #1750 again - All of the properties and now :ensure check replace? Signed-off-by: Luke Kanies --- lib/puppet/type/file/ensure.rb | 4 ++++ spec/unit/type/file/ensure.rb | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100755 spec/unit/type/file/ensure.rb diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb index 3a1a824bd..175b821b3 100755 --- a/lib/puppet/type/file/ensure.rb +++ b/lib/puppet/type/file/ensure.rb @@ -137,6 +137,10 @@ module Puppet # We have to treat :present specially, because it works with any # type of file. def insync?(currentvalue) + unless currentvalue == :absent or resource.replace? + return true + end + if self.should == :present if currentvalue.nil? or currentvalue == :absent return false diff --git a/spec/unit/type/file/ensure.rb b/spec/unit/type/file/ensure.rb new file mode 100755 index 000000000..b336c7c7a --- /dev/null +++ b/spec/unit/type/file/ensure.rb @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby + +Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } + +property = Puppet::Type.type(:file).attrclass(:ensure) + +describe property do + before do + @resource = stub 'resource', :line => "foo", :file => "bar", :replace? => true + @resource.stubs(:[]).returns "foo" + @resource.stubs(:[]).with(:path).returns "/my/file" + @ensure = property.new :resource => @resource + end + + describe "when testing whether in sync" do + it "should always be in sync if replace is 'false' unless the file is missing" do + @resource.expects(:replace?).returns false + @ensure.insync?(:link).should be_true + end + end +end -- cgit From 6075d10373dbdb7de1f665cc39453daa6418cffd Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Sun, 7 Dec 2008 17:04:14 -0600 Subject: Fixing #1794 - returning sync when it is already initialized Signed-off-by: Luke Kanies --- lib/puppet/reports/tagmail.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb index fa4e536e1..00571a8be 100644 --- a/lib/puppet/reports/tagmail.rb +++ b/lib/puppet/reports/tagmail.rb @@ -181,6 +181,7 @@ Puppet::Reports.register_report(:tagmail) do unless defined?(@sync) @sync = Sync.new end + @sync end end -- cgit From 8616d74b47ac9177a3f29f1ebf63902bdefb3275 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 8 Dec 2008 00:00:17 -0600 Subject: Fixing #1800 - tidy now correctly ignores missing files and directories Signed-off-by: Luke Kanies --- lib/puppet/type/tidy.rb | 9 ++++++++- spec/unit/type/tidy.rb | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb index e37da5ef8..b4df4a9a2 100755 --- a/lib/puppet/type/tidy.rb +++ b/lib/puppet/type/tidy.rb @@ -44,7 +44,14 @@ module Puppet end def insync?(is) - if File.lstat(resource[:path]).ftype == "directory" and ! @resource[:rmdirs] + begin + stat = File.lstat(resource[:path]) + rescue Errno::ENOENT + info "Tidy target does not exist; ignoring" + return true + end + + if stat.ftype == "directory" and ! @resource[:rmdirs] self.debug "Not tidying directories" return true end diff --git a/spec/unit/type/tidy.rb b/spec/unit/type/tidy.rb index ee820d4aa..9bcae86d7 100755 --- a/spec/unit/type/tidy.rb +++ b/spec/unit/type/tidy.rb @@ -6,6 +6,14 @@ tidy = Puppet::Type.type(:tidy) describe tidy do after { tidy.clear } + + it "should be in sync if the targeted file does not exist" do + File.expects(:lstat).with("/tmp/foonesslaters").raises Errno::ENOENT + @tidy = tidy.create :path => "/tmp/foonesslaters", :age => "100d" + + @tidy.property(:ensure).must be_insync({}) + end + [:ensure, :age, :size].each do |property| it "should have a %s property" % property do tidy.attrclass(property).ancestors.should be_include(Puppet::Property) -- cgit From 7e2da7eeb25bb8879af40f12c4a04047a159374e Mon Sep 17 00:00:00 2001 From: Andrew Shafer Date: Sun, 7 Dec 2008 22:41:45 -0700 Subject: Refactor #1802 Use 'zfs get -H -o value' instead of parsing output for value just simplifying code --- lib/puppet/provider/zfs/solaris.rb | 13 +------------ spec/unit/provider/zfs/solaris.rb | 4 ++-- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/lib/puppet/provider/zfs/solaris.rb b/lib/puppet/provider/zfs/solaris.rb index 4d382cfad..256e4e9b4 100644 --- a/lib/puppet/provider/zfs/solaris.rb +++ b/lib/puppet/provider/zfs/solaris.rb @@ -15,14 +15,6 @@ Puppet::Type.type(:zfs).provide(:solaris) do properties end - def arrayify_second_line_on_whitespace(text) - if second_line = text.split("\n")[1] - second_line.split("\s") - else - [] - end - end - def create zfs *([:create] + add_properties + [@resource[:name]]) end @@ -41,10 +33,7 @@ Puppet::Type.type(:zfs).provide(:solaris) do [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |field| define_method(field) do - #special knowledge of format - #the command returns values in this format with the header - #NAME PROPERTY VALUE SOURCE - arrayify_second_line_on_whitespace(zfs(:get, field, @resource[:name]))[2] + zfs(:get, "-H", "-o", "value", field, @resource[:name]).strip end define_method(field.to_s + "=") do |should| diff --git a/spec/unit/provider/zfs/solaris.rb b/spec/unit/provider/zfs/solaris.rb index 63aefcdc4..9189e44f0 100755 --- a/spec/unit/provider/zfs/solaris.rb +++ b/spec/unit/provider/zfs/solaris.rb @@ -66,12 +66,12 @@ describe provider_class do [:mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir].each do |prop| describe "when getting the #{prop} value" do it "should call zfs with :get, #{prop} and this zfs" do - @provider.expects(:zfs).with(:get, prop, @resource[:name]).returns("NAME PROPERTY VALUE SOURCE\nmyzfs name value blah") + @provider.expects(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n") @provider.send(prop) end it "should get the third value of the second line from the output" do - @provider.stubs(:zfs).with(:get, prop, @resource[:name]).returns("NAME PROPERTY VALUE SOURCE\nmyzfs name value blah") + @provider.stubs(:zfs).with(:get, "-H", "-o", "value", prop, @resource[:name]).returns("value\n") @provider.send(prop).should == "value" end end -- cgit From 68ffd46c9fd87e07d0171e7daa54b951f621c7b7 Mon Sep 17 00:00:00 2001 From: Andrew Shafer Date: Mon, 8 Dec 2008 00:09:50 -0700 Subject: Bug #1803 Zfs should auto require the ancestor file systems --- lib/puppet/type/zfs.rb | 6 ++++++ spec/unit/type/zfs.rb | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/lib/puppet/type/zfs.rb b/lib/puppet/type/zfs.rb index d3af3a461..3a8806a5e 100755 --- a/lib/puppet/type/zfs.rb +++ b/lib/puppet/type/zfs.rb @@ -40,6 +40,12 @@ module Puppet #strip the zpool off the zfs name and autorequire it [@parameters[:name].value.split('/')[0]] end + + autorequire(:zfs) do + #slice and dice, we want all the zfs before this one + names = @parameters[:name].value.split('/') + names.slice(1..-2).inject([]) { |a,v| a << "#{a.last}/#{v}" }.collect { |fs| names[0] + fs } + end end end diff --git a/spec/unit/type/zfs.rb b/spec/unit/type/zfs.rb index 434415e24..bce6500b1 100755 --- a/spec/unit/type/zfs.rb +++ b/spec/unit/type/zfs.rb @@ -25,4 +25,21 @@ describe zpool do zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) end end + + it "should autorequire the containing zfss and the zpool" do + #this is a little funky because the autorequire depends on a property with a feature + foo_pool = Puppet.type(:zpool).create(:name => "foo") + + foo_bar_zfs = Puppet.type(:zfs).create(:name => "foo/bar") + foo_bar_baz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz") + foo_bar_baz_buz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz/buz") + + config = Puppet::Node::Catalog.new :testing do |conf| + [foo_pool, foo_bar_zfs, foo_bar_baz_zfs, foo_bar_baz_buz_zfs].each { |resource| conf.add_resource resource } + end + + req = foo_bar_baz_buz_zfs.autorequire.collect { |edge| edge.source.ref } + + [foo_pool.ref, foo_bar_zfs.ref, foo_bar_baz_zfs.ref].each { |ref| req.include?(ref).should == true } + end end -- cgit From a0a6d2cfa88cac5418097fb9f71df4cbcae4b192 Mon Sep 17 00:00:00 2001 From: John Ferlito Date: Tue, 9 Dec 2008 11:46:21 +1100 Subject: Add a unique name to objects so we can determine uniqueness when read back in The nagios object definitions have been updated to correlate with Nagios 3.0.6. In Nagios it is possible to have multiple service checks with the same service_description. eg I could have an check with a service_description of 'SSH' for multiple hosts. So in puppet we can't use it as a unique name for the resource. This patch modifies the code to use $name as the unique name. For some types eg command_name $name ends up in the config and thus we can tell which puppet resources match to which nagios ones. For other types like service there is no direct mapping from $name to a nagios attibute. So we use a custom attribute called _naginator_name. Signed-off-by: John Ferlito --- CHANGELOG | 4 + lib/puppet/external/nagios/base.rb | 184 ++++++++++++++++---------- lib/puppet/type/nagios_hostgroupescalation.rb | 3 - 3 files changed, 117 insertions(+), 74 deletions(-) delete mode 100644 lib/puppet/type/nagios_hostgroupescalation.rb diff --git a/CHANGELOG b/CHANGELOG index d75b5bf85..cdff75c74 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,8 @@ 0.24.x + Fixed #1496 - nagios_servicedependency needs a unique host_name? + + Fixed #1420 - nagios_serviceescalation not allowing host_name more than one type + Fixed #1695 - Solaris 10 zone provider doesn't properly handle unknown zone attributes in newer releases Fixed #1776 - Trivial fix for gentoo service provider diff --git a/lib/puppet/external/nagios/base.rb b/lib/puppet/external/nagios/base.rb index 25c689559..9b9d7ca34 100755 --- a/lib/puppet/external/nagios/base.rb +++ b/lib/puppet/external/nagios/base.rb @@ -196,6 +196,9 @@ class Nagios::Base args.each { |param,value| self[param] = value } + if @namevar == :_naginator_name + self['_naginator_name'] = self['name'] + end end # Handle parameters like attributes. @@ -321,115 +324,154 @@ class Nagios::Base end # object types - newtype :command do - setparameters :command_name, :command_line + newtype :host do + setparameters :host_name, :alias, :display_name, :address, :parents, + :hostgroups, :check_command, :initial_state, :max_check_attempts, + :check_interval, :retry_interval, :active_checks_enabled, + :passive_checks_enabled, :check_period, :obsess_over_host, + :check_freshness, :freshness_threshold, :event_handler, + :event_handler_enabled, :low_flap_threshold, :high_flap_threshold, + :flap_detection_enabled, :flap_detection_options, + :failure_prediction_enabled, :process_perf_data, + :retain_status_information, :retain_nonstatus_information, :contacts, + :contact_groups, :notification_interval, :first_notification_delay, + :notification_period, :notification_options, :notifications_enabled, + :stalking_options, :notes, :notes_url, :action_url, :icon_image, + :icon_image_alt, :vrml_image, :statusmap_image, "2d_coords".intern, + "3d_coords".intern, + :register, :use + + setsuperior "person" + map :address => "ipHostNumber" end - newtype :contact do - setparameters :contact_name, :alias, :host_notification_period, - :host_notification_commands, :service_notification_period, - :service_notification_commands, :register, :email, :pager, - :service_notification_options, :host_notification_options + newtype :hostgroup do + setparameters :hostgroup_name, :alias, :members, :hostgroup_members, :notes, + :notes_url, :action_url, + :register, :use + end - setsuperior "person" + newtype :service do + attach :host => :host_name + setparameters :host_name, :hostgroup_name, :service_description, + :display_name, :servicegroups, :is_volatile, :check_command, + :initial_state, :max_check_attempts, :check_interval, :retry_interval, + :normal_check_interval, :retry_check_interval, :active_checks_enabled, + :passive_checks_enabled, :parallelize_check, :check_period, + :obsess_over_service, :check_freshness, :freshness_threshold, + :event_handler, :event_handler_enabled, :low_flap_threshold, + :high_flap_threshold, :flap_detection_enabled,:flap_detection_options, + :process_perf_data, :failure_prediction_enabled, :retain_status_information, + :retain_nonstatus_information, :notification_interval, + :first_notification_delay, :notification_period, :notification_options, + :notifications_enabled, :contacts, :contact_groups, :stalking_options, + :notes, :notes_url, :action_url, :icon_image, :icon_image_alt, + :register, :use, + :_naginator_name + + suppress :host_name + + setnamevar :_naginator_name end - newtype :contactgroup do - setparameters :contactgroup_name, :alias, :members + newtype :servicegroup do + setparameters :servicegroup_name, :alias, :members, :servicegroup_members, + :notes, :notes_url, :action_url, + :register, :use end - newtype :host do - setparameters :host_name, :notifications_enabled, :event_handler_enabled, - :flap_detection_enabled, :process_perf_data, :retain_status_information, - :retain_nonstatus_information, :register, :use, :alias, - :address, :check_command, :max_check_attempts, :notification_interval, - :notification_period, :notification_options, :checks_enabled, - :failure_prediction_enabled, :parents, :contact_groups + newtype :contact do + setparameters :contact_name, :alias, :contactgroups, + :host_notifications_enabled, :service_notifications_enabled, + :host_notification_period, :service_notification_period, + :host_notification_options, :service_notification_options, + :host_notification_commands, :service_notification_commands, + :email, :pager, :address1, :address2, :address3, :address4, + :address5, :address6, :can_submit_commands, :retain_status_information, + :retain_nonstatus_information, + :register, :use setsuperior "person" - map :address => "ipHostNumber" end - newtype :hostextinfo do - auxiliary = true - setparameters :host_name, :notes_url, :icon_image, :icon_image_alt, :vrml_image, - "2d_coords".intern, "3d_coords".intern - - setnamevar :host_name + newtype :contactgroup do + setparameters :contactgroup_name, :alias, :members, :contactgroup_members, + :register, :use end - newtype :hostgroup do - setparameters :hostgroup_name, :alias, :contact_groups, :members + # TODO - We should support generic time periods here eg "day 1 - 15" + newtype :timeperiod do + setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday, + :wednesday, :thursday, :friday, :saturday, :exclude, + :register, :use end - newtype :hostescalation do - setparameters :name, :first_notification, :last_notification, - :notification_interval, :contact_groups, - :escalation_options, :register, :hostgroup_name - setnamevar :name - end + newtype :command do + setparameters :command_name, :command_line + end - newtype :hostgroupescalation do + newtype :servicedependency do auxiliary = true - setparameters :hostgroup_name, :first_notification, :last_notification, - :contact_groups, :notification_interval + setparameters :dependent_host_name, :dependent_hostgroup_name, + :dependent_service_description, :host_name, :hostgroup_name, + :service_description, :inherits_parent, :execution_failure_criteria, + :notification_failure_criteria, :dependency_period, + :register, :use, + :_naginator_name - setnamevar :hostgroup_name + setnamevar :_naginator_name end - newtype :service do - attach :host => :host_name - setparameters :name, :active_checks_enabled, :passive_checks_enabled, - :parallelize_check, :obsess_over_service, :check_freshness, - :notifications_enabled, :event_handler_enabled, - :flap_detection_enabled, :process_perf_data, - :retain_status_information, :retain_nonstatus_information, :register, - :is_volatile, :check_period, :max_check_attempts, - :normal_check_interval, :retry_check_interval, :contact_groups, - :notification_interval, :notification_period, :notification_options, - :service_description, :host_name, :freshness_threshold, - :check_command, :hostgroup_name, :event_handler, :servicegroups, :host - - suppress :host_name + newtype :serviceescalation do + setparameters :host_name, :hostgroup_name, :service_description, :contacts, + :contact_groups, :first_notification, :last_notification, + :notification_interval, :escalation_period, :escalation_options, + :register, :use, + :_naginator_name - setnamevar :service_description + setnamevar :_naginator_name end - newtype :servicedependency do - auxiliary = true - setparameters :host_name, :service_description, :dependent_host_name, - :dependent_service_description, :execution_failure_criteria, - :notification_failure_criteria, :hostgroup_name, - :dependent_hostgroup_name + newtype :hostdependency do + auxiliary = true + setparameters :dependent_host_name, :dependent_hostgroup_name, :host_name, + :hostgroup_name, :inherits_parent, :execution_failure_criteria, + :notification_failure_criteria, :dependency_period, + :register, :use - setnamevar :host_name + setnamevar :_naginator_name end - newtype :serviceescalation do - setparameters :host_name, :service_description, :first_notification, - :last_notification, :contact_groups, :notification_interval, :hostgroup_name + newtype :hostescalation do + setparameters :host_name, :hostgroup_name, :contacts, :contact_groups, + :first_notification, :last_notification, :notification_interval, + :escalation_period, :escalation_options, + :register, :use, + :_naginator_name - setnamevar :host_name + setnamevar :_naginator_name end - newtype :servicegroup do - setparameters :servicegroup_name, :alias + newtype :hostextinfo do + auxiliary = true + setparameters :host_name, :notes, :notes_url, :icon_image, :icon_image_alt, + :vrml_image, :statusmap_image, "2d_coords".intern, "3d_coords".intern, + :register, :use - setnamevar :servicegroup_name + setnamevar :host_name end newtype :serviceextinfo do auxiliary = true - setparameters :host_name, :service_description, :icon_image, :icon_image_alt + setparameters :host_name, :service_description, :notes, :notes_url, + :action_url, :icon_image, :icon_image_alt, + :register, :use, + :_naginator_name - setnamevar :host_name + setnamevar :_naginator_name end - newtype :timeperiod do - setparameters :timeperiod_name, :alias, :sunday, :monday, :tuesday, - :wednesday, :thursday, :friday, :saturday - end end # $Id$ diff --git a/lib/puppet/type/nagios_hostgroupescalation.rb b/lib/puppet/type/nagios_hostgroupescalation.rb deleted file mode 100644 index 21b39f681..000000000 --- a/lib/puppet/type/nagios_hostgroupescalation.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'puppet/util/nagios_maker' - -Puppet::Util::NagiosMaker.create_nagios_type :hostgroupescalation -- cgit From 50ac03a2a404faa60fe0774a608397b3e4448b9b Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Tue, 9 Dec 2008 14:18:31 +1100 Subject: CHANGELOG updates --- CHANGELOG | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Rakefile | 3 +-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index cdff75c74..4daa9f524 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,46 @@ -0.24.x +0.24.7 + Bug #1803 Zfs should auto require the ancestor file systems + + Refactor #1802 Use 'zfs get -H -o value' instead of parsing output for value + + Fixing #1800 - tidy now correctly ignores missing files and directories + + Fixing #1794 - returning sync when it is already initialized + + Fixing #1750 again - All of the properties and now :ensure check replace? + + Deprecate the NetInfo nameservice provider. Use directoryservice instead + + Add macauthorization type + + Fixing #1703 - using a mutex around the sending of the tagmails + + Fix #1788 - allow rspec rake to run only some tests + + Fixing the AST constant warnings, using a variable instead of a constant + + Feature #1696 Add support for branded zones + + Feature #1783 - Add ZFS support + + type/mcx.rb Feature #1026 - MCX Type + + Fixing #1749 - Splay now hopefully behaves "better" for small values + + Fix #1741 - Add inline_template function + + Slight denormalisation to store a host's environment as a first class + + Added Rake :ci namespace and CI tasks + + Refactoring the thread-safety in Puppet::Util + + Removing the included testing gems; you must now install them yourself + + Refactoring of SELinux functions to use native Ruby SELinux interface + + Removing all mention of EPM, RPM, or Sun packages. + Fixed #1496 - nagios_servicedependency needs a unique host_name? Fixed #1420 - nagios_serviceescalation not allowing host_name more than one type @@ -7,8 +49,6 @@ Fixed #1776 - Trivial fix for gentoo service provider - Added Rake :ci namespace and CI tasks - Fixed #1767 - Minor fix to emacs mode Fixed #1711 - fileserver test fails due to incorrect mocking @@ -60,6 +100,13 @@ Removed conf/debian directory - Debian packaging information now maintained downstream + Added augeas type + + Added support for @doc type and manifest documentation support - see: + http://reductivelabs.com/trac/puppet/wiki/PuppetManifestDocumentation + + Added multiline comment support + 0.24.6 Adding support to the user type for: profiles, auths, project, key/value pairs (extension to Solaris RBAC support added in diff --git a/Rakefile b/Rakefile index 7175c3eb8..21d7651d4 100644 --- a/Rakefile +++ b/Rakefile @@ -217,10 +217,9 @@ end mkdir(CHANGELOG_DIR) unless File.directory?(CHANGELOG_DIR) change_body=`git log --pretty=format:'%aD%n%an <%ae>%n%s%n'` - version = version + "\n" File.open(File.join(CHANGELOG_DIR, "CHANGELOG.git"), 'w') do |f| - f << version << change_body + f << change_body end # Changelog commit -- cgit From 544a3e1ecbbb59170c72c649b281a54fd3b41f14 Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Sun, 7 Dec 2008 15:44:23 -0800 Subject: remove unnecessary mk_resource_methods call --- lib/puppet/provider/macauthorization/macauthorization.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index d29c1d294..67e4e06bd 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -34,8 +34,6 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe :auth_class => "class", :k_of_n => "k-of-n", :session_owner => "session-owner", } - - mk_resource_methods class << self attr_accessor :parsed_auth_db -- cgit From 4b2bdf981431b11b6c9829d3c2d81abe0f1c71ba Mon Sep 17 00:00:00 2001 From: Nigel Kersten Date: Mon, 8 Dec 2008 18:37:27 -0800 Subject: Fix the spec tests to work on other platforms, do the confine around OS X versions more sanely --- .../provider/macauthorization/macauthorization.rb | 13 ++- lib/rake | 1 - spec/unit/provider/macauthorization.rb | 40 +++---- spec/unit/type/macauthorization.rb | 120 ++++++++++----------- 4 files changed, 85 insertions(+), 89 deletions(-) delete mode 120000 lib/rake mode change 100644 => 100755 spec/unit/provider/macauthorization.rb mode change 100644 => 100755 spec/unit/type/macauthorization.rb diff --git a/lib/puppet/provider/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb index 67e4e06bd..2cdef6c12 100644 --- a/lib/puppet/provider/macauthorization/macauthorization.rb +++ b/lib/puppet/provider/macauthorization/macauthorization.rb @@ -12,10 +12,15 @@ Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppe confine :operatingsystem => :darwin - product_version = sw_vers "-productVersion" - - confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version) - true + # This should be confined based on macosx_productversion once + # http://projects.reductivelabs.com/issues/show/1796 + # is resolved. + if FileTest.exists?("/usr/bin/sw_vers") + product_version = sw_vers "-productVersion" + + confine :true => if /^10.5/.match(product_version) or /^10.6/.match(product_version) + true + end end defaultfor :operatingsystem => :darwin diff --git a/lib/rake b/lib/rake deleted file mode 120000 index 0ac8c7681..000000000 --- a/lib/rake +++ /dev/null @@ -1 +0,0 @@ -/Qualia/Repos/github/reductive-build/lib/rake \ No newline at end of file diff --git a/spec/unit/provider/macauthorization.rb b/spec/unit/provider/macauthorization.rb old mode 100644 new mode 100755 index 4754b11c7..8c9636f16 --- a/spec/unit/provider/macauthorization.rb +++ b/spec/unit/provider/macauthorization.rb @@ -16,31 +16,27 @@ describe provider_class do # Create a mock resource @resource = stub 'resource' - @provider = provider_class.new(@resource) - @authname = "foo.spam.eggs.puppettest" @authplist = {} @rules = {@authname => @authplist} - @authdb = {} - @authdb["rules"] = @rules + + authdb = {} + authdb["rules"] = { "foorule" => "foo" } + authdb["rights"] = { "fooright" => "foo" } + + # Stub out Plist::parse_xml + Plist.stubs(:parse_xml).returns(authdb) # A catch all; no parameters set @resource.stubs(:[]).returns(nil) # But set name, ensure @resource.stubs(:[]).with(:name).returns @authname - @resource.stubs(:[]).with(:ensure).returns :present - @resource.stubs(:ref).returns "MacAuthorization[#{@authname}]" - # stub out the provider methods that actually touch the filesystem - # or execute commands - @provider.stubs(:populate_rules_rights).returns("") - - # Stub out Plist::parse_xml - Plist.stubs("parse_xml").returns(@authdb) + @provider = provider_class.new(@resource) end it "should have a create method" do @@ -60,9 +56,9 @@ describe provider_class do end properties = [ :allow_root, :authenticate_user, :auth_class, :comment, - :group, :k_of_n, :mechanisms, :rule, :session_owner, - :shared, :timeout, :tries, :auth_type ] - + :group, :k_of_n, :mechanisms, :rule, :session_owner, + :shared, :timeout, :tries, :auth_type ] + properties.each do |prop| it "should have a #{prop.to_s} method" do @provider.should respond_to(prop.to_s) @@ -79,7 +75,7 @@ describe provider_class do end it "should call the internal method destroy_right" do - @provider.expects("destroy_right") + @provider.expects(:destroy_right) @provider.destroy end it "should call the external command 'security authorizationdb remove @authname" do @@ -94,7 +90,7 @@ describe provider_class do end it "should call the internal method destroy_rule" do - @provider.expects("destroy_rule") + @provider.expects(:destroy_rule) @provider.destroy end end @@ -105,12 +101,12 @@ describe provider_class do end it "should call the internal method flush_right" do - @provider.expects("flush_right") + @provider.expects(:flush_right) @provider.flush end it "should call the internal method set_right" do - @provider.expects("set_right") + @provider.expects(:set_right) @provider.flush end @@ -138,16 +134,14 @@ describe provider_class do end it "should call the internal method flush_rule" do - @provider.expects("flush_rule") + @provider.expects(:flush_rule) @provider.flush end it "should call the internal method set_rule" do - @provider.expects("set_rule") + @provider.expects(:set_rule) @provider.flush end end - - end \ No newline at end of file diff --git a/spec/unit/type/macauthorization.rb b/spec/unit/type/macauthorization.rb old mode 100644 new mode 100755 index a27841c82..1c7f122b8 --- a/spec/unit/type/macauthorization.rb +++ b/spec/unit/type/macauthorization.rb @@ -4,77 +4,75 @@ require File.dirname(__FILE__) + '/../../spec_helper' macauth_type = Puppet::Type.type(:macauthorization) - -describe macauth_type, "when validating attributes" do - - parameters = [:name,] - properties = [:auth_type, :allow_root, :authenticate_user, :auth_class, - :comment, :group, :k_of_n, :mechanisms, :rule, - :session_owner, :shared, :timeout, :tries] - - parameters.each do |parameter| - it "should have a %s parameter" % parameter do - macauth_type.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) - end - - it "should have documentation for its %s parameter" % parameter do - macauth_type.attrclass(parameter).doc.should be_instance_of(String) - end - end - - properties.each do |property| - it "should have a %s property" % property do - macauth_type.attrclass(property).ancestors.should be_include(Puppet::Property) - end - - it "should have documentation for its %s property" % property do - macauth_type.attrclass(property).doc.should be_instance_of(String) - end - end - -end - -describe macauth_type, "when validating properties" do +describe Puppet.type(:macauthorization), "when checking macauthorization objects" do before do - @provider = stub 'provider' - @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil + authplist = {} + authplist["rules"] = { "foorule" => "foo" } + authplist["rights"] = { "fooright" => "foo" } + provider_class = macauth_type.provider(macauth_type.providers[0]) + Plist.stubs(:parse_xml).with("/etc/authorization").returns(authplist) + macauth_type.stubs(:defaultprovider).returns provider_class end after do macauth_type.clear end + - it "should have a default provider inheriting from Puppet::Provider" do - macauth_type.defaultprovider.ancestors.should be_include(Puppet::Provider) - end - - it "should be able to create a instance" do - macauth_type.create(:name => "foo").should_not be_nil - end + describe "when validating attributes" do + + parameters = [:name,] + properties = [:auth_type, :allow_root, :authenticate_user, :auth_class, + :comment, :group, :k_of_n, :mechanisms, :rule, + :session_owner, :shared, :timeout, :tries] + + parameters.each do |parameter| + it "should have a %s parameter" % parameter do + macauth_type.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) + end + + it "should have documentation for its %s parameter" % parameter do + macauth_type.attrclass(parameter).doc.should be_instance_of(String) + end + end + + properties.each do |property| + it "should have a %s property" % property do + macauth_type.attrclass(property).ancestors.should be_include(Puppet::Property) + end + + it "should have documentation for its %s property" % property do + macauth_type.attrclass(property).doc.should be_instance_of(String) + end + end - it "should be able to create an instance" do - lambda { - macauth_type.create(:name => 'foo') - }.should_not raise_error - end - - it "should support :present as a value to :ensure" do - lambda { - macauth_type.create(:name => "foo", :ensure => :present) - }.should_not raise_error end - - it "should support :absent as a value to :ensure" do - lambda { - macauth_type.create(:name => "foo", :ensure => :absent) - }.should_not raise_error + + describe "when validating properties" do + + it "should have a default provider inheriting from Puppet::Provider" do + macauth_type.defaultprovider.ancestors.should be_include(Puppet::Provider) + end + + it "should be able to create an instance" do + lambda { + macauth_type.create(:name => 'foo') + }.should_not raise_error + end + + it "should support :present as a value to :ensure" do + lambda { + macauth_type.create(:name => "foo", :ensure => :present) + }.should_not raise_error + end + + it "should support :absent as a value to :ensure" do + lambda { + macauth_type.create(:name => "foo", :ensure => :absent) + }.should_not raise_error + end + end -end - -describe "instances" do - it "should have a valid provider" do - macauth_type.create(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider) - end end \ No newline at end of file -- cgit From 4418b3436e96b6aa8d2310fe87e315533ed53415 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Tue, 9 Dec 2008 14:28:35 +1100 Subject: Fix launchd service test on non-OSX platforms --- spec/unit/provider/service/launchd.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/provider/service/launchd.rb b/spec/unit/provider/service/launchd.rb index 9650ea423..cc2dae190 100755 --- a/spec/unit/provider/service/launchd.rb +++ b/spec/unit/provider/service/launchd.rb @@ -62,7 +62,7 @@ describe provider_class do describe "when checking status" do it "should call the external command 'launchctl list' once" do - @provider.expects("launchctl").with(:list, @resource[:name]).returns(:running).once + @provider.expects(:launchctl).with(:list, @resource[:name]).returns(:running).once @provider.status end end -- cgit From da71ad53cc49b9a8c56785d865c47bb282e467b6 Mon Sep 17 00:00:00 2001 From: John Ferlito Date: Tue, 9 Dec 2008 11:46:21 +1100 Subject: Add a unique name to objects so we can determine uniqueness when read back in The nagios object definitions have been updated to correlate with Nagios 3.0.6. In Nagios it is possible to have multiple service checks with the same service_description. eg I could have an check with a service_description of 'SSH' for multiple hosts. So in puppet we can't use it as a unique name for the resource. This patch modifies the code to use $name as the unique name. For some types eg command_name $name ends up in the config and thus we can tell which puppet resources match to which nagios ones. For other types like service there is no direct mapping from $name to a nagios attibute. So we use a custom attribute called _naginator_name. Signed-off-by: John Ferlito --- CHANGELOG | 4 ++++ lib/puppet/external/nagios/base.rb | 3 ++- lib/puppet/type/nagios_hostdependency.rb | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 lib/puppet/type/nagios_hostdependency.rb diff --git a/CHANGELOG b/CHANGELOG index 4daa9f524..d6596627b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,8 @@ 0.24.7 + Fixed #1496 - nagios_servicedependency needs a unique host_name? + + Fixed #1420 - nagios_serviceescalation not allowing host_name more than one type + Bug #1803 Zfs should auto require the ancestor file systems Refactor #1802 Use 'zfs get -H -o value' instead of parsing output for value diff --git a/lib/puppet/external/nagios/base.rb b/lib/puppet/external/nagios/base.rb index 9b9d7ca34..6a0c1831c 100755 --- a/lib/puppet/external/nagios/base.rb +++ b/lib/puppet/external/nagios/base.rb @@ -437,7 +437,8 @@ class Nagios::Base setparameters :dependent_host_name, :dependent_hostgroup_name, :host_name, :hostgroup_name, :inherits_parent, :execution_failure_criteria, :notification_failure_criteria, :dependency_period, - :register, :use + :register, :use, + :_naginator_name setnamevar :_naginator_name end diff --git a/lib/puppet/type/nagios_hostdependency.rb b/lib/puppet/type/nagios_hostdependency.rb new file mode 100644 index 000000000..fea71a619 --- /dev/null +++ b/lib/puppet/type/nagios_hostdependency.rb @@ -0,0 +1,3 @@ +require 'puppet/util/nagios_maker' + +Puppet::Util::NagiosMaker.create_nagios_type :hostdependency -- cgit From e5c36fd865a5699c867e68a23153ec40da919e33 Mon Sep 17 00:00:00 2001 From: Andrew Shafer Date: Mon, 8 Dec 2008 23:20:43 -0700 Subject: Fix ZFS autorequire test Couldn't find a default provider because the world is not my laptop --- spec/unit/type/zfs.rb | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/spec/unit/type/zfs.rb b/spec/unit/type/zfs.rb index bce6500b1..08d6e0747 100755 --- a/spec/unit/type/zfs.rb +++ b/spec/unit/type/zfs.rb @@ -2,19 +2,14 @@ Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } -zpool = Puppet::Type.type(:zfs) - -describe zpool do - before do - @provider = stub 'provider' - @resource = stub 'resource', :resource => nil, :provider => @provider, :line => nil, :file => nil - end +zfs = Puppet::Type.type(:zfs) +describe zfs do properties = [:ensure, :mountpoint, :compression, :copies, :quota, :reservation, :sharenfs, :snapdir] properties.each do |property| it "should have a %s property" % property do - zpool.attrclass(property).ancestors.should be_include(Puppet::Property) + zfs.attrclass(property).ancestors.should be_include(Puppet::Property) end end @@ -22,24 +17,29 @@ describe zpool do parameters.each do |parameter| it "should have a %s parameter" % parameter do - zpool.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) + zfs.attrclass(parameter).ancestors.should be_include(Puppet::Parameter) end end it "should autorequire the containing zfss and the zpool" do - #this is a little funky because the autorequire depends on a property with a feature - foo_pool = Puppet.type(:zpool).create(:name => "foo") + provider = mock "provider" + provider.stubs(:name).returns(:solaris) + zfs.stubs(:defaultprovider).returns(provider) + Puppet.type(:zpool).stubs(:defaultprovider).returns(provider) + - foo_bar_zfs = Puppet.type(:zfs).create(:name => "foo/bar") - foo_bar_baz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz") - foo_bar_baz_buz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz/buz") + foo_pool = Puppet.type(:zpool).create(:name => "foo") - config = Puppet::Node::Catalog.new :testing do |conf| - [foo_pool, foo_bar_zfs, foo_bar_baz_zfs, foo_bar_baz_buz_zfs].each { |resource| conf.add_resource resource } - end + foo_bar_zfs = Puppet.type(:zfs).create(:name => "foo/bar") + foo_bar_baz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz") + foo_bar_baz_buz_zfs = Puppet.type(:zfs).create(:name => "foo/bar/baz/buz") + + config = Puppet::Node::Catalog.new :testing do |conf| + [foo_pool, foo_bar_zfs, foo_bar_baz_zfs, foo_bar_baz_buz_zfs].each { |resource| conf.add_resource resource } + end - req = foo_bar_baz_buz_zfs.autorequire.collect { |edge| edge.source.ref } + req = foo_bar_baz_buz_zfs.autorequire.collect { |edge| edge.source.ref } - [foo_pool.ref, foo_bar_zfs.ref, foo_bar_baz_zfs.ref].each { |ref| req.include?(ref).should == true } + [foo_pool.ref, foo_bar_zfs.ref, foo_bar_baz_zfs.ref].each { |ref| req.include?(ref).should == true } end end -- cgit