summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-07 02:53:19 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2005-09-07 02:53:19 +0000
commitb77d29568e8adaa0104d8ee5b4c168ef6e3c4bdd (patch)
tree8372dc3bc8ed4cb293ff19e7cf6f920d8e7abb69 /lib/puppet
parent4f2812a2180894b645583c7a7c3aa8a012b2b0ac (diff)
downloadpuppet-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/puppet')
-rw-r--r--lib/puppet/type.rb24
-rwxr-xr-xlib/puppet/type/group.rb156
-rwxr-xr-xlib/puppet/type/user.rb205
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