summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-12-09 15:10:09 -0600
committerLuke Kanies <luke@madstop.com>2008-12-09 15:10:09 -0600
commit71b8befa424c6c82a10a5cc7d7ea50331851c7e9 (patch)
tree0143dc9e61dba7b54ec0b44399b6c9d20ae32767
parent89e9ef7521f5d62f1eb65514fe8923d0456e6184 (diff)
parente5c36fd865a5699c867e68a23153ec40da919e33 (diff)
downloadpuppet-71b8befa424c6c82a10a5cc7d7ea50331851c7e9.tar.gz
puppet-71b8befa424c6c82a10a5cc7d7ea50331851c7e9.tar.xz
puppet-71b8befa424c6c82a10a5cc7d7ea50331851c7e9.zip
Merge branch '0.24.x'
Conflicts: CHANGELOG lib/puppet/type/tidy.rb spec/unit/type/file/ensure.rb spec/unit/type/tidy.rb
-rw-r--r--CHANGELOG66
-rw-r--r--Rakefile18
-rwxr-xr-xbin/ralsh4
-rwxr-xr-xlib/puppet/external/nagios/base.rb185
-rw-r--r--lib/puppet/provider/group/netinfo.rb8
-rw-r--r--lib/puppet/provider/macauthorization/macauthorization.rb313
-rw-r--r--lib/puppet/provider/nameservice/netinfo.rb9
-rw-r--r--lib/puppet/provider/user/directoryservice.rb1
-rw-r--r--lib/puppet/provider/user/netinfo.rb12
-rw-r--r--lib/puppet/provider/zfs/solaris.rb13
-rw-r--r--lib/puppet/reports/tagmail.rb1
-rwxr-xr-xlib/puppet/type/file/ensure.rb4
-rw-r--r--lib/puppet/type/macauthorization.rb142
-rw-r--r--lib/puppet/type/nagios_hostdependency.rb3
-rw-r--r--lib/puppet/type/nagios_hostgroupescalation.rb3
-rwxr-xr-xlib/puppet/type/zfs.rb6
-rw-r--r--lib/puppet/util.rb10
-rwxr-xr-xspec/unit/provider/macauthorization.rb147
-rwxr-xr-xspec/unit/provider/service/launchd.rb2
-rwxr-xr-xspec/unit/provider/zfs/solaris.rb4
-rwxr-xr-xspec/unit/type/file/ensure.rb11
-rwxr-xr-xspec/unit/type/macauthorization.rb78
-rwxr-xr-xspec/unit/type/tidy.rb6
-rwxr-xr-xspec/unit/type/user.rb12
-rwxr-xr-xspec/unit/type/zfs.rb35
-rw-r--r--test/lib/puppettest/runnable_test.rb2
26 files changed, 972 insertions, 123 deletions
diff --git a/CHANGELOG b/CHANGELOG
index aa427efbf..cb918eb62 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,19 +1,58 @@
-0.25.?
- Fixing #1168 for REST -- all ssl classes downcase their names.
- This is a much cleaner fix than the xmlrpc version, thankfully. :)
+0.24.7
+ Fixed #1496 - nagios_servicedependency needs a unique host_name?
- Added a boolean 'crl' default value. Now we have a location for
- the CA CRL and the host CRL, and then a setting for configuring
- whether we should even use a CRL. This way we aren't trying to
- set file paths to 'false' to disable the CRL.
+ Fixed #1420 - nagios_serviceescalation not allowing host_name more than one type
-0.24.x
- Fixed #1695 - Solaris 10 zone provider doesn't properly handle unknown zone attributes in newer releases
+ Bug #1803 Zfs should auto require the ancestor file systems
- Fixed #1776 - Trivial fix for gentoo service provider
+ 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
+
+ Fixed #1695 - Solaris 10 zone provider doesn't properly handle unknown zone attributes in newer releases
+
+ Fixed #1776 - Trivial fix for gentoo service provider
+
Fixed #1767 - Minor fix to emacs mode
Fixed #1711 - fileserver test fails due to incorrect mocking
@@ -65,6 +104,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 f9e349afc..21d7651d4 100644
--- a/Rakefile
+++ b/Rakefile
@@ -208,3 +208,21 @@ 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'`
+
+ File.open(File.join(CHANGELOG_DIR, "CHANGELOG.git"), 'w') do |f|
+ f << change_body
+ end
+
+ # Changelog commit
+ `git add #{CHANGELOG_DIR}/CHANGELOG.git`
+ `git commit -m "Update CHANGELOG.git"`
+ end
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
diff --git a/lib/puppet/external/nagios/base.rb b/lib/puppet/external/nagios/base.rb
index 25c689559..6a0c1831c 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,155 @@ 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,
+ :_naginator_name
- 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/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/macauthorization/macauthorization.rb b/lib/puppet/provider/macauthorization/macauthorization.rb
new file mode 100644
index 000000000..2cdef6c12
--- /dev/null
+++ b/lib/puppet/provider/macauthorization/macauthorization.rb
@@ -0,0 +1,313 @@
+require 'facter'
+require 'facter/util/plist'
+require 'puppet'
+require 'tempfile'
+
+Puppet::Type.type(:macauthorization).provide :macauthorization, :parent => Puppet::Provider do
+
+ 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
+
+ # 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
+
+ AuthDB = "/etc/authorization"
+
+ @rights = {}
+ @rules = {}
+ @parsed_auth_db = {}
+ @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",
+ :auth_class => "class",
+ :k_of_n => "k-of-n",
+ :session_owner => "session-owner", }
+
+ class << self
+ attr_accessor :parsed_auth_db
+ attr_accessor :rights
+ attr_accessor :rules
+ attr_accessor :comments # Not implemented yet.
+
+ def prefetch(resources)
+ self.populate_rules_rights
+ end
+
+ def instances
+ if self.parsed_auth_db == {}
+ self.prefetch(nil)
+ end
+ self.parsed_auth_db.collect do |k,v|
+ new(:name => k)
+ end
+ end
+
+ 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
+
+ end
+
+ # standard required provider instance methods
+
+ def initialize(resource)
+ 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 rather than repeating code.
+ new_values = {}
+ 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
+ end
+
+ def destroy
+ # We explicitly delete here rather than in the flush method.
+ case resource[:auth_type]
+ when :right
+ destroy_right
+ when :rule
+ destroy_rule
+ else
+ 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 true
+ else
+ return false
+ end
+ end
+
+
+ def flush
+ # 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("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 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?
+ 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)
+ set_right(resource[:name], new_values)
+ end
+
+ def flush_rule
+ authdb = Plist::parse_xml(AuthDB)
+ 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
+ Plist::Emit.save_plist(values, tmp.path)
+ 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
+ end
+ 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
+ values = convert_plist_to_native_attributes(values)
+ authdb = Plist::parse_xml(AuthDB)
+ authdb["rules"][name] = values
+
+ begin
+ Plist::Emit.save_plist(authdb, AuthDB)
+ rescue
+ 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.
+ newplist = {}
+ propertylist.each_pair do |key, value|
+ 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
+ elsif not key.is_a?(String)
+ new_key = key.to_s
+ end
+ newplist[new_key] = value
+ end
+ newplist
+ end
+
+ def retrieve_value(resource_name, attribute)
+
+ if not self.class.parsed_auth_db.has_key?(resource_name)
+ raise Puppet::Error.new("Cannot find #{resource_name} in auth db")
+ end
+
+ if PuppetToNativeAttributeMap.has_key?(attribute)
+ native_attribute = PuppetToNativeAttributeMap[attribute]
+ 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
+ when true, "true", :true
+ value = :true
+ when false, "false", :false
+ value = :false
+ end
+
+ @property_hash[attribute] = value
+ return value
+ else
+ @property_hash.delete(attribute)
+ return "" # so ralsh doesn't display it.
+ end
+ 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.
+
+ properties = [ :allow_root, :authenticate_user, :auth_class, :comment,
+ :group, :k_of_n, :mechanisms, :rule, :session_owner,
+ :shared, :timeout, :tries ]
+
+ properties.each do |field|
+ define_method(field.to_s) do
+ retrieve_value(resource[:name], field)
+ end
+
+ define_method(field.to_s + "=") do |value|
+ @property_hash[field] = value
+ end
+ end
+
+ def auth_type
+ 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("#{resource[:name]} is unknown type.")
+ end
+ else
+ raise Puppet::Error.new("auth_type required for new resources.")
+ end
+ end
+
+ def auth_type=(value)
+ @property_hash[:auth_type] = value
+ end
+
+end \ No newline at end of file
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
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]
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/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
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index bd2e2fbdd..026d13fae 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -135,6 +135,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/lib/puppet/type/macauthorization.rb b/lib/puppet/type/macauthorization.rb
new file mode 100644
index 000000000..46e02ddae
--- /dev/null
+++ b/lib/puppet/type/macauthorization.rb
@@ -0,0 +1,142 @@
+Puppet::Type.newtype(:macauthorization) do
+
+ @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
+
+ 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.
+ 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' or a 'rule'. 'comment' has not yet been
+ implemented."
+
+ newvalue(:right)
+ newvalue(:rule)
+ # newvalue(:comment) # not yet implemented.
+ end
+
+ newproperty(:allow_root, :boolean => true) do
+ 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)
+
+ munge do |value|
+ @resource.munge_boolean(value)
+ end
+ end
+
+ newproperty(:authenticate_user, :boolean => true) do
+ desc "Corresponds to 'authenticate-user' in the authorization store,
+ renamed due to hyphens being problematic."
+
+ newvalue(:true)
+ newvalue(:false)
+
+ munge do |value|
+ @resource.munge_boolean(value)
+ end
+ end
+
+ newproperty(:auth_class) do
+ 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 "The 'comment' attribute for authorization resources."
+ end
+
+ newproperty(:group) do
+ 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. 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 "an array of suitable mechanisms."
+ end
+
+ newproperty(:rule, :array_match => :all) do
+ 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 "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)
+
+ munge do |value|
+ @resource.munge_boolean(value)
+ 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/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
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
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/lib/puppet/util.rb b/lib/puppet/util.rb
index 09c94c3c9..a5f3c5b1a 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -268,6 +268,9 @@ module Util
# Execute the desired command, and return the status and output.
# def execute(command, failonfail = true, uid = nil, gid = nil)
+ # :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 }
@@ -321,7 +324,11 @@ module Util
# Child process executes this
Process.setsid
begin
- $stdin.reopen("/dev/null")
+ 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'
-
diff --git a/spec/unit/provider/macauthorization.rb b/spec/unit/provider/macauthorization.rb
new file mode 100755
index 000000000..8c9636f16
--- /dev/null
+++ b/spec/unit/provider/macauthorization.rb
@@ -0,0 +1,147 @@
+#!/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'
+
+ @authname = "foo.spam.eggs.puppettest"
+ @authplist = {}
+
+ @rules = {@authname => @authplist}
+
+ 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}]"
+
+ @provider = provider_class.new(@resource)
+ 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/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
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
diff --git a/spec/unit/type/file/ensure.rb b/spec/unit/type/file/ensure.rb
index be1e65110..d766eeb35 100755
--- a/spec/unit/type/file/ensure.rb
+++ b/spec/unit/type/file/ensure.rb
@@ -3,10 +3,14 @@
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
# Wow that's a messy interface to the resource.
- @resource = stub 'resource', :[] => nil, :[]= => nil, :property => nil, :newattr => nil, :parameter => nil
+ @resource = stub 'resource', :[] => nil, :[]= => nil, :property => nil, :newattr => nil, :parameter => nil, :replace? => true
+ @resource.stubs(:[]).returns "foo"
+ @resource.stubs(:[]).with(:path).returns "/my/file"
+ @ensure = property.new :resource => @resource
end
it "should be a subclass of Ensure" do
@@ -36,6 +40,11 @@ describe property do
@stat = stub 'stat', :ftype => "file"
end
+ 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
+
it "should be in sync if :ensure is set to :absent and the file does not exist" do
@ensure.should = :absent
diff --git a/spec/unit/type/macauthorization.rb b/spec/unit/type/macauthorization.rb
new file mode 100755
index 000000000..1c7f122b8
--- /dev/null
+++ b/spec/unit/type/macauthorization.rb
@@ -0,0 +1,78 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+macauth_type = Puppet::Type.type(:macauthorization)
+
+describe Puppet.type(:macauthorization), "when checking macauthorization objects" do
+
+ before do
+ 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
+
+
+ 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
+
+ end
+
+ 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 \ No newline at end of file
diff --git a/spec/unit/type/tidy.rb b/spec/unit/type/tidy.rb
index 4609dbc85..c1cb8eabf 100755
--- a/spec/unit/type/tidy.rb
+++ b/spec/unit/type/tidy.rb
@@ -122,6 +122,12 @@ describe Puppet::Type.type(:tidy) do
@tidy.mkfile("/what/ever")
end
+
+ it "should do nothing if the targeted file does not exist" do
+ File.expects(:lstat).with("/what/ever").raises Errno::ENOENT
+
+ @tidy.generate.should == []
+ end
end
describe "and recursion is not used" do
diff --git a/spec/unit/type/user.rb b/spec/unit/type/user.rb
index 17524c5e5..78bfa2e82 100755
--- a/spec/unit/type/user.rb
+++ b/spec/unit/type/user.rb
@@ -239,12 +239,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
diff --git a/spec/unit/type/zfs.rb b/spec/unit/type/zfs.rb
index 434415e24..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,7 +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
+ provider = mock "provider"
+ provider.stubs(:name).returns(:solaris)
+ zfs.stubs(:defaultprovider).returns(provider)
+ Puppet.type(:zpool).stubs(:defaultprovider).returns(provider)
+
+
+ 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
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|