puppet 0.9.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (182) hide show
  1. data/CHANGELOG +0 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +17 -0
  4. data/README +24 -0
  5. data/Rakefile +294 -0
  6. data/TODO +4 -0
  7. data/bin/cf2puppet +186 -0
  8. data/bin/puppet +176 -0
  9. data/bin/puppetca +213 -0
  10. data/bin/puppetd +246 -0
  11. data/bin/puppetdoc +184 -0
  12. data/bin/puppetmasterd +258 -0
  13. data/examples/code/allatonce +13 -0
  14. data/examples/code/assignments +11 -0
  15. data/examples/code/classing +35 -0
  16. data/examples/code/components +73 -0
  17. data/examples/code/execs +16 -0
  18. data/examples/code/failers/badclassnoparam +10 -0
  19. data/examples/code/failers/badclassparam +10 -0
  20. data/examples/code/failers/badcompnoparam +9 -0
  21. data/examples/code/failers/badcompparam +9 -0
  22. data/examples/code/failers/badtypeparam +3 -0
  23. data/examples/code/file.bl +11 -0
  24. data/examples/code/filedefaults +10 -0
  25. data/examples/code/fileparsing +116 -0
  26. data/examples/code/filerecursion +15 -0
  27. data/examples/code/functions +3 -0
  28. data/examples/code/groups +7 -0
  29. data/examples/code/head +30 -0
  30. data/examples/code/importing +8 -0
  31. data/examples/code/nodes +20 -0
  32. data/examples/code/one +8 -0
  33. data/examples/code/relationships +34 -0
  34. data/examples/code/selectors +28 -0
  35. data/examples/code/simpletests +11 -0
  36. data/examples/code/snippets/argumentdefaults +14 -0
  37. data/examples/code/snippets/casestatement +39 -0
  38. data/examples/code/snippets/classheirarchy.pp +15 -0
  39. data/examples/code/snippets/classincludes.pp +17 -0
  40. data/examples/code/snippets/classpathtest +11 -0
  41. data/examples/code/snippets/dirchmod +19 -0
  42. data/examples/code/snippets/failmissingexecpath.pp +13 -0
  43. data/examples/code/snippets/falsevalues.pp +3 -0
  44. data/examples/code/snippets/filecreate +11 -0
  45. data/examples/code/snippets/implicititeration +15 -0
  46. data/examples/code/snippets/multipleinstances +7 -0
  47. data/examples/code/snippets/namevartest +9 -0
  48. data/examples/code/snippets/scopetest +13 -0
  49. data/examples/code/snippets/selectorvalues.pp +22 -0
  50. data/examples/code/snippets/simpledefaults +5 -0
  51. data/examples/code/snippets/simpleselector +38 -0
  52. data/examples/code/svncommit +13 -0
  53. data/examples/root/bin/sleeper +69 -0
  54. data/examples/root/etc/configfile +0 -0
  55. data/examples/root/etc/debian-passwd +29 -0
  56. data/examples/root/etc/debian-syslog.conf +71 -0
  57. data/examples/root/etc/init.d/sleeper +65 -0
  58. data/examples/root/etc/otherfile +0 -0
  59. data/examples/root/etc/puppet/fileserver.conf +3 -0
  60. data/examples/root/etc/puppet/puppetmasterd.conf +10 -0
  61. data/ext/module:puppet +195 -0
  62. data/install.rb +270 -0
  63. data/lib/puppet.rb +249 -0
  64. data/lib/puppet/base64.rb +19 -0
  65. data/lib/puppet/client.rb +519 -0
  66. data/lib/puppet/config.rb +49 -0
  67. data/lib/puppet/daemon.rb +208 -0
  68. data/lib/puppet/element.rb +71 -0
  69. data/lib/puppet/event.rb +259 -0
  70. data/lib/puppet/log.rb +321 -0
  71. data/lib/puppet/metric.rb +250 -0
  72. data/lib/puppet/parsedfile.rb +38 -0
  73. data/lib/puppet/parser/ast.rb +1560 -0
  74. data/lib/puppet/parser/interpreter.rb +150 -0
  75. data/lib/puppet/parser/lexer.rb +226 -0
  76. data/lib/puppet/parser/parser.rb +1354 -0
  77. data/lib/puppet/parser/scope.rb +755 -0
  78. data/lib/puppet/server.rb +170 -0
  79. data/lib/puppet/server/authstore.rb +227 -0
  80. data/lib/puppet/server/ca.rb +140 -0
  81. data/lib/puppet/server/filebucket.rb +147 -0
  82. data/lib/puppet/server/fileserver.rb +477 -0
  83. data/lib/puppet/server/logger.rb +43 -0
  84. data/lib/puppet/server/master.rb +103 -0
  85. data/lib/puppet/server/servlet.rb +247 -0
  86. data/lib/puppet/sslcertificates.rb +737 -0
  87. data/lib/puppet/statechange.rb +150 -0
  88. data/lib/puppet/storage.rb +95 -0
  89. data/lib/puppet/transaction.rb +179 -0
  90. data/lib/puppet/transportable.rb +151 -0
  91. data/lib/puppet/type.rb +1354 -0
  92. data/lib/puppet/type/component.rb +141 -0
  93. data/lib/puppet/type/cron.rb +543 -0
  94. data/lib/puppet/type/exec.rb +316 -0
  95. data/lib/puppet/type/group.rb +152 -0
  96. data/lib/puppet/type/nameservice.rb +3 -0
  97. data/lib/puppet/type/nameservice/netinfo.rb +173 -0
  98. data/lib/puppet/type/nameservice/objectadd.rb +146 -0
  99. data/lib/puppet/type/nameservice/posix.rb +200 -0
  100. data/lib/puppet/type/package.rb +420 -0
  101. data/lib/puppet/type/package/apt.rb +70 -0
  102. data/lib/puppet/type/package/dpkg.rb +108 -0
  103. data/lib/puppet/type/package/rpm.rb +81 -0
  104. data/lib/puppet/type/package/sun.rb +117 -0
  105. data/lib/puppet/type/package/yum.rb +58 -0
  106. data/lib/puppet/type/pfile.rb +569 -0
  107. data/lib/puppet/type/pfile/checksum.rb +219 -0
  108. data/lib/puppet/type/pfile/create.rb +108 -0
  109. data/lib/puppet/type/pfile/group.rb +129 -0
  110. data/lib/puppet/type/pfile/mode.rb +131 -0
  111. data/lib/puppet/type/pfile/source.rb +264 -0
  112. data/lib/puppet/type/pfile/type.rb +31 -0
  113. data/lib/puppet/type/pfile/uid.rb +166 -0
  114. data/lib/puppet/type/pfilebucket.rb +80 -0
  115. data/lib/puppet/type/pprocess.rb +97 -0
  116. data/lib/puppet/type/service.rb +347 -0
  117. data/lib/puppet/type/service/base.rb +17 -0
  118. data/lib/puppet/type/service/debian.rb +50 -0
  119. data/lib/puppet/type/service/init.rb +145 -0
  120. data/lib/puppet/type/service/smf.rb +29 -0
  121. data/lib/puppet/type/state.rb +182 -0
  122. data/lib/puppet/type/symlink.rb +183 -0
  123. data/lib/puppet/type/tidy.rb +183 -0
  124. data/lib/puppet/type/typegen.rb +149 -0
  125. data/lib/puppet/type/typegen/filerecord.rb +243 -0
  126. data/lib/puppet/type/typegen/filetype.rb +316 -0
  127. data/lib/puppet/type/user.rb +290 -0
  128. data/lib/puppet/util.rb +138 -0
  129. data/test/certmgr/certmgr.rb +265 -0
  130. data/test/client/client.rb +203 -0
  131. data/test/executables/puppetbin.rb +53 -0
  132. data/test/executables/puppetca.rb +79 -0
  133. data/test/executables/puppetd.rb +71 -0
  134. data/test/executables/puppetmasterd.rb +153 -0
  135. data/test/executables/puppetmodule.rb +60 -0
  136. data/test/language/ast.rb +412 -0
  137. data/test/language/interpreter.rb +71 -0
  138. data/test/language/scope.rb +412 -0
  139. data/test/language/snippets.rb +445 -0
  140. data/test/other/events.rb +111 -0
  141. data/test/other/log.rb +195 -0
  142. data/test/other/metrics.rb +92 -0
  143. data/test/other/overrides.rb +115 -0
  144. data/test/other/parsedfile.rb +31 -0
  145. data/test/other/relationships.rb +113 -0
  146. data/test/other/state.rb +106 -0
  147. data/test/other/storage.rb +39 -0
  148. data/test/other/transactions.rb +235 -0
  149. data/test/parser/lexer.rb +120 -0
  150. data/test/parser/parser.rb +180 -0
  151. data/test/puppet/conffiles.rb +104 -0
  152. data/test/puppet/defaults.rb +100 -0
  153. data/test/puppet/error.rb +23 -0
  154. data/test/puppet/utiltest.rb +120 -0
  155. data/test/puppettest.rb +774 -0
  156. data/test/server/authstore.rb +209 -0
  157. data/test/server/bucket.rb +227 -0
  158. data/test/server/ca.rb +201 -0
  159. data/test/server/fileserver.rb +710 -0
  160. data/test/server/logger.rb +175 -0
  161. data/test/server/master.rb +150 -0
  162. data/test/server/server.rb +130 -0
  163. data/test/tagging/tagging.rb +80 -0
  164. data/test/test +51 -0
  165. data/test/types/basic.rb +119 -0
  166. data/test/types/component.rb +272 -0
  167. data/test/types/cron.rb +261 -0
  168. data/test/types/exec.rb +273 -0
  169. data/test/types/file.rb +616 -0
  170. data/test/types/filebucket.rb +167 -0
  171. data/test/types/fileignoresource.rb +287 -0
  172. data/test/types/filesources.rb +587 -0
  173. data/test/types/filetype.rb +162 -0
  174. data/test/types/group.rb +271 -0
  175. data/test/types/package.rb +205 -0
  176. data/test/types/query.rb +101 -0
  177. data/test/types/service.rb +100 -0
  178. data/test/types/symlink.rb +93 -0
  179. data/test/types/tidy.rb +124 -0
  180. data/test/types/type.rb +135 -0
  181. data/test/types/user.rb +371 -0
  182. metadata +243 -0
@@ -0,0 +1,316 @@
1
+ #!/usr/local/bin/ruby -w
2
+
3
+ # $Id: filetype.rb 576 2005-08-23 16:09:14Z luke $
4
+
5
+ # parse and write configuration files using objects with minimal parsing abilities
6
+
7
+ require 'puppet/type'
8
+ require 'puppet/type/typegen'
9
+
10
+ class Puppet::Type::FileType < Puppet::Type::TypeGenerator
11
+ attr_accessor :childtype
12
+
13
+ @parameters = [:name, :linesplit, :escapednewlines]
14
+ #@abstract = true
15
+ @metaclass = true
16
+
17
+ @namevar = :name
18
+ @name = :filetype
19
+
20
+ @modsystem = true
21
+
22
+ #---------------------------------------------------------------
23
+ def FileType.newtype(hash)
24
+ unless hash.include?(:linesplit)
25
+ hash[:linesplit] = "\n"
26
+ end
27
+
28
+ # i don't think there's any reason to 'super' this
29
+ #klass = Puppet::Type::TypeGenerator.newtype(hash)
30
+ klass = super(hash)
31
+
32
+ klass.escapednewlines = true
33
+ klass.namevar = :name
34
+ klass.parameters = [:name, :path, :complete]
35
+
36
+ #klass.childtype = Puppet::Type::FileRecord.newtype(
37
+ # :name => hash[:name] + "_record",
38
+ # :splitchar => hash[:recordsplit],
39
+ # :fields => hash[:fields],
40
+ # :namevar => hash[:namevar]
41
+ #)
42
+ #klass.addrecord(
43
+ # :name => hash[:name] + "_record",
44
+ # :splitchar => hash[:recordsplit],
45
+ # :fields => hash[:fields],
46
+ # :namevar => hash[:namevar]
47
+ #)
48
+
49
+ return klass
50
+ end
51
+ #---------------------------------------------------------------
52
+
53
+ #---------------------------------------------------------------
54
+ # currently not used
55
+ def FileType.addrecord(hash)
56
+ unless defined? @records
57
+ @records = {}
58
+ end
59
+ hash[:filetype] = self
60
+
61
+ # default to the naming field being the first field provided
62
+ unless hash.include?(:namevar)
63
+ hash[:namevar] = hash[:fields][0]
64
+ end
65
+
66
+ recordtype = Puppet::Type::FileRecord.newtype(hash)
67
+ @records[recordtype.name] = recordtype
68
+ end
69
+ #---------------------------------------------------------------
70
+
71
+ #---------------------------------------------------------------
72
+ def FileType.records
73
+ return @records
74
+ end
75
+ #---------------------------------------------------------------
76
+
77
+ #---------------------------------------------------------------
78
+ def FileType.escapednewlines=(value)
79
+ @escnlines = value
80
+ end
81
+ #---------------------------------------------------------------
82
+
83
+ #---------------------------------------------------------------
84
+ def FileType.escapednewlines
85
+ if ! defined? @escnlines or @escnlines.nil?
86
+ return false
87
+ else
88
+ return @escnlines
89
+ end
90
+ end
91
+ #---------------------------------------------------------------
92
+
93
+ #---------------------------------------------------------------
94
+ def FileType.childtype
95
+ unless defined? @childtype
96
+ @childtype = nil
97
+ end
98
+ return @childtype
99
+ end
100
+ #---------------------------------------------------------------
101
+
102
+ #---------------------------------------------------------------
103
+ def FileType.childtype=(childtype)
104
+ @childtype = childtype
105
+ end
106
+ #---------------------------------------------------------------
107
+
108
+ #---------------------------------------------------------------
109
+ def FileType.regex
110
+ return @regex
111
+ end
112
+ #---------------------------------------------------------------
113
+
114
+ #---------------------------------------------------------------
115
+ def FileType.linesplit=(linesplit)
116
+ @regex = %r{#{linesplit}}
117
+ @linesplit = linesplit
118
+ end
119
+ #---------------------------------------------------------------
120
+
121
+ #---------------------------------------------------------------
122
+ def FileType.linesplit
123
+ return @linesplit
124
+ end
125
+ #---------------------------------------------------------------
126
+
127
+ #---------------------------------------------------------------
128
+ #def [](name)
129
+ # return @childhash[name]
130
+ #end
131
+ #---------------------------------------------------------------
132
+
133
+ #---------------------------------------------------------------
134
+ #def []=(name,value)
135
+ #end
136
+ #---------------------------------------------------------------
137
+
138
+ #---------------------------------------------------------------
139
+ # we don't really have a 'less-than/greater-than' sense here
140
+ # so i'm sticking with 'equals' until those make sense
141
+ def ==(other)
142
+ unless self.children.length == other.children.length
143
+ debug("file has %s records instead of %s" %
144
+ [self.children.length, other.children.length])
145
+ return self.children.length == other.children.length
146
+ end
147
+ equal = true
148
+ self.zip(other.children) { |schild,ochild|
149
+ unless schild == ochild
150
+ debug("%s has changed in %s" %
151
+ [schild.name,self.name])
152
+ equal = false
153
+ break
154
+ end
155
+ }
156
+
157
+ return equal
158
+ end
159
+ #---------------------------------------------------------------
160
+
161
+ #---------------------------------------------------------------
162
+ # create a new record with a block
163
+ def add(type,&block)
164
+ obj = self.class.records[type].new(self,&block)
165
+ debug("adding %s" % obj.name)
166
+ @childary.push(obj)
167
+ @childhash[obj.name] = obj
168
+
169
+ return obj
170
+ end
171
+ #---------------------------------------------------------------
172
+
173
+ #---------------------------------------------------------------
174
+ def children
175
+ return @childary
176
+ end
177
+ #---------------------------------------------------------------
178
+
179
+ #---------------------------------------------------------------
180
+ # remove a record
181
+ def delete(name)
182
+ if @childhash.has_key?(name)
183
+ child = @childhash[name]
184
+
185
+ @childhash.delete(child)
186
+ @childary.delete(child)
187
+ else
188
+ raise "No such entry %s" % name
189
+ end
190
+ end
191
+ #---------------------------------------------------------------
192
+
193
+ #---------------------------------------------------------------
194
+ def each
195
+ @childary.each { |child|
196
+ yield child
197
+ }
198
+ end
199
+ #---------------------------------------------------------------
200
+
201
+ #---------------------------------------------------------------
202
+ # create a new file
203
+ def initialize(hash)
204
+ # if we are the FileType object itself, we create a new type
205
+ # otherwise, we create an instance of an existing type
206
+ # yes, this should be more straightforward
207
+ if self.class == Puppet::Type::FileType
208
+ self.class.newtype(hash)
209
+ return
210
+ end
211
+ debug "Creating new '%s' file with path '%s' and name '%s'" %
212
+ [self.class.name,hash["path"],hash[:name]]
213
+ debug hash.inspect
214
+ @file = hash["path"]
215
+
216
+ @childary = []
217
+ @childhash = {}
218
+ super
219
+ end
220
+ #---------------------------------------------------------------
221
+
222
+ #---------------------------------------------------------------
223
+ # this is where we're pretty different from other objects
224
+ # we can choose to either reparse the existing file and compare
225
+ # the objects, or we can write our file out and do an
226
+ # text comparison
227
+ def insync?
228
+ tmp = self.class.new(@file)
229
+ tmp.retrieve
230
+
231
+ return self == tmp
232
+ end
233
+ #---------------------------------------------------------------
234
+
235
+ #---------------------------------------------------------------
236
+ #def name
237
+ # return @file
238
+ #end
239
+ #---------------------------------------------------------------
240
+
241
+ #---------------------------------------------------------------
242
+ # read the whole file in and turn it into each of the appropriate
243
+ # objects
244
+ def retrieve
245
+ str = ""
246
+ ::File.open(@file) { |fname|
247
+ fname.each { |line|
248
+ str += line
249
+ }
250
+ }
251
+
252
+ if self.class.escapednewlines
253
+ endreg = %r{\\\n\s*}
254
+ str.gsub!(endreg,'')
255
+ end
256
+ @childary = str.split(self.class.regex).collect { |line|
257
+ childobj = nil
258
+ self.class.records.each { |name,recordtype|
259
+ if childobj = recordtype.match(self,line)
260
+ break
261
+ end
262
+ }
263
+ if childobj.nil?
264
+ warning("%s: could not match %s" % [self.name,line])
265
+ #warning("could not match %s" % line)
266
+ next
267
+ end
268
+
269
+ begin
270
+ debug("got child: %s(%s)" % [childobj.class,childobj.to_s])
271
+ rescue NoMethodError
272
+ warning "Failed: %s" % childobj
273
+ end
274
+ childobj
275
+ }.reject { |child|
276
+ child.nil?
277
+ }
278
+
279
+ @childary.each { |child|
280
+ begin
281
+ @childhash[child.name] = child
282
+ rescue NoMethodError => detail
283
+ p child
284
+ p child.class
285
+ puts detail
286
+ exit
287
+ end
288
+ }
289
+ end
290
+ #---------------------------------------------------------------
291
+
292
+ #---------------------------------------------------------------
293
+ def sync
294
+ #unless self.insync?
295
+ self.write
296
+ #end
297
+ end
298
+ #---------------------------------------------------------------
299
+
300
+ #---------------------------------------------------------------
301
+ def to_s
302
+ return @childary.collect { |child|
303
+ child.to_s
304
+ }.join(self.class.linesplit) + self.class.linesplit
305
+ end
306
+ #---------------------------------------------------------------
307
+
308
+ #---------------------------------------------------------------
309
+ def write
310
+ ::File.open(@file, "w") { |file|
311
+ file.write(self.to_s)
312
+ }
313
+ end
314
+ #---------------------------------------------------------------
315
+ end
316
+ #---------------------------------------------------------------
@@ -0,0 +1,290 @@
1
+ require 'etc'
2
+ require 'facter'
3
+ require 'puppet/type/state'
4
+ require 'puppet/type/nameservice'
5
+
6
+ module Puppet
7
+ class State
8
+ module UserUID
9
+ def self.doc
10
+ "The user ID. Must be specified numerically. For new users
11
+ being created, if no user ID is specified then one will be
12
+ chosen automatically, which will likely result in the same user
13
+ having different IDs on different systems, which is not
14
+ recommended."
15
+ end
16
+
17
+ def self.name
18
+ :uid
19
+ end
20
+
21
+ def autogen
22
+ highest = 0
23
+ Etc.passwd { |user|
24
+ if user.uid > highest
25
+ unless user.uid > 65000
26
+ highest = user.uid
27
+ end
28
+ end
29
+ }
30
+
31
+ return highest + 1
32
+ end
33
+
34
+ def shouldprocess(value)
35
+ case value
36
+ when String
37
+ if value =~ /^[-0-9]+$/
38
+ value = Integer(value)
39
+ end
40
+ when Symbol
41
+ unless value == :notfound or value == :auto
42
+ raise Puppet::DevError, "Invalid UID %s" % value
43
+ end
44
+
45
+ if value == :auto
46
+ value = autogen()
47
+ end
48
+ end
49
+
50
+ return value
51
+ end
52
+ end
53
+
54
+ module UserGID
55
+ def self.doc
56
+ "The user's primary group. Can be specified numerically or
57
+ by name."
58
+ end
59
+
60
+ def self.name
61
+ :gid
62
+ end
63
+
64
+ def shouldprocess(gid)
65
+ method = :getgrgid
66
+ case gid
67
+ when String
68
+ if gid =~ /^[-0-9]+$/
69
+ gid = Integer(gid)
70
+ else
71
+ method = :getgrnam
72
+ end
73
+ when Symbol
74
+ unless gid == :auto or gid == :notfound
75
+ raise Puppet::DevError, "Invalid GID %s" % gid
76
+ end
77
+ # these are treated specially by sync()
78
+ return gid
79
+ end
80
+
81
+ # FIXME this should really check to see if we already have a
82
+ # group ready to be managed; if so, then we should just mark it
83
+ # as a prereq
84
+ begin
85
+ ginfo = Etc.send(method, gid)
86
+ rescue ArgumentError => detail
87
+ raise Puppet::Error, "Could not find group %s: %s" %
88
+ [gid, detail]
89
+ end
90
+
91
+ self.notice "setting gid to %s" % ginfo.gid.inspect
92
+ return ginfo.gid
93
+ end
94
+ end
95
+
96
+ module UserComment
97
+ def self.doc
98
+ "A description of the user. Generally is a user's full name."
99
+ end
100
+
101
+ def self.name
102
+ :comment
103
+ end
104
+
105
+ def self.optional?
106
+ true
107
+ end
108
+
109
+ def self.posixmethod
110
+ :gecos
111
+ end
112
+ end
113
+
114
+ module UserHome
115
+ def self.doc
116
+ "The home directory of the user. The directory must be created
117
+ separately and is not currently checked for existence."
118
+ end
119
+
120
+ def self.name
121
+ :home
122
+ end
123
+
124
+ def self.posixmethod
125
+ :dir
126
+ end
127
+ end
128
+
129
+ module UserShell
130
+ def self.doc
131
+ "The user's login shell. The shell must exist and be
132
+ executable."
133
+ end
134
+
135
+ def self.name
136
+ :shell
137
+ end
138
+ end
139
+
140
+ # these three states are all implemented differently on each platform,
141
+ # so i'm disabling them for now
142
+
143
+ # FIXME Puppet::State::UserLocked is currently non-functional
144
+ module UserLocked
145
+ def self.doc
146
+ "The expected return code. An error will be returned if the
147
+ executed command returns something else."
148
+ end
149
+
150
+ def self.name
151
+ :locked
152
+ end
153
+ end
154
+
155
+ # FIXME Puppet::State::UserExpire is currently non-functional
156
+ module UserExpire
157
+ def self.doc
158
+ "The expected return code. An error will be returned if the
159
+ executed command returns something else."
160
+ end
161
+
162
+ def self.name; :expire; end
163
+ end
164
+
165
+ # FIXME Puppet::State::UserInactive is currently non-functional
166
+ module UserInactive
167
+ def self.doc
168
+ "The expected return code. An error will be returned if the
169
+ executed command returns something else."
170
+ end
171
+
172
+ def self.name; :inactive; end
173
+ end
174
+
175
+ end
176
+
177
+ class Type
178
+ class User < Type
179
+ statenames = [
180
+ "UserUID",
181
+ "UserGID",
182
+ "UserComment",
183
+ "UserHome",
184
+ "UserShell"
185
+ ]
186
+ @statemodule = nil
187
+ case Facter["operatingsystem"].value
188
+ when "Darwin":
189
+ @statemodule = Puppet::NameService::NetInfo
190
+ else
191
+ @statemodule = Puppet::NameService::ObjectAdd
192
+ end
193
+
194
+ class << self
195
+ attr_accessor :netinfodir
196
+ attr_accessor :statemodule
197
+ end
198
+
199
+ @states = []
200
+
201
+ @states = statenames.collect { |name|
202
+ fullname = @statemodule.to_s + "::" + name
203
+ begin
204
+ eval(fullname)
205
+ rescue NameError
206
+ raise Puppet::DevError, "Could not retrieve state class %s" %
207
+ fullname
208
+ end
209
+ }.each { |klass|
210
+ klass.complete
211
+ }
212
+
213
+ @parameters = [
214
+ :name
215
+ ]
216
+
217
+ @paramdoc[:name] = "User name. While limitations are determined for
218
+ each operating system, it is generally a good idea to keep to the
219
+ degenerate 8 characters, beginning with a letter."
220
+
221
+ @doc = "Manage users. Currently can create and modify users, but
222
+ cannot delete them. Theoretically all of the parameters are
223
+ optional, but if no parameters are specified the comment will
224
+ be set to the user name in order to make the internals work out
225
+ correctly."
226
+ @name = :user
227
+ @namevar = :name
228
+
229
+ @netinfodir = "users"
230
+
231
+ def exists?
232
+ self.class.statemodule.exists?(self)
233
+ end
234
+
235
+ def getinfo(refresh = false)
236
+ if @userinfo.nil? or refresh == true
237
+ begin
238
+ @userinfo = Etc.getpwnam(self[:name])
239
+ rescue ArgumentError => detail
240
+ @userinfo = nil
241
+ end
242
+ end
243
+
244
+ @userinfo
245
+ end
246
+
247
+ def initialize(hash)
248
+ @userinfo = nil
249
+ super
250
+
251
+ # Verify that they have provided everything necessary, if we
252
+ # are trying to manage the user
253
+ if self.managed?
254
+ self.class.states.each { |state|
255
+ next if @states.include?(state.name)
256
+
257
+ unless state.autogen? or state.optional?
258
+ if state.method_defined?(:autogen)
259
+ self[state.name] = :auto
260
+ else
261
+ raise Puppet::Error,
262
+ "Users require a value for %s" % state.name
263
+ end
264
+ end
265
+ }
266
+
267
+ if @states.empty?
268
+ self[:comment] = self[:name]
269
+ end
270
+ end
271
+ end
272
+
273
+ def retrieve
274
+ info = self.getinfo(true)
275
+
276
+ if info.nil?
277
+ # the user does not exist
278
+ @states.each { |name, state|
279
+ state.is = :notfound
280
+ }
281
+ return
282
+ else
283
+ super
284
+ end
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ # $Id: user.rb 731 2005-10-26 04:44:25Z luke $