diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-07 02:53:19 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-07 02:53:19 +0000 |
commit | b77d29568e8adaa0104d8ee5b4c168ef6e3c4bdd (patch) | |
tree | 8372dc3bc8ed4cb293ff19e7cf6f920d8e7abb69 /lib | |
parent | 4f2812a2180894b645583c7a7c3aa8a012b2b0ac (diff) | |
download | puppet-b77d29568e8adaa0104d8ee5b4c168ef6e3c4bdd.tar.gz puppet-b77d29568e8adaa0104d8ee5b4c168ef6e3c4bdd.tar.xz puppet-b77d29568e8adaa0104d8ee5b4c168ef6e3c4bdd.zip |
adding user and group classes (although user class is not yet functional), and added "is(state)" and "should(state)" methods for retrieving the respective values on a specified state
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@630 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/type.rb | 24 | ||||
-rwxr-xr-x | lib/puppet/type/group.rb | 156 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 205 |
3 files changed, 385 insertions, 0 deletions
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 509a10333..4a1afd91d 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -576,6 +576,28 @@ class Type < Puppet::Element #--------------------------------------------------------------- #--------------------------------------------------------------- + # retrieve the 'is' value for a specified state + def is(state) + if @states.include?(state) + return @states[state].is + else + return nil + end + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- + # retrieve the 'should' value for a specified state + def should(state) + if @states.include?(state) + return @states[state].should + else + return nil + end + end + #--------------------------------------------------------------- + + #--------------------------------------------------------------- # is the instance a managed instance? A 'yes' here means that # the instance was created from the language, vs. being created # in order resolve other questions, such as finding a package @@ -1219,11 +1241,13 @@ end require 'puppet/statechange' require 'puppet/type/component' require 'puppet/type/exec' +require 'puppet/type/group' require 'puppet/type/package' require 'puppet/type/pfile' require 'puppet/type/pfilebucket' require 'puppet/type/service' require 'puppet/type/symlink' +require 'puppet/type/user' require 'puppet/type/tidy' #require 'puppet/type/typegen' #require 'puppet/type/typegen/filetype' diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb new file mode 100755 index 000000000..38a56dc31 --- /dev/null +++ b/lib/puppet/type/group.rb @@ -0,0 +1,156 @@ +# $Id$ + +require 'etc' +require 'facter' +require 'puppet/type/state' + +module Puppet + class State + class GroupState < Puppet::State + class << self + def infomethod + if defined? @infomethod and @infomethod + return @infomethod + else + return @name + end + end + end + + def retrieve + obj = @parent.getinfo(true) + + method = self.class.infomethod + + @is = obj.send(method) + end + + def sync + obj = @parent.getinfo + + cmd = nil + event = nil + if @should == :notfound + # we need to remove the object... + if obj.nil? + # the group already doesn't exist + return nil + end + + cmd = ["groupdel", @parent.name] + type = "delete" + else + unless obj.nil? + raise Puppet::DevError, + "Got told to create a group that already exists" + end + # we're creating the group + + # i can just tell i'm going to regret this + # why doesn't POSIX include interfaces for adding users + # and groups? it's stupid + cmd = ["groupadd"] + if gid = @parent.should(:gid) + cmd << "-g" << gid + end + cmd << @parent.name + type = "create" + end + + output = %x{#{cmd.join(" ")} 2>&1} + + unless $? == 0 + raise Puppet::Error, "Could not %s group %s: %s" % + [type, @parent.name, output] + end + + return "group_#{type}d".intern + end + end + + class GroupGID < GroupState + @doc = "The group ID. Must be specified numerically. If not specified, + a number will be picked, which can result in ID differences across + systems and thus is not recommended. The method for picking GIDs + is basically to find the next GID above the highest existing GID + excluding those above 65000." + @name = :gid + + def should=(gid) + if gid.is_a?(String) + if gid =~ /^[0-9]+$/ + gid = Integer(gid) + end + end + + Puppet.info "Setting gid to %s" % gid + + @should = gid + end + end + end + + class Type + class Group < Type + @states = [ + Puppet::State::GroupGID + ] + + @parameters = [ + :name + ] + + @doc = " " + @name = :group + @namevar = :name + + def getinfo(refresh = false) + if @groupinfo.nil? or refresh == true + begin + @groupinfo = Etc.getgrnam(self[:name]) + rescue ArgumentError => detail + # leave groupinfo as nil + end + end + + @groupinfo + end + + def initialize(hash) + @groupinfo = nil + super + end + + def retrieve + obj = self.getinfo(true) + + if obj.nil? + # the group does not exist + + # unless we're in noop mode, we need to auto-pick a gid if there + # hasn't been one specified + unless @states.include?(:gid) or self.noop + highest = 0 + Etc.group { |group| + if group.gid > highest + unless group.gid > 65000 + highest = group.gid + end + end + } + + self[:gid] = highest + 1 + end + + @states.each { |name, state| + state.is = :notfound + } + + return + else + super + end + end + end + end +end diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb new file mode 100755 index 000000000..cc7bbadaa --- /dev/null +++ b/lib/puppet/type/user.rb @@ -0,0 +1,205 @@ +# $Id$ + +require 'etc' +require 'facter' +require 'puppet/type/state' + +module Puppet + class State + class UserState < Puppet::State + @@userinfo = nil + + class << self + attr_accessor :infomethod + + def getinfo(refresh = false) + if @@userinfo.nil? or refresh == true + begin + @@userinfo = Etc.getpwnam(@parent[:name]) + rescue ArgumentError => detail + @@userinfo = :notfound + end + end + + @@userinfo + end + end + + def retrieve + info = self.class.getinfo(true) + + method = self.class.infomethod || self.class.name + + unless method + raise Puppet::DevError, + "Could not retrieve info method for state %s" % self.class.name + end + + unless info.respond_to?(method) + raise Puppet::DevError, "UserInfo object does not respond to %s" % + method + end + + @is = info.send(method) + end + + def sync + end + end + + class UserUID < UserState + @doc = "The user ID. Must be specified numerically. For new users being + created, if no user ID is specified then one will be chosen + automatically, which will likely result in the same user having + different IDs on different systems, which is not recommended." + @name = :uid + end + + class UserGID < UserState + @doc = "The user's primary group. Can be specified numerically or by name." + @name = :gid + + def should=(gid) + method = :getgrgid + if gid.is_a?(String) + if gid =~ /^[0-9]+$/ + gid = Integer(gid) + else + method = :getgrnam + end + end + + # FIXME this should really check to see if we already have a group + # ready to be managed; if so, then we should just mark it as a prereq + begin + ginfo = Etc.send(method, gid) + rescue ArgumentError => detail + raise Puppet::Error, "Could not find group %s: %s" % [gid, detail] + end + + @should = ginfo.gid + end + + def sync + return :executed_command + end + end + + class UserComment < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :comment + + def retrieve + end + + def sync + return :executed_command + end + end + + class UserHome < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :home + + def retrieve + end + + def sync + return :executed_command + end + end + + class UserShell < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :shell + + def retrieve + end + + def sync + return :executed_command + end + end + + class UserLocked < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :locked + + def retrieve + end + + def sync + return :executed_command + end + end + + class UserExpire < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :expire + + def retrieve + end + + def sync + return :executed_command + end + end + + class UserInactive < UserState + @doc = "The expected return code. An error will be returned if the + executed command returns something else." + @name = :inactive + + def retrieve + end + + def sync + return :executed_command + end + end + + end + + class Type + class User < Type + @states = [ + Puppet::State::UserUID, + Puppet::State::UserGID, + Puppet::State::UserComment, + Puppet::State::UserHome, + Puppet::State::UserShell, + Puppet::State::UserLocked, + Puppet::State::UserExpire, + Puppet::State::UserInactive + ] + + @parameters = [ + :name + ] + + @doc = " + " + @name = :user + @namevar = :name + + def retrieve + info = Puppet::State::UserState.getinfo + + if info == :notfound + # the user does not exist + @states.each { |name, state| + state.is = :notfound + } + return + else + super + end + end + end + end +end |