[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, master, updated. debian/0.24.6-1-356-g5718585

James Turnbull james at lovedthanlost.net
Fri Jan 23 14:21:28 UTC 2009


The following commit has been merged in the master branch:
commit c09d0cc128aa3f6a0b741422ae45326b258bae7d
Author: Andrew Shafer <andrew at reductivelabs.com>
Date:   Tue Oct 21 12:20:12 2008 -0600

    Solaris RBAC Attributes
    
    Adding support to user type for:
    profiles
    auths
    project
    key/value pairs
    
    Refactored useradd.addcmd so I could override how properties get added in the subclass
    Added keyvalue property to manage generic keyvalues

diff --git a/CHANGELOG b/CHANGELOG
index 1c9e446..d3a2ef2 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,8 @@
 0.24.6
+    Adding support to the user type for: profiles, auths, project, 
+    key/value pairs (extension to Solaris RBAC support added in
+    0.24.6)
+
     Fixed #1662 - Configuration Reference still references 'section'
 
     Fixed #1460 - enhance redhat puppetmaster init.d script to easy start puppetmaster as a mongrel cluster
diff --git a/lib/puppet/property/keyvalue.rb b/lib/puppet/property/keyvalue.rb
new file mode 100644
index 0000000..6c0800c
--- /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 819516d..00fc24b 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 b327db3..6996dd6 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 29f4880..929e45d 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
 
diff --git a/spec/unit/property/keyvalue.rb b/spec/unit/property/keyvalue.rb
new file mode 100644
index 0000000..6f9eef5
--- /dev/null
+++ b/spec/unit/property/keyvalue.rb
@@ -0,0 +1,168 @@
+#!/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") }
+
+require 'puppet/property/keyvalue'
+
+klass = Puppet::Property::KeyValue
+
+describe klass do
+
+    it "should be a subclass of Property" do
+        klass.superclass.must == Puppet::Property
+    end
+
+    describe "as an instance" do
+        before do
+            # Wow that's a messy interface to the resource.
+            klass.initvars
+            @resource = stub 'resource', :[]= => nil, :property => nil
+            @property = klass.new(:resource => @resource)
+        end
+
+        it "should have a , as default delimiter" do
+            @property.delimiter.should == ";"
+        end
+
+        it "should have a = as default separator" do
+            @property.separator.should == "="
+        end
+
+        it "should have a :membership as default membership" do
+            @property.membership.should == :key_value_membership
+        end
+
+        it "should return the same value passed into should_to_s" do
+            @property.should_to_s({:foo => "baz", :bar => "boo"}) == "foo=baz;bar=boo"
+        end
+
+        it "should return the passed in array values joined with the delimiter from is_to_s" do
+            @property.is_to_s({"foo" => "baz" , "bar" => "boo"}).should == "foo=baz;bar=boo"
+        end
+
+        describe "when calling inclusive?" do
+            it "should use the membership method to look up on the @resource" do
+                @property.expects(:membership).returns(:key_value_membership)
+                @resource.expects(:[]).with(:key_value_membership)
+                @property.inclusive?
+            end
+
+            it "should return true when @resource[membership] == inclusive" do
+                @property.stubs(:membership).returns(:key_value_membership)
+                @resource.stubs(:[]).with(:key_value_membership).returns(:inclusive)
+                @property.inclusive?.must == true
+            end
+
+            it "should return false when @resource[membership] != inclusive" do
+                @property.stubs(:membership).returns(:key_value_membership)
+                @resource.stubs(:[]).with(:key_value_membership).returns(:minimum)
+                @property.inclusive?.must == false
+            end
+        end
+
+        describe "when calling process_current_hash" do
+            it "should return {} if hash is :absent" do
+                @property.process_current_hash(:absent).must == {}
+            end
+
+            it "should set every key to nil if inclusive?" do
+                @property.stubs(:inclusive?).returns(true)
+                @property.process_current_hash({:foo => "bar", :do => "re"}).must == { :foo => nil, :do => nil }
+            end
+
+            it "should return the hash if !inclusive?" do
+                @property.stubs(:inclusive?).returns(false)
+                @property.process_current_hash({:foo => "bar", :do => "re"}).must == {:foo => "bar", :do => "re"}
+            end
+        end
+
+        describe "when calling should" do
+            it "should return nil if @should is nil" do
+                @property.should.must == nil
+            end
+
+            it "should call process_current_hash" do
+                @property.should = ["foo=baz", "bar=boo"]
+                @property.stubs(:retrieve).returns({:do => "re", :mi => "fa" })
+                @property.expects(:process_current_hash).returns({})
+                @property.should
+            end
+
+            it "should return the hashed values of @should and the nilled values of retrieve if inclusive" do
+                @property.should = ["foo=baz", "bar=boo"]
+                @property.expects(:retrieve).returns({:do => "re", :mi => "fa" })
+                @property.expects(:inclusive?).returns(true)
+                @property.should.must == { :foo => "baz", :bar => "boo", :do => nil, :mi => nil }
+            end
+
+            it "should return the hashed @should + the unique values of retrieve if !inclusive" do
+                @property.should = ["foo=baz", "bar=boo"]
+                @property.expects(:retrieve).returns({:foo => "diff", :do => "re", :mi => "fa"})
+                @property.expects(:inclusive?).returns(false)
+                @property.should.must == { :foo => "baz", :bar => "boo", :do => "re", :mi => "fa" }
+            end
+        end
+
+        describe "when calling retrieve" do
+            before do
+                @provider = mock("provider")
+                @property.stubs(:provider).returns(@provider)
+            end
+
+            it "should send 'name' to the provider" do
+                @provider.expects(:send).with(:keys)
+                @property.expects(:name).returns(:keys)
+                @property.retrieve
+            end
+
+            it "should return a hash with the provider returned info" do
+                @provider.stubs(:send).with(:keys).returns({"do" => "re", "mi" => "fa" })
+                @property.stubs(:name).returns(:keys)
+                @property.retrieve == {"do" => "re", "mi" => "fa" }
+            end
+
+            it "should return :absent when the provider returns :absent" do
+                @provider.stubs(:send).with(:keys).returns(:absent)
+                @property.stubs(:name).returns(:keys)
+                @property.retrieve == :absent
+            end
+        end
+
+        describe "when calling hashify" do
+            it "should return the array hashified" do
+                @property.hashify(["foo=baz", "bar=boo"]).must == { :foo => "baz", :bar => "boo" }
+            end
+        end
+
+        describe "when calling insync?" do
+            before do
+                @provider = mock("provider")
+                @property.stubs(:provider).returns(@provider)
+                @property.stubs(:name).returns(:prop_name)
+            end
+
+            it "should return true unless @should is defined and not nil" do
+                @property.insync?("foo") == true
+            end
+
+            it "should return true if the passed in values is nil" do
+                @property.should = "foo"
+                @property.insync?(nil) == true
+            end
+
+            it "should return true if hashified should value == (retrieved) value passed in" do
+                @provider.stubs(:prop_name).returns({ :foo => "baz", :bar => "boo" })
+                @property.should = ["foo=baz", "bar=boo"]
+                @property.expects(:inclusive?).returns(true)
+                @property.insync?({ :foo => "baz", :bar => "boo" }).must == true
+            end
+
+            it "should return false if prepared value != should value" do
+                @provider.stubs(:prop_name).returns({ "foo" => "bee", "bar" => "boo" })
+                @property.should = ["foo=baz", "bar=boo"]
+                @property.expects(:inclusive?).returns(true)
+                @property.insync?({ "foo" => "bee", "bar" => "boo" }).must == false
+            end
+        end
+    end
+end
diff --git a/spec/unit/provider/user/user_role_add.rb b/spec/unit/provider/user/user_role_add.rb
index e9bd9a6..fc2074d 100644
--- a/spec/unit/provider/user/user_role_add.rb
+++ b/spec/unit/provider/user/user_role_add.rb
@@ -42,9 +42,9 @@ describe provider_class do
     end
 
     describe "when calling transition" do
-        it "should return foomod setting the type to bar" do
+        it "should return the type set to whatever is passed in" do
             @provider.expects(:command).with(:modify).returns("foomod")
-            @provider.transition("bar").should == ["foomod", "-K", "type=bar", "fakeval"]
+            @provider.transition("bar").include?("type=bar")
         end
     end
 
@@ -115,17 +115,77 @@ describe provider_class do
         end
     end
 
-    describe "when getting roles" do
+    [:roles, :auths, :profiles].each do |val|
+        describe "when getting #{val}" do
+            it "should get the user_attributes" do
+                @provider.expects(:user_attributes)
+                @provider.send(val)
+            end
+
+            it "should get the #{val} attribute" do
+                attributes = mock("attributes")
+                attributes.expects(:[]).with(val)
+                @provider.stubs(:user_attributes).returns(attributes)
+                @provider.send(val)
+            end
+        end
+    end
+
+    describe "when getting the keys" do
         it "should get the user_attributes" do
             @provider.expects(:user_attributes)
-            @provider.roles
+            @provider.keys
+        end
+
+        it "should call removed_managed_attributes" do
+            @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
+            @provider.expects(:remove_managed_attributes)
+            @provider.keys
+        end
+
+        it "should removed managed attribute (type, auths, roles, etc)" do
+            @provider.stubs(:user_attributes).returns({ :type => "normal", :foo => "something" })
+            @provider.keys.should == { :foo => "something" }
+        end
+    end
+
+    describe "when adding properties" do
+        it "should call build_keys_cmd" do
+            @resource.stubs(:should).returns ""
+            @resource.expects(:should).with(:keys).returns({ :foo => "bar" })
+            @provider.expects(:build_keys_cmd).returns([])
+            @provider.add_properties
+        end
+
+        it "should add the elements of the keys hash to an array" do
+            @resource.stubs(:should).returns ""
+            @resource.expects(:should).with(:keys).returns({ :foo => "bar"})
+            @provider.add_properties.must == ["-K", "foo=bar"]
+        end
+    end
+
+    describe "when calling build_keys_cmd" do
+        it "should build cmd array with keypairs seperated by -K ending with user" do
+            @provider.build_keys_cmd({"foo" => "bar", "baz" => "boo"}).should.eql? ["-K", "foo=bar", "-K", "baz=boo"]
+        end
+    end
+
+    describe "when setting the keys" do
+        before do
+            @provider.stubs(:is_role?).returns(false)
+        end
+
+        it "should run a command" do
+            @provider.expects(:run)
+            @provider.keys=({})
         end
 
-        it "should get the :roles attribute" do
-            attributes = mock("attributes")
-            attributes.expects(:[]).with(:roles)
-            @provider.stubs(:user_attributes).returns(attributes)
-            @provider.roles
+        it "should build the command" do
+            @resource.stubs(:[]).with(:name).returns("someuser")
+            @provider.stubs(:command).returns("usermod")
+            @provider.expects(:build_keys_cmd).returns(["-K", "foo=bar"])
+            @provider.expects(:run).with(["usermod", "-K", "foo=bar", "someuser"], "modify attribute key pairs")
+            @provider.keys=({})
         end
     end
 end
diff --git a/spec/unit/provider/user/useradd.rb b/spec/unit/provider/user/useradd.rb
index 96a7855..463212e 100755
--- a/spec/unit/provider/user/useradd.rb
+++ b/spec/unit/provider/user/useradd.rb
@@ -7,25 +7,109 @@ provider_class = Puppet::Type.type(:user).provider(:useradd)
 describe provider_class do
     before do
         @resource = stub("resource", :name => "myuser", :managehome? => nil)
+        @resource.stubs(:should).returns "fakeval"
+        @resource.stubs(:[]).returns "fakeval"
         @provider = provider_class.new(@resource)
     end
 
     # #1360
     it "should add -o when allowdupe is enabled and the user is being created" do
-        @resource.stubs(:should).returns "fakeval"
-        @resource.stubs(:[]).returns "fakeval"
         @resource.expects(:allowdupe?).returns true
         @provider.expects(:execute).with { |args| args.include?("-o") }
-
         @provider.create
     end
 
     it "should add -o when allowdupe is enabled and the uid is being modified" do
-        @resource.stubs(:should).returns "fakeval"
-        @resource.stubs(:[]).returns "fakeval"
         @resource.expects(:allowdupe?).returns true
         @provider.expects(:execute).with { |args| args.include?("-o") }
 
         @provider.uid = 150
     end
+
+    describe "when checking to add allow dup" do
+        it "should check allow dup" do
+            @resource.expects(:allowdupe?)
+            @provider.check_allow_dup
+        end
+
+        it "should return an array with a flag if dup is allowed" do
+            @resource.stubs(:allowdupe?).returns true
+            @provider.check_allow_dup.must == ["-o"]
+        end
+
+        it "should return an empty array if no dup is allowed" do
+            @resource.stubs(:allowdupe?).returns false
+            @provider.check_allow_dup.must == []
+        end
+    end
+
+    describe "when checking manage home" do
+        it "should check manage home" do
+            @resource.expects(:managehome?)
+            @provider.check_manage_home
+        end
+
+        it "should return an array with -m flag if home is managed" do
+            @resource.stubs(:managehome?).returns true
+            @provider.check_manage_home.must == ["-m"]
+        end
+
+        it "should return an array with -M if home is not managed and on Redhat" do
+            Facter.stubs(:value).with("operatingsystem").returns("RedHat")
+            @resource.stubs(:managehome?).returns false
+            @provider.check_manage_home.must == ["-M"]
+        end
+
+        it "should return an empty array if home is not managed and not on Redhat" do
+            Facter.stubs(:value).with("operatingsystem").returns("some OS")
+            @resource.stubs(:managehome?).returns false
+            @provider.check_manage_home.must == []
+        end
+    end
+
+    describe "when adding properties" do
+        it "should get the valid properties"
+        it "should not add the ensure property"
+        it "should add the flag and value to an array"
+        it "should return and array of flags and values"
+    end
+
+    describe "when calling addcmd" do
+        before do
+            @resource.stubs(:allowdupe?).returns true
+            @resource.stubs(:managehome?).returns true
+        end
+
+        it "should call command with :add" do
+            @provider.expects(:command).with(:add)
+            @provider.addcmd
+        end
+
+        it "should add properties" do
+            @provider.expects(:add_properties).returns([])
+            @provider.addcmd
+        end
+
+        it "should check and add if dup allowed" do
+            @provider.expects(:check_allow_dup).returns([])
+            @provider.addcmd
+        end
+
+        it "should check and add if home is managed" do
+            @provider.expects(:check_manage_home).returns([])
+            @provider.addcmd
+        end
+
+        it "should add the resource :name" do
+            @resource.expects(:[]).with(:name)
+            @provider.addcmd
+        end
+
+        it "should return an array with full command" do
+            @provider.stubs(:command).with(:add).returns("useradd")
+            @provider.stubs(:add_properties).returns(["-G", "somegroup"])
+            @resource.stubs(:[]).with(:name).returns("someuser")
+            @provider.addcmd.must == ["useradd", "-G", "somegroup", "-o", "-m", "someuser"]
+        end
+    end
 end
diff --git a/spec/unit/type/user.rb b/spec/unit/type/user.rb
index 51c6dd8..41b10da 100755
--- a/spec/unit/type/user.rb
+++ b/spec/unit/type/user.rb
@@ -32,13 +32,19 @@ describe user do
         user.provider_feature(:manages_passwords).should_not be_nil
     end
 
+    it "should have a manages_solaris_rbac feature" do
+        user.provider_feature(:manages_solaris_rbac).should_not be_nil
+    end
+
     describe "instances" do
         it "should have a valid provider" do
             user.create(:name => "foo").provider.class.ancestors.should be_include(Puppet::Provider)
         end
     end
 
-    [:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups].each do |property|
+    properties = [:ensure, :uid, :gid, :home, :comment, :shell, :password, :groups, :roles, :auths, :profiles, :project, :keys]
+
+    properties.each do |property|
         it "should have a %s property" % property do
             user.attrclass(property).ancestors.should be_include(Puppet::Property)
         end
@@ -184,4 +190,16 @@ describe user do
             @password.change_to_s("other", "mypass").should_not be_include("mypass")
         end
     end
+
+    describe "when manages_solaris_rbac is enabled" do
+        before do
+            @provider.stubs(:satisfies?).returns(false)
+            @provider.expects(:satisfies?).with(:manages_solaris_rbac).returns(true)
+        end
+
+        it "should support a :role value for ensure" do
+            @ensure = user.attrclass(:ensure).new(:resource => @resource)
+            lambda { @ensure.should = :role }.should_not raise_error
+        end
+    end
 end

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list