summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAndrew Shafer <andrew@reductivelabs.com>2008-10-01 18:58:09 -0600
committerAndrew Shafer <andrew@reductivelabs.com>2008-10-01 19:07:55 -0600
commitd1abb86565b63f98d8fc1395a78c840c45e47238 (patch)
tree7c17696812bf0942132959b2da730e1792e712f2 /lib
parent2fba85af73f7a5de31cc13de64f0243df99fef1a (diff)
downloadpuppet-d1abb86565b63f98d8fc1395a78c840c45e47238.tar.gz
puppet-d1abb86565b63f98d8fc1395a78c840c45e47238.tar.xz
puppet-d1abb86565b63f98d8fc1395a78c840c45e47238.zip
Add role support to user type and an implemention
modify user type: add ensure = role logic add roles property add manages_solaris_rbac feature refactored 'list' property to reuse logic for groups in roles
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/property/list.rb78
-rw-r--r--lib/puppet/provider/user/user_role_add.rb89
-rwxr-xr-xlib/puppet/type/user.rb88
3 files changed, 206 insertions, 49 deletions
diff --git a/lib/puppet/property/list.rb b/lib/puppet/property/list.rb
new file mode 100644
index 000000000..4e7f6ec90
--- /dev/null
+++ b/lib/puppet/property/list.rb
@@ -0,0 +1,78 @@
+require 'puppet/property'
+
+module Puppet
+ class Property
+ class List < Property
+
+ def should_to_s(should_value)
+ #just return the should value
+ should_value
+ end
+
+ def is_to_s(currentvalue)
+ currentvalue.join(delimiter)
+ end
+
+ def membership
+ :membership
+ end
+
+ def add_should_with_current(should, current)
+ if current.is_a?(Array)
+ should += current
+ end
+ should.uniq
+ end
+
+ def inclusive?
+ @resource[membership] == :inclusive
+ end
+
+ def should
+ unless defined? @should and @should
+ return nil
+ end
+
+ members = @should
+ #inclusive means we are managing everything so if it isn't in should, its gone
+ if ! inclusive?
+ members = add_should_with_current(members, retrieve)
+ end
+
+ members.sort.join(delimiter)
+ end
+
+ def delimiter
+ ","
+ end
+
+ def retrieve
+ #ok, some 'convention' if the list property is named groups, provider should implement a groups method
+ if tmp = provider.send(name) and tmp != :absent
+ return tmp.split(delimiter)
+ else
+ return :absent
+ end
+ end
+
+ def prepare_is_for_comparison(is)
+ if is.is_a? Array
+ is = is.sort.join(delimiter)
+ end
+ is
+ end
+
+ def insync?(is)
+ unless defined? @should and @should
+ return true
+ end
+
+ unless is
+ return true
+ end
+
+ return (prepare_is_for_comparison(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
new file mode 100644
index 000000000..23581abbb
--- /dev/null
+++ b/lib/puppet/provider/user/user_role_add.rb
@@ -0,0 +1,89 @@
+require 'puppet/util/user_attr'
+
+Puppet::Type.type(:user).provide :user_role_add, :parent => Puppet::Type::User::ProviderUseradd do
+
+ desc "User management inherits ``useradd`` and adds logic to manage roles on Solaris using roleadd."
+
+ defaultfor :operatingsystem => :solaris
+
+ commands :add => "useradd", :delete => "userdel", :modify => "usermod", :role_add => "roleadd", :role_delete => "roledel", :role_modify => "rolemod"
+ options :home, :flag => "-d", :method => :dir
+ options :comment, :method => :gecos
+ options :groups, :flag => "-G"
+ options :roles, :flag => "-R"
+
+ verify :gid, "GID must be an integer" do |value|
+ value.is_a? Integer
+ end
+
+ verify :groups, "Groups must be comma-separated" do |value|
+ value !~ /\s/
+ end
+
+ has_features :manages_homedir, :allows_duplicates, :manages_solaris_rbac
+
+ if Puppet.features.libshadow?
+ has_feature :manages_passwords
+ end
+
+ def user_attributes
+ @user_attributes ||= UserAttr.get_attributes_by_name(@resource[:name])
+ end
+
+ def flush
+ @user_attributes = nil
+ end
+
+ def command(cmd)
+ if is_role? or (!exists? and @resource[:ensure] == :role)
+ cmd = ("role_" + cmd.to_s).intern
+ end
+ super(cmd)
+ end
+
+ def is_role?
+ user_attributes and user_attributes[:type] == "role"
+ end
+
+ def run(cmd, msg)
+ begin
+ execute(cmd)
+ rescue Puppet::ExecutionFailure => detail
+ raise Puppet::Error, "Could not %s %s %s: %s" %
+ [msg, @resource.class.name, @resource.name, detail]
+ end
+ end
+
+ def transition(type)
+ cmd = [command(:modify)]
+ cmd << "-K" << "type=#{type}"
+ cmd << @resource[:name]
+ end
+
+ def create
+ if is_role?
+ run(transition("normal"), "transition role to")
+ else
+ run(addcmd, "create")
+ end
+ end
+
+ def destroy
+ run(deletecmd, "delete "+ (is_role? ? "role" : "user"))
+ end
+
+ def create_role
+ if exists? and !is_role?
+ run(transition("role"), "transition user to")
+ else
+ run(addcmd, "create role")
+ end
+ end
+
+ def roles
+ if user_attributes
+ user_attributes[:roles]
+ end
+ end
+end
+
diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb
index bb0a86fd0..74c4c6a33 100755
--- a/lib/puppet/type/user.rb
+++ b/lib/puppet/type/user.rb
@@ -1,5 +1,6 @@
require 'etc'
require 'facter'
+require 'puppet/property/list'
module Puppet
newtype(:user) do
@@ -21,6 +22,9 @@ module Puppet
"The provider can modify user passwords, by accepting a password
hash."
+ feature :manages_solaris_rbac,
+ "The provider can manage roles and normal users"
+
newproperty(:ensure, :parent => Puppet::Property::Ensure) do
newvalue(:present, :event => :user_created) do
provider.create
@@ -30,6 +34,10 @@ module Puppet
provider.delete
end
+ newvalue(:role, :event => :role_created, :required_features => :manages_solaris_rbac) do
+ provider.create_role
+ end
+
desc "The basic state that the object should be in."
# If they're talking about the thing at all, they generally want to
@@ -44,7 +52,11 @@ module Puppet
def retrieve
if provider.exists?
- return :present
+ if provider.respond_to?(:is_role?) and provider.is_role?
+ return :role
+ else
+ return :present
+ end
else
return :absent
end
@@ -125,68 +137,36 @@ module Puppet
end
end
- newproperty(:groups) do
+ 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
specified as an array."
- def should_to_s(newvalue)
- self.should
- end
-
- def is_to_s(currentvalue)
- currentvalue.join(",")
- end
-
- # We need to override this because the groups need to
- # be joined with commas
- def should
- current_value = retrieve
-
- unless defined? @should and @should
- return nil
- end
-
- if @resource[:membership] == :inclusive
- return @should.sort.join(",")
- else
- members = @should
- if current_value.is_a?(Array)
- members += current_value
- end
- return members.uniq.sort.join(",")
+ validate do |value|
+ if value =~ /^\d+$/
+ raise ArgumentError, "Group names must be provided, not numbers"
end
- end
-
- def retrieve
- if tmp = provider.groups and tmp != :absent
- return tmp.split(",")
- else
- return :absent
+ if value.include?(",")
+ puts value
+ raise ArgumentError, "Group names must be provided as an array, not a comma-separated list"
end
end
+ end
- def insync?(is)
- unless defined? @should and @should
- return true
- end
- unless defined? is and is
- return true
- end
- tmp = is
- if is.is_a? Array
- tmp = is.sort.join(",")
- 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."
- return tmp == self.should
+ def membership
+ :role_membership
end
validate do |value|
if value =~ /^\d+$/
- raise ArgumentError, "Group names must be provided, not numbers"
+ raise ArgumentError, "Role names must be provided, not numbers"
end
if value.include?(",")
- raise ArgumentError, "Group names must be provided as an array, not a comma-separated list"
+ raise ArgumentError, "Role names must be provided as an array, not a comma-separated list"
end
end
end
@@ -202,7 +182,17 @@ module Puppet
desc "Whether specified groups should be treated as the only groups
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(: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