diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/property/keyvalue.rb | 96 | ||||
-rw-r--r-- | lib/puppet/provider/user/user_role_add.rb | 67 | ||||
-rw-r--r-- | lib/puppet/provider/user/useradd.rb | 37 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 148 |
4 files changed, 303 insertions, 45 deletions
diff --git a/lib/puppet/property/keyvalue.rb b/lib/puppet/property/keyvalue.rb new file mode 100644 index 000000000..6c0800c79 --- /dev/null +++ b/lib/puppet/property/keyvalue.rb @@ -0,0 +1,96 @@ +#This subclass of property manages string key value pairs. + +#In order to use this property: +# - the @should value must be an array of keyvalue pairs separated by the 'separator' +# - the retrieve method should return a hash with the keys as symbols +# IMPORTANT NOTE: In order for this property to work there must also be a 'membership' parameter +# The class that inherits from property should override that method with the symbol for the membership + +require 'puppet/property' + +module Puppet + class Property + class KeyValue < Property + + def hash_to_key_value_s(hash) + hash.select { |k,v| true }.map { |pair| pair.join(separator) }.join(delimiter) + end + + def should_to_s(should_value) + hash_to_key_value_s(should_value) + end + + def is_to_s(current_value) + hash_to_key_value_s(current_value) + end + + def membership + :key_value_membership + end + + def inclusive? + @resource[membership] == :inclusive + end + + def hashify(key_value_array) + #turns string array into a hash + key_value_array.inject({}) do |hash, key_value| + tmp = key_value.split(separator) + hash[tmp[0].intern] = tmp[1] + hash + end + end + + def process_current_hash(current) + return {} if current == :absent + + #inclusive means we are managing everything so if it isn't in should, its gone + if inclusive? + current.each_key { |key| current[key] = nil } + end + current + end + + def should + unless defined? @should and @should + return nil + end + + members = hashify(@should) + current = process_current_hash(retrieve) + + #shared keys will get overwritten by members + current.merge(members) + end + + def separator + "=" + end + + def delimiter + ";" + end + + def retrieve + #ok, some 'convention' if the keyvalue property is named properties, provider should implement a properties method + if key_hash = provider.send(name) and key_hash != :absent + return key_hash + else + return :absent + end + end + + def insync?(is) + unless defined? @should and @should + return true + end + + unless is + return true + end + + return (is == self.should) + end + end + end +end diff --git a/lib/puppet/provider/user/user_role_add.rb b/lib/puppet/provider/user/user_role_add.rb index 819516dc4..00fc24b3a 100644 --- a/lib/puppet/provider/user/user_role_add.rb +++ b/lib/puppet/provider/user/user_role_add.rb @@ -11,6 +11,8 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do options :comment, :method => :gecos options :groups, :flag => "-G" options :roles, :flag => "-R" + options :auths, :flag => "-A" + options :profiles, :flag => "-P" verify :gid, "GID must be an integer" do |value| value.is_a? Integer @@ -26,6 +28,24 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do has_feature :manages_passwords end + #must override this to hand the keyvalue pairs + def add_properties + cmd = [] + Puppet::Type.type(:user).validproperties.each do |property| + next if property == :ensure + # the value needs to be quoted, mostly because -c might + # have spaces in it + if value = @resource.should(property) and value != "" + if property == :keys + cmd += build_keys_cmd(value) + else + cmd << flag(property) << value + end + end + end + cmd + end + def user_attributes @user_attributes ||= UserAttr.get_attributes_by_name(@resource[:name]) end @@ -57,6 +77,7 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do def transition(type) cmd = [command(:modify)] cmd << "-K" << "type=#{type}" + cmd += add_properties cmd << @resource[:name] end @@ -85,5 +106,51 @@ Puppet::Type.type(:user).provide :user_role_add, :parent => :useradd do user_attributes[:roles] end end + + def auths + if user_attributes + user_attributes[:auths] + end + end + + def profiles + if user_attributes + user_attributes[:profiles] + end + end + + def project + if user_attributes + user_attributes[:project] + end + end + + def managed_attributes + [:name, :type, :roles, :auths, :profiles, :project] + end + + def remove_managed_attributes + managed = managed_attributes + user_attributes.select { |k,v| !managed.include?(k) }.inject({}) { |hash, array| hash[array[0]] = array[1]; hash } + end + + def keys + if user_attributes + #we have to get rid of all the keys we are managing another way + remove_managed_attributes + end + end + + def build_keys_cmd(keys_hash) + cmd = [] + keys_hash.each do |k,v| + cmd << "-K" << "#{k}=#{v}" + end + cmd + end + + def keys=(keys_hash) + run([command(:modify)] + build_keys_cmd(keys_hash) << @resource[:name], "modify attribute key pairs") + end end diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb index b327db384..6996dd69a 100644 --- a/lib/puppet/provider/user/useradd.rb +++ b/lib/puppet/provider/user/useradd.rb @@ -23,8 +23,22 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ has_feature :manages_passwords end - def addcmd - cmd = [command(:add)] + def check_allow_dup + @resource.allowdupe? ? ["-o"] : [] + end + + def check_manage_home + cmd = [] + if @resource.managehome? + cmd << "-m" + elsif %w{Fedora RedHat}.include?(Facter.value("operatingsystem")) + cmd << "-M" + end + cmd + end + + def add_properties + cmd = [] Puppet::Type.type(:user).validproperties.each do |property| next if property == :ensure # the value needs to be quoted, mostly because -c might @@ -33,20 +47,15 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ cmd << flag(property) << value end end + cmd + end - if @resource.allowdupe? - cmd << "-o" - end - - if @resource.managehome? - cmd << "-m" - elsif %w{Fedora RedHat}.include?(Facter.value("operatingsystem")) - cmd << "-M" - end - + def addcmd + cmd = [command(:add)] + cmd += add_properties + cmd += check_allow_dup + cmd += check_manage_home cmd << @resource[:name] - - cmd end # Retrieve the password using the Shadow Password library diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index 29f4880c1..929e45d14 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -1,6 +1,7 @@ require 'etc' require 'facter' require 'puppet/property/list' +require 'puppet/property/keyvalue' module Puppet newtype(:user) do @@ -137,6 +138,7 @@ module Puppet end end + newproperty(:groups, :parent => Puppet::Property::List) do desc "The groups of which the user is a member. The primary group should not be listed. Multiple groups should be @@ -147,25 +149,7 @@ module Puppet raise ArgumentError, "Group names must be provided, not numbers" end if value.include?(",") - raise ArgumentError, "Group names must be provided as an array, not as a comma-separated list '%s'" % value - end - end - end - - newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do - desc "The roles of which the user the user has. The roles should be - specified as an array." - - def membership - :role_membership - end - - validate do |value| - if value =~ /^\d+$/ - raise ArgumentError, "Role names must be provided, not numbers" - end - if value.include?(",") - raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" + raise ArgumentError, "Group names must be provided as an array, not a comma-separated list" end end end @@ -187,19 +171,9 @@ module Puppet defaultto :minimum end - newparam(:role_membership) do - desc "Whether specified roles should be treated as the only roles - of which the user is a member or whether they should merely - be treated as the minimum membership list." - - newvalues(:inclusive, :minimum) - - defaultto :minimum - end - newparam(:allowdupe, :boolean => true) do desc "Whether to allow duplicate UIDs." - + newvalues(:true, :false) defaultto false @@ -240,7 +214,7 @@ module Puppet gobj.should(:gid) == group } autos << obj - + end else autos << group @@ -273,6 +247,118 @@ module Puppet prophash } end + + newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The roles the user has. Multiple roles should be + specified as an array." + + def membership + :role_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Role names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Role names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:role_membership) do + desc "Whether specified roles should be treated as the only roles + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:auths, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The auths the user has. Multiple auths should be + specified as an array." + + def membership + :auth_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Auth names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Auth names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:auth_membership) do + desc "Whether specified auths should be treated as the only auths + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:profiles, :parent => Puppet::Property::List, :required_features => :manages_solaris_rbac) do + desc "The profiles the user has. Multiple profiles should be + specified as an array." + + def membership + :profile_membership + end + + validate do |value| + if value =~ /^\d+$/ + raise ArgumentError, "Profile names must be provided, not numbers" + end + if value.include?(",") + raise ArgumentError, "Profile names must be provided as an array, not a comma-separated list" + end + end + end + + newparam(:profile_membership) do + desc "Whether specified roles should be treated as the only roles + of which the user is a member or whether they should merely + be treated as the minimum membership list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:keys, :parent => Puppet::Property::KeyValue, :required_features => :manages_solaris_rbac) do + desc "Specify user attributes in an array of keyvalue pairs" + + def membership + :key_membership + end + + validate do |value| + unless value.include?("=") + raise ArgumentError, "key value pairs must be seperated by an =" + end + end + end + + newparam(:key_membership) do + desc "Whether specified key value pairs should be treated as the only attributes + of the user or whether they should merely + be treated as the minimum list." + + newvalues(:inclusive, :minimum) + + defaultto :minimum + end + + newproperty(:project, :required_features => :manages_solaris_rbac) do + desc "The name of the project associated with a user" + end end end |