chef 0.7.10

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

Potentially problematic release.


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

Files changed (120) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +135 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +26 -0
  5. data/lib/chef.rb +49 -0
  6. data/lib/chef/application.rb +98 -0
  7. data/lib/chef/application/agent.rb +18 -0
  8. data/lib/chef/application/client.rb +209 -0
  9. data/lib/chef/application/indexer.rb +141 -0
  10. data/lib/chef/application/server.rb +18 -0
  11. data/lib/chef/application/solo.rb +214 -0
  12. data/lib/chef/client.rb +396 -0
  13. data/lib/chef/compile.rb +138 -0
  14. data/lib/chef/config.rb +141 -0
  15. data/lib/chef/cookbook.rb +144 -0
  16. data/lib/chef/cookbook/metadata.rb +407 -0
  17. data/lib/chef/cookbook/metadata/version.rb +87 -0
  18. data/lib/chef/cookbook_loader.rb +168 -0
  19. data/lib/chef/couchdb.rb +172 -0
  20. data/lib/chef/daemon.rb +170 -0
  21. data/lib/chef/exceptions.rb +36 -0
  22. data/lib/chef/file_cache.rb +205 -0
  23. data/lib/chef/log.rb +39 -0
  24. data/lib/chef/mixin/check_helper.rb +31 -0
  25. data/lib/chef/mixin/checksum.rb +37 -0
  26. data/lib/chef/mixin/command.rb +351 -0
  27. data/lib/chef/mixin/create_path.rb +56 -0
  28. data/lib/chef/mixin/deep_merge.rb +36 -0
  29. data/lib/chef/mixin/find_preferred_file.rb +99 -0
  30. data/lib/chef/mixin/from_file.rb +36 -0
  31. data/lib/chef/mixin/generate_url.rb +48 -0
  32. data/lib/chef/mixin/language.rb +79 -0
  33. data/lib/chef/mixin/params_validate.rb +197 -0
  34. data/lib/chef/mixin/template.rb +84 -0
  35. data/lib/chef/node.rb +406 -0
  36. data/lib/chef/node/attribute.rb +412 -0
  37. data/lib/chef/openid_registration.rb +181 -0
  38. data/lib/chef/platform.rb +253 -0
  39. data/lib/chef/provider.rb +40 -0
  40. data/lib/chef/provider/cron.rb +137 -0
  41. data/lib/chef/provider/directory.rb +72 -0
  42. data/lib/chef/provider/execute.rb +58 -0
  43. data/lib/chef/provider/file.rb +191 -0
  44. data/lib/chef/provider/group.rb +120 -0
  45. data/lib/chef/provider/group/groupadd.rb +92 -0
  46. data/lib/chef/provider/group/pw.rb +88 -0
  47. data/lib/chef/provider/http_request.rb +102 -0
  48. data/lib/chef/provider/ifconfig.rb +131 -0
  49. data/lib/chef/provider/link.rb +157 -0
  50. data/lib/chef/provider/mount.rb +121 -0
  51. data/lib/chef/provider/mount/mount.rb +208 -0
  52. data/lib/chef/provider/package.rb +160 -0
  53. data/lib/chef/provider/package/apt.rb +110 -0
  54. data/lib/chef/provider/package/dpkg.rb +113 -0
  55. data/lib/chef/provider/package/freebsd.rb +153 -0
  56. data/lib/chef/provider/package/macports.rb +105 -0
  57. data/lib/chef/provider/package/portage.rb +124 -0
  58. data/lib/chef/provider/package/rpm.rb +99 -0
  59. data/lib/chef/provider/package/rubygems.rb +130 -0
  60. data/lib/chef/provider/package/yum-dump.py +104 -0
  61. data/lib/chef/provider/package/yum.rb +175 -0
  62. data/lib/chef/provider/remote_directory.rb +126 -0
  63. data/lib/chef/provider/remote_file.rb +134 -0
  64. data/lib/chef/provider/route.rb +118 -0
  65. data/lib/chef/provider/ruby_block.rb +15 -0
  66. data/lib/chef/provider/script.rb +42 -0
  67. data/lib/chef/provider/service.rb +129 -0
  68. data/lib/chef/provider/service/debian.rb +64 -0
  69. data/lib/chef/provider/service/freebsd.rb +157 -0
  70. data/lib/chef/provider/service/gentoo.rb +54 -0
  71. data/lib/chef/provider/service/init.rb +126 -0
  72. data/lib/chef/provider/service/redhat.rb +62 -0
  73. data/lib/chef/provider/template.rb +141 -0
  74. data/lib/chef/provider/user.rb +170 -0
  75. data/lib/chef/provider/user/pw.rb +113 -0
  76. data/lib/chef/provider/user/useradd.rb +107 -0
  77. data/lib/chef/queue.rb +145 -0
  78. data/lib/chef/recipe.rb +210 -0
  79. data/lib/chef/resource.rb +256 -0
  80. data/lib/chef/resource/apt_package.rb +34 -0
  81. data/lib/chef/resource/bash.rb +33 -0
  82. data/lib/chef/resource/cron.rb +143 -0
  83. data/lib/chef/resource/csh.rb +33 -0
  84. data/lib/chef/resource/directory.rb +76 -0
  85. data/lib/chef/resource/dpkg_package.rb +34 -0
  86. data/lib/chef/resource/execute.rb +127 -0
  87. data/lib/chef/resource/file.rb +84 -0
  88. data/lib/chef/resource/gem_package.rb +41 -0
  89. data/lib/chef/resource/group.rb +68 -0
  90. data/lib/chef/resource/http_request.rb +52 -0
  91. data/lib/chef/resource/ifconfig.rb +134 -0
  92. data/lib/chef/resource/link.rb +78 -0
  93. data/lib/chef/resource/macports_package.rb +29 -0
  94. data/lib/chef/resource/mount.rb +135 -0
  95. data/lib/chef/resource/package.rb +80 -0
  96. data/lib/chef/resource/perl.rb +33 -0
  97. data/lib/chef/resource/portage_package.rb +33 -0
  98. data/lib/chef/resource/python.rb +33 -0
  99. data/lib/chef/resource/remote_directory.rb +91 -0
  100. data/lib/chef/resource/remote_file.rb +60 -0
  101. data/lib/chef/resource/route.rb +135 -0
  102. data/lib/chef/resource/ruby.rb +33 -0
  103. data/lib/chef/resource/ruby_block.rb +20 -0
  104. data/lib/chef/resource/script.rb +51 -0
  105. data/lib/chef/resource/service.rb +134 -0
  106. data/lib/chef/resource/template.rb +60 -0
  107. data/lib/chef/resource/user.rb +98 -0
  108. data/lib/chef/resource_collection.rb +176 -0
  109. data/lib/chef/resource_definition.rb +67 -0
  110. data/lib/chef/rest.rb +238 -0
  111. data/lib/chef/role.rb +231 -0
  112. data/lib/chef/run_list.rb +156 -0
  113. data/lib/chef/runner.rb +123 -0
  114. data/lib/chef/search.rb +88 -0
  115. data/lib/chef/search/result.rb +64 -0
  116. data/lib/chef/search_index.rb +77 -0
  117. data/lib/chef/tasks/chef_repo.rake +345 -0
  118. data/lib/chef/util/file_edit.rb +125 -0
  119. data/lib/chef/util/fileedit.rb +121 -0
  120. metadata +262 -0
@@ -0,0 +1,412 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: AJ Christensen (<aj@opscode.com>)
4
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require 'chef/mixin/deep_merge'
21
+ require 'chef/log'
22
+
23
+ class Chef
24
+ class Node
25
+ class Attribute
26
+ attr_accessor :attribute,
27
+ :default,
28
+ :override,
29
+ :state,
30
+ :current_attribute,
31
+ :current_default,
32
+ :current_override,
33
+ :auto_vivifiy_on_read,
34
+ :set_unless_value_present,
35
+ :has_been_read
36
+
37
+ include Enumerable
38
+
39
+ def initialize(attribute, default, override, state=[])
40
+ @attribute = attribute
41
+ @current_attribute = attribute
42
+ @default = default
43
+ @current_default = default
44
+ @override = override
45
+ @current_override = override
46
+ @state = state
47
+ @auto_vivifiy_on_read = false
48
+ @set_unless_value_present = false
49
+ @has_been_read = false
50
+ end
51
+
52
+ # Reset our internal state to the top of every tree
53
+ def reset
54
+ @current_attribute = @attribute
55
+ @current_default = @default
56
+ @current_override = @override
57
+ @has_been_read = false
58
+ @state = []
59
+ end
60
+
61
+ def [](key)
62
+ @state << key
63
+
64
+ # We set this to so that we can cope with ||= as a setting.
65
+ # See the comments in []= for more details.
66
+ @has_been_read = true
67
+
68
+ o_value = value_or_descend(current_override, key, auto_vivifiy_on_read)
69
+ a_value = value_or_descend(current_attribute, key, auto_vivifiy_on_read)
70
+ d_value = value_or_descend(current_default, key, auto_vivifiy_on_read)
71
+
72
+ determine_value(o_value, a_value, d_value)
73
+ end
74
+
75
+ def attribute?(key)
76
+ return true if get_value(override, key)
77
+ return true if get_value(attribute, key)
78
+ return true if get_value(default, key)
79
+ false
80
+ end
81
+
82
+ def has_key?(key)
83
+ attribute?(key)
84
+ end
85
+
86
+ alias :include? :has_key?
87
+ alias :key? :has_key?
88
+ alias :member? :has_key?
89
+
90
+ def each(&block)
91
+ get_keys.each do |key|
92
+ value = determine_value(
93
+ get_value(override, key),
94
+ get_value(attribute, key),
95
+ get_value(default, key)
96
+ )
97
+ block.call([key, value])
98
+ end
99
+ end
100
+
101
+ def each_pair(&block)
102
+ get_keys.each do |key|
103
+ value = determine_value(
104
+ get_value(override, key),
105
+ get_value(attribute, key),
106
+ get_value(default, key)
107
+ )
108
+ block.call(key, value)
109
+ end
110
+ end
111
+
112
+ def each_attribute(&block)
113
+ get_keys.each do |key|
114
+ value = determine_value(
115
+ get_value(override, key),
116
+ get_value(attribute, key),
117
+ get_value(default, key)
118
+ )
119
+ block.call(key, value)
120
+ end
121
+ end
122
+
123
+ def each_key(&block)
124
+ get_keys.each do |key|
125
+ block.call(key)
126
+ end
127
+ end
128
+
129
+ def each_value(&block)
130
+ get_keys.each do |key|
131
+ value = determine_value(
132
+ get_value(override, key),
133
+ get_value(attribute, key),
134
+ get_value(default, key)
135
+ )
136
+ block.call(value)
137
+ end
138
+ end
139
+
140
+ def empty?
141
+ get_keys.empty?
142
+ end
143
+
144
+ def fetch(key, default_value=nil, &block)
145
+ if get_keys.include? key
146
+ determine_value(
147
+ get_value(override, key),
148
+ get_value(attribute, key),
149
+ get_value(default, key)
150
+ )
151
+ elsif default_value
152
+ default_value
153
+ elsif block_given?
154
+ block.call(key)
155
+ else
156
+ raise IndexError, "Key #{key} does not exist"
157
+ end
158
+ end
159
+
160
+ # Writing this method hurts me a little bit.
161
+ #
162
+ # TODO: Refactor all this stuff so this kind of horror is no longer needed
163
+ #
164
+ # We have invented a new kind of duck-typing, we call it Madoff typing.
165
+ # We just lie and hope we die before you recognize our scheme. :)
166
+ def kind_of?(klass)
167
+ if klass == Hash || klass == Mash || klass == Chef::Node::Attribute
168
+ true
169
+ else
170
+ false
171
+ end
172
+ end
173
+
174
+ def has_value?(value)
175
+ self.any? do |k,v|
176
+ value == v
177
+ end
178
+ end
179
+
180
+ alias :value? :has_value?
181
+
182
+ def index(value)
183
+ index = self.find do |h|
184
+ value == h[1]
185
+ end
186
+ index.first if index.is_a? Array || nil
187
+ end
188
+
189
+ def values
190
+ self.collect { |h| h[1] }
191
+ end
192
+
193
+ def size
194
+ self.collect{}.length
195
+ end
196
+
197
+ alias :length :size
198
+
199
+ def get_keys
200
+ keys
201
+ end
202
+
203
+ def keys
204
+ tkeys = []
205
+ if current_override
206
+ tkeys = current_override.keys
207
+ end
208
+ if current_attribute
209
+ current_attribute.keys.each do |key|
210
+ tkeys << key unless tkeys.include?(key)
211
+ end
212
+ end
213
+ if current_default
214
+ current_default.keys.each do |key|
215
+ tkeys << key unless tkeys.include?(key)
216
+ end
217
+ end
218
+ tkeys
219
+ end
220
+
221
+ def get_value(data_hash, key)
222
+ last = nil
223
+
224
+ if state.length == 0
225
+ if data_hash.has_key?(key) && ! data_hash[key].nil?
226
+ return data_hash[key]
227
+ else
228
+ return nil
229
+ end
230
+ end
231
+
232
+ 0.upto(state.length) do |i|
233
+ if i == 0
234
+ last = auto_vivifiy(data_hash, state[i])
235
+ elsif i == state.length
236
+ fk = last[state[i - 1]]
237
+ if fk.has_key?(key) && ! fk[key].nil?
238
+ return fk[key]
239
+ else
240
+ return nil
241
+ end
242
+ else
243
+ last = auto_vivifiy(last[state[i - 1]], state[i])
244
+ end
245
+ end
246
+ end
247
+
248
+ def hash_and_not_cna?(to_check)
249
+ (! to_check.kind_of?(Chef::Node::Attribute)) && to_check.respond_to?(:has_key?)
250
+ end
251
+
252
+ def determine_value(o_value, a_value, d_value)
253
+ # If all three have hash values, merge them
254
+ if hash_and_not_cna?(o_value) && hash_and_not_cna?(a_value) && hash_and_not_cna?(d_value)
255
+ value = Chef::Mixin::DeepMerge.merge(d_value, a_value)
256
+ value = Chef::Mixin::DeepMerge.merge(value, o_value)
257
+ value
258
+ # If only the override and attributes have values, merge them
259
+ elsif hash_and_not_cna?(o_value) && hash_and_not_cna?(a_value)
260
+ Chef::Mixin::DeepMerge.merge(a_value, o_value)
261
+ # If only the override and default attributes have values, merge them
262
+ elsif hash_and_not_cna?(o_value) && hash_and_not_cna?(d_value)
263
+ Chef::Mixin::DeepMerge.merge(d_value, o_value)
264
+ # If only the override attribute has a value (any value) use it
265
+ elsif ! o_value.nil?
266
+ o_value
267
+ # If the attributes is a hash, and the default is a hash, merge them
268
+ elsif hash_and_not_cna?(a_value) && hash_and_not_cna?(d_value)
269
+ Chef::Mixin::DeepMerge.merge(d_value, a_value)
270
+ # If we have an attribute value, use it
271
+ elsif ! a_value.nil?
272
+ a_value
273
+ # If we have a default value, use it
274
+ elsif ! d_value.nil?
275
+ d_value
276
+ else
277
+ nil
278
+ end
279
+ end
280
+
281
+ def []=(key, value)
282
+ if set_unless_value_present
283
+ if get_value(@default, key) != nil
284
+ Chef::Log.debug("Not setting #{state.join("/")}/#{key} to #{value.inspect} because it has a default value already")
285
+ return false
286
+ end
287
+ if get_value(@attribute, key) != nil
288
+ Chef::Log.debug("Not setting #{state.join("/")}/#{key} to #{value.inspect} because it has a node attribute value already")
289
+ return false
290
+ end
291
+ if get_value(@override, key) != nil
292
+ Chef::Log.debug("Not setting #{state.join("/")}/#{key} to #{value.inspect} because it has an override value already")
293
+ return false
294
+ end
295
+ end
296
+
297
+ # If we have been read, and the key we are writing is the same
298
+ # as our parent, we have most like been ||='ed. So we need to
299
+ # just rewind a bit.
300
+ #
301
+ # In practice, these objects are single use - this is just
302
+ # supporting one more single-use style.
303
+ @state.pop if @has_been_read && @state.last == key
304
+
305
+ set_value(@attribute, key, value)
306
+ set_value(@override, key, value)
307
+ value
308
+ end
309
+
310
+ def set_value(data_hash, key, value)
311
+ last = nil
312
+
313
+ # If there is no state, just set the value
314
+ if state.length == 0
315
+ data_hash[key] = value
316
+ return data_hash
317
+ end
318
+
319
+ # Walk all the previous places we have been
320
+ 0.upto(state.length) do |i|
321
+ # If we are the first, we are top level, and should vivifiy the data_hash
322
+ if i == 0
323
+ last = auto_vivifiy(data_hash, state[i])
324
+ # If we are one past the last state, we are adding a key to that hash with a value
325
+ elsif i == state.length
326
+ last[state[i - 1]][key] = value
327
+ # Otherwise, we're auto-vivifiy-ing an interim mash
328
+ else
329
+ last = auto_vivifiy(last[state[i - 1]], state[i])
330
+ end
331
+ end
332
+ data_hash
333
+ end
334
+
335
+ def auto_vivifiy(data_hash, key)
336
+ if data_hash.has_key?(key)
337
+ unless data_hash[key].respond_to?(:has_key?)
338
+ raise ArgumentError, "You tried to set a nested key, where the parent is not a hash-like object: #{@state.join("/")}/#{key} " unless auto_vivifiy_on_read
339
+ end
340
+ else
341
+ data_hash[key] = Mash.new
342
+ end
343
+ data_hash
344
+ end
345
+
346
+ def value_or_descend(data_hash, key, auto_vivifiy=false)
347
+
348
+ if auto_vivifiy
349
+ data_hash = auto_vivifiy(data_hash, key)
350
+ unless current_attribute.has_key?(key)
351
+ current_attribute[key] = data_hash[key]
352
+ end
353
+ unless current_default.has_key?(key)
354
+ current_default[key] = data_hash[key]
355
+ end
356
+ unless current_override.has_key?(key)
357
+ current_override[key] = data_hash[key]
358
+ end
359
+ else
360
+ return nil if data_hash == nil
361
+ return nil unless data_hash.has_key?(key)
362
+ end
363
+
364
+ if data_hash[key].respond_to?(:has_key?)
365
+ cna = Chef::Node::Attribute.new(@attribute, @default, @override, @state)
366
+ cna.current_attribute = current_attribute.nil? ? Mash.new : current_attribute[key]
367
+ cna.current_default = current_default.nil? ? Mash.new : current_default[key]
368
+ cna.current_override = current_override.nil? ? Mash.new : current_override[key]
369
+ cna.auto_vivifiy_on_read = auto_vivifiy_on_read
370
+ cna.set_unless_value_present = set_unless_value_present
371
+ cna
372
+ else
373
+ data_hash[key]
374
+ end
375
+ end
376
+
377
+ def method_missing(symbol, *args)
378
+ by = symbol
379
+ if self.attribute?(symbol)
380
+ by = symbol
381
+ elsif self.attribute?(symbol.to_s)
382
+ by = symbol.to_s
383
+ else
384
+ if args.length != 0
385
+ by = symbol
386
+ else
387
+ raise ArgumentError, "Attribute #{symbol.to_s} is not defined!" unless auto_vivifiy_on_read
388
+ end
389
+ end
390
+
391
+ if args.length != 0
392
+ if by.to_s =~ /^(.+)=$/
393
+ by = $1
394
+ end
395
+ self[by] = args.length == 1 ? args[0] : args
396
+ else
397
+ self[by]
398
+ end
399
+ end
400
+
401
+ def to_hash
402
+ result = determine_value(current_override, current_attribute, current_default)
403
+ if result.class == Hash
404
+ result
405
+ else
406
+ result.to_hash
407
+ end
408
+ end
409
+
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,181 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/config'
20
+ require 'chef/mixin/params_validate'
21
+ require 'chef/couchdb'
22
+ require 'digest/sha1'
23
+ require 'rubygems'
24
+ require 'json'
25
+
26
+ class Chef
27
+ class OpenIDRegistration
28
+
29
+ attr_accessor :name, :salt, :validated, :password, :couchdb_rev, :admin
30
+
31
+ include Chef::Mixin::ParamsValidate
32
+
33
+ DESIGN_DOCUMENT = {
34
+ "version" => 3,
35
+ "language" => "javascript",
36
+ "views" => {
37
+ "all" => {
38
+ "map" => <<-EOJS
39
+ function(doc) {
40
+ if (doc.chef_type == "openid_registration") {
41
+ emit(doc.name, doc);
42
+ }
43
+ }
44
+ EOJS
45
+ },
46
+ "all_id" => {
47
+ "map" => <<-EOJS
48
+ function(doc) {
49
+ if (doc.chef_type == "openid_registration") {
50
+ emit(doc.name, doc.name);
51
+ }
52
+ }
53
+ EOJS
54
+ },
55
+ "validated" => {
56
+ "map" => <<-EOJS
57
+ function(doc) {
58
+ if (doc.chef_type == "openid_registration") {
59
+ if (doc.validated == true) {
60
+ emit(doc.name, doc);
61
+ }
62
+ }
63
+ }
64
+ EOJS
65
+ },
66
+ "unvalidated" => {
67
+ "map" => <<-EOJS
68
+ function(doc) {
69
+ if (doc.chef_type == "openid_registration") {
70
+ if (doc.validated == false) {
71
+ emit(doc.name, doc);
72
+ }
73
+ }
74
+ }
75
+ EOJS
76
+ },
77
+ },
78
+ }
79
+
80
+ # Create a new Chef::OpenIDRegistration object.
81
+ def initialize()
82
+ @name = nil
83
+ @salt = nil
84
+ @password = nil
85
+ @validated = false
86
+ @admin = false
87
+ @couchdb_rev = nil
88
+ @couchdb = Chef::CouchDB.new
89
+ end
90
+
91
+ def name=(n)
92
+ @name = n.gsub(/\./, '_')
93
+ end
94
+
95
+ # Set the password for this object.
96
+ def set_password(password)
97
+ @salt = generate_salt
98
+ @password = encrypt_password(@salt, password)
99
+ end
100
+
101
+ # Serialize this object as a hash
102
+ def to_json(*a)
103
+ attributes = Hash.new
104
+ recipes = Array.new
105
+ result = {
106
+ 'name' => @name,
107
+ 'json_class' => self.class.name,
108
+ 'salt' => @salt,
109
+ 'password' => @password,
110
+ 'validated' => @validated,
111
+ 'admin' => @admin,
112
+ 'chef_type' => 'openid_registration',
113
+ }
114
+ result["_rev"] = @couchdb_rev if @couchdb_rev
115
+ result.to_json(*a)
116
+ end
117
+
118
+ # Create a Chef::Node from JSON
119
+ def self.json_create(o)
120
+ me = new
121
+ me.name = o["name"]
122
+ me.salt = o["salt"]
123
+ me.password = o["password"]
124
+ me.validated = o["validated"]
125
+ me.admin = o["admin"]
126
+ me.couchdb_rev = o["_rev"] if o.has_key?("_rev")
127
+ me
128
+ end
129
+
130
+ # List all the Chef::OpenIDRegistration objects in the CouchDB. If inflate is set to true, you will get
131
+ # the full list of all registration objects. Otherwise, you'll just get the IDs
132
+ def self.list(inflate=false)
133
+ rs = Chef::CouchDB.new.list("registrations", inflate)
134
+ if inflate
135
+ rs["rows"].collect { |r| r["value"] }
136
+ else
137
+ rs["rows"].collect { |r| r["key"] }
138
+ end
139
+ end
140
+
141
+ # Load an OpenIDRegistration by name from CouchDB
142
+ def self.load(name)
143
+ Chef::CouchDB.new.load("openid_registration", name)
144
+ end
145
+
146
+ # Whether or not there is an OpenID Registration with this key.
147
+ def self.has_key?(name)
148
+ Chef::CouchDB.new.has_key?("openid_registration", name)
149
+ end
150
+
151
+ # Remove this node from the CouchDB
152
+ def destroy
153
+ @couchdb.delete("openid_registration", @name, @couchdb_rev)
154
+ end
155
+
156
+ # Save this node to the CouchDB
157
+ def save
158
+ results = @couchdb.store("openid_registration", @name, self)
159
+ @couchdb_rev = results["rev"]
160
+ end
161
+
162
+ # Set up our CouchDB design document
163
+ def self.create_design_document
164
+ Chef::CouchDB.new.create_design_document("registrations", DESIGN_DOCUMENT)
165
+ end
166
+
167
+ protected
168
+
169
+ def generate_salt
170
+ salt = Time.now.to_s
171
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
172
+ 1.upto(30) { |i| salt << chars[rand(chars.size-1)] }
173
+ salt
174
+ end
175
+
176
+ def encrypt_password(salt, password)
177
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
178
+ end
179
+
180
+ end
181
+ end