runa-chef 0.8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +136 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +26 -0
  5. data/bin/knife +27 -0
  6. data/bin/shef +45 -0
  7. data/distro/README +2 -0
  8. data/distro/common/man/man1/chef-indexer.1 +42 -0
  9. data/distro/common/man/man1/chef-server.1 +108 -0
  10. data/distro/common/man/man8/chef-client.8 +61 -0
  11. data/distro/common/man/man8/chef-solo.8 +58 -0
  12. data/distro/common/man/man8/knife.8 +359 -0
  13. data/distro/debian/etc/init.d/chef-client +175 -0
  14. data/distro/debian/etc/init.d/chef-indexer +175 -0
  15. data/distro/debian/etc/init.d/chef-server +120 -0
  16. data/distro/redhat/etc/init.d/chef-client +78 -0
  17. data/distro/redhat/etc/init.d/chef-indexer +76 -0
  18. data/distro/redhat/etc/init.d/chef-server +78 -0
  19. data/distro/redhat/etc/sysconfig/chef-client +10 -0
  20. data/distro/redhat/etc/sysconfig/chef-indexer +8 -0
  21. data/distro/redhat/etc/sysconfig/chef-server +10 -0
  22. data/distro/suse/etc/init.d/chef-client +121 -0
  23. data/lib/chef.rb +49 -0
  24. data/lib/chef/api_client.rb +269 -0
  25. data/lib/chef/application.rb +98 -0
  26. data/lib/chef/application/agent.rb +18 -0
  27. data/lib/chef/application/client.rb +214 -0
  28. data/lib/chef/application/knife.rb +138 -0
  29. data/lib/chef/application/server.rb +19 -0
  30. data/lib/chef/application/solo.rb +214 -0
  31. data/lib/chef/cache.rb +61 -0
  32. data/lib/chef/cache/checksum.rb +70 -0
  33. data/lib/chef/certificate.rb +154 -0
  34. data/lib/chef/client.rb +323 -0
  35. data/lib/chef/compile.rb +158 -0
  36. data/lib/chef/config.rb +195 -0
  37. data/lib/chef/cookbook.rb +198 -0
  38. data/lib/chef/cookbook/metadata.rb +487 -0
  39. data/lib/chef/cookbook/metadata/version.rb +87 -0
  40. data/lib/chef/cookbook_loader.rb +180 -0
  41. data/lib/chef/couchdb.rb +273 -0
  42. data/lib/chef/daemon.rb +170 -0
  43. data/lib/chef/data_bag.rb +216 -0
  44. data/lib/chef/data_bag_item.rb +227 -0
  45. data/lib/chef/exceptions.rb +39 -0
  46. data/lib/chef/file_cache.rb +205 -0
  47. data/lib/chef/knife.rb +300 -0
  48. data/lib/chef/knife/client_bulk_delete.rb +41 -0
  49. data/lib/chef/knife/client_create.rb +55 -0
  50. data/lib/chef/knife/client_delete.rb +37 -0
  51. data/lib/chef/knife/client_edit.rb +37 -0
  52. data/lib/chef/knife/client_list.rb +40 -0
  53. data/lib/chef/knife/client_reregister.rb +48 -0
  54. data/lib/chef/knife/client_show.rb +42 -0
  55. data/lib/chef/knife/configure.rb +84 -0
  56. data/lib/chef/knife/cookbook_bulk_delete.rb +47 -0
  57. data/lib/chef/knife/cookbook_delete.rb +41 -0
  58. data/lib/chef/knife/cookbook_download.rb +57 -0
  59. data/lib/chef/knife/cookbook_list.rb +41 -0
  60. data/lib/chef/knife/cookbook_metadata.rb +87 -0
  61. data/lib/chef/knife/cookbook_show.rb +75 -0
  62. data/lib/chef/knife/cookbook_upload.rb +173 -0
  63. data/lib/chef/knife/data_bag_create.rb +43 -0
  64. data/lib/chef/knife/data_bag_delete.rb +43 -0
  65. data/lib/chef/knife/data_bag_edit.rb +49 -0
  66. data/lib/chef/knife/data_bag_list.rb +42 -0
  67. data/lib/chef/knife/data_bag_show.rb +40 -0
  68. data/lib/chef/knife/ec2_instance_data.rb +46 -0
  69. data/lib/chef/knife/node_bulk_delete.rb +44 -0
  70. data/lib/chef/knife/node_create.rb +39 -0
  71. data/lib/chef/knife/node_delete.rb +36 -0
  72. data/lib/chef/knife/node_edit.rb +36 -0
  73. data/lib/chef/knife/node_from_file.rb +42 -0
  74. data/lib/chef/knife/node_list.rb +41 -0
  75. data/lib/chef/knife/node_run_list_add.rb +64 -0
  76. data/lib/chef/knife/node_run_list_remove.rb +45 -0
  77. data/lib/chef/knife/node_show.rb +46 -0
  78. data/lib/chef/knife/role_bulk_delete.rb +45 -0
  79. data/lib/chef/knife/role_create.rb +44 -0
  80. data/lib/chef/knife/role_delete.rb +36 -0
  81. data/lib/chef/knife/role_edit.rb +37 -0
  82. data/lib/chef/knife/role_from_file.rb +46 -0
  83. data/lib/chef/knife/role_list.rb +40 -0
  84. data/lib/chef/knife/role_show.rb +43 -0
  85. data/lib/chef/knife/search.rb +94 -0
  86. data/lib/chef/log.rb +39 -0
  87. data/lib/chef/mixin/check_helper.rb +31 -0
  88. data/lib/chef/mixin/checksum.rb +32 -0
  89. data/lib/chef/mixin/command.rb +390 -0
  90. data/lib/chef/mixin/convert_to_class_name.rb +57 -0
  91. data/lib/chef/mixin/create_path.rb +56 -0
  92. data/lib/chef/mixin/deep_merge.rb +33 -0
  93. data/lib/chef/mixin/find_preferred_file.rb +92 -0
  94. data/lib/chef/mixin/from_file.rb +50 -0
  95. data/lib/chef/mixin/generate_url.rb +58 -0
  96. data/lib/chef/mixin/language.rb +107 -0
  97. data/lib/chef/mixin/language_include_attribute.rb +56 -0
  98. data/lib/chef/mixin/language_include_recipe.rb +53 -0
  99. data/lib/chef/mixin/params_validate.rb +197 -0
  100. data/lib/chef/mixin/recipe_definition_dsl_core.rb +79 -0
  101. data/lib/chef/mixin/template.rb +94 -0
  102. data/lib/chef/nanite.rb +100 -0
  103. data/lib/chef/node.rb +463 -0
  104. data/lib/chef/node/attribute.rb +412 -0
  105. data/lib/chef/openid_registration.rb +181 -0
  106. data/lib/chef/platform.rb +268 -0
  107. data/lib/chef/provider.rb +101 -0
  108. data/lib/chef/provider/breakpoint.rb +36 -0
  109. data/lib/chef/provider/cron.rb +184 -0
  110. data/lib/chef/provider/deploy.rb +314 -0
  111. data/lib/chef/provider/deploy/revision.rb +70 -0
  112. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  113. data/lib/chef/provider/directory.rb +72 -0
  114. data/lib/chef/provider/erl_call.rb +72 -0
  115. data/lib/chef/provider/execute.rb +58 -0
  116. data/lib/chef/provider/file.rb +195 -0
  117. data/lib/chef/provider/git.rb +203 -0
  118. data/lib/chef/provider/group.rb +120 -0
  119. data/lib/chef/provider/group/dscl.rb +128 -0
  120. data/lib/chef/provider/group/gpasswd.rb +50 -0
  121. data/lib/chef/provider/group/groupadd.rb +78 -0
  122. data/lib/chef/provider/group/pw.rb +88 -0
  123. data/lib/chef/provider/group/usermod.rb +57 -0
  124. data/lib/chef/provider/http_request.rb +106 -0
  125. data/lib/chef/provider/ifconfig.rb +131 -0
  126. data/lib/chef/provider/link.rb +157 -0
  127. data/lib/chef/provider/mdadm.rb +88 -0
  128. data/lib/chef/provider/mount.rb +117 -0
  129. data/lib/chef/provider/mount/mount.rb +208 -0
  130. data/lib/chef/provider/package.rb +160 -0
  131. data/lib/chef/provider/package/apt.rb +110 -0
  132. data/lib/chef/provider/package/dpkg.rb +109 -0
  133. data/lib/chef/provider/package/easy_install.rb +106 -0
  134. data/lib/chef/provider/package/freebsd.rb +153 -0
  135. data/lib/chef/provider/package/macports.rb +105 -0
  136. data/lib/chef/provider/package/portage.rb +124 -0
  137. data/lib/chef/provider/package/rpm.rb +99 -0
  138. data/lib/chef/provider/package/rubygems.rb +136 -0
  139. data/lib/chef/provider/package/yum-dump.py +125 -0
  140. data/lib/chef/provider/package/yum.rb +175 -0
  141. data/lib/chef/provider/package/zypper.rb +132 -0
  142. data/lib/chef/provider/remote_directory.rb +126 -0
  143. data/lib/chef/provider/remote_file.rb +141 -0
  144. data/lib/chef/provider/route.rb +118 -0
  145. data/lib/chef/provider/ruby_block.rb +33 -0
  146. data/lib/chef/provider/script.rb +42 -0
  147. data/lib/chef/provider/service.rb +135 -0
  148. data/lib/chef/provider/service/debian.rb +64 -0
  149. data/lib/chef/provider/service/freebsd.rb +156 -0
  150. data/lib/chef/provider/service/gentoo.rb +54 -0
  151. data/lib/chef/provider/service/init.rb +71 -0
  152. data/lib/chef/provider/service/redhat.rb +62 -0
  153. data/lib/chef/provider/service/simple.rb +114 -0
  154. data/lib/chef/provider/subversion.rb +156 -0
  155. data/lib/chef/provider/template.rb +175 -0
  156. data/lib/chef/provider/user.rb +170 -0
  157. data/lib/chef/provider/user/dscl.rb +280 -0
  158. data/lib/chef/provider/user/pw.rb +113 -0
  159. data/lib/chef/provider/user/useradd.rb +108 -0
  160. data/lib/chef/recipe.rb +105 -0
  161. data/lib/chef/resource.rb +380 -0
  162. data/lib/chef/resource/apt_package.rb +34 -0
  163. data/lib/chef/resource/bash.rb +33 -0
  164. data/lib/chef/resource/breakpoint.rb +35 -0
  165. data/lib/chef/resource/cron.rb +179 -0
  166. data/lib/chef/resource/csh.rb +33 -0
  167. data/lib/chef/resource/deploy.rb +359 -0
  168. data/lib/chef/resource/deploy_revision.rb +35 -0
  169. data/lib/chef/resource/directory.rb +76 -0
  170. data/lib/chef/resource/dpkg_package.rb +34 -0
  171. data/lib/chef/resource/easy_install_package.rb +41 -0
  172. data/lib/chef/resource/erl_call.rb +83 -0
  173. data/lib/chef/resource/execute.rb +127 -0
  174. data/lib/chef/resource/file.rb +84 -0
  175. data/lib/chef/resource/gem_package.rb +41 -0
  176. data/lib/chef/resource/git.rb +36 -0
  177. data/lib/chef/resource/group.rb +70 -0
  178. data/lib/chef/resource/http_request.rb +52 -0
  179. data/lib/chef/resource/ifconfig.rb +134 -0
  180. data/lib/chef/resource/link.rb +78 -0
  181. data/lib/chef/resource/macports_package.rb +29 -0
  182. data/lib/chef/resource/mdadm.rb +82 -0
  183. data/lib/chef/resource/mount.rb +135 -0
  184. data/lib/chef/resource/package.rb +80 -0
  185. data/lib/chef/resource/perl.rb +33 -0
  186. data/lib/chef/resource/portage_package.rb +33 -0
  187. data/lib/chef/resource/python.rb +33 -0
  188. data/lib/chef/resource/remote_directory.rb +91 -0
  189. data/lib/chef/resource/remote_file.rb +60 -0
  190. data/lib/chef/resource/route.rb +135 -0
  191. data/lib/chef/resource/ruby.rb +33 -0
  192. data/lib/chef/resource/ruby_block.rb +39 -0
  193. data/lib/chef/resource/scm.rb +137 -0
  194. data/lib/chef/resource/script.rb +51 -0
  195. data/lib/chef/resource/service.rb +134 -0
  196. data/lib/chef/resource/subversion.rb +34 -0
  197. data/lib/chef/resource/template.rb +60 -0
  198. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  199. data/lib/chef/resource/user.rb +101 -0
  200. data/lib/chef/resource_collection.rb +212 -0
  201. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  202. data/lib/chef/resource_definition.rb +67 -0
  203. data/lib/chef/rest.rb +298 -0
  204. data/lib/chef/role.rb +301 -0
  205. data/lib/chef/run_list.rb +164 -0
  206. data/lib/chef/runner.rb +130 -0
  207. data/lib/chef/search/query.rb +71 -0
  208. data/lib/chef/shef.rb +220 -0
  209. data/lib/chef/shef/ext.rb +297 -0
  210. data/lib/chef/shef/shef_session.rb +175 -0
  211. data/lib/chef/streaming_cookbook_uploader.rb +185 -0
  212. data/lib/chef/tasks/chef_repo.rake +245 -0
  213. data/lib/chef/util/file_edit.rb +125 -0
  214. data/lib/chef/util/fileedit.rb +121 -0
  215. data/lib/chef/webui_user.rb +231 -0
  216. metadata +398 -0
@@ -0,0 +1,125 @@
1
+ #
2
+ # Author:: Nuo Yan (<nuo@opscode.com>)
3
+ # Copyright:: Copyright (c) 2009 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
+ require 'ftools'
19
+ require 'fileutils'
20
+ require 'tempfile'
21
+
22
+ class Chef
23
+ class Util
24
+ class FileEdit
25
+
26
+ private
27
+
28
+ attr_accessor :original_pathname, :contents, :file_edited
29
+
30
+ public
31
+
32
+ def initialize(filepath)
33
+ @original_pathname = filepath
34
+ @file_edited = false
35
+
36
+ raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
37
+ raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
38
+ end
39
+
40
+ #search the file line by line and match each line with the given regex
41
+ #if matched, replace the whole line with newline.
42
+ def search_file_replace_line(regex, newline)
43
+ search_match(regex, newline, 'r', 1)
44
+ end
45
+
46
+ #search the file line by line and match each line with the given regex
47
+ #if matched, replace the match (all occurances) with the replace parameter
48
+ def search_file_replace(regex, replace)
49
+ search_match(regex, replace, 'r', 2)
50
+ end
51
+
52
+ #search the file line by line and match each line with the given regex
53
+ #if matched, delete the line
54
+ def search_file_delete_line(regex)
55
+ search_match(regex, " ", 'd', 1)
56
+ end
57
+
58
+ #search the file line by line and match each line with the given regex
59
+ #if matched, delete the match (all occurances) from the line
60
+ def search_file_delete(regex)
61
+ search_match(regex, " ", 'd', 2)
62
+ end
63
+
64
+ #search the file line by line and match each line with the given regex
65
+ #if matched, insert newline after each matching line
66
+ def insert_line_after_match(regex, newline)
67
+ search_match(regex, newline, 'i', 0)
68
+ end
69
+
70
+ #Make a copy of old_file and write new file out (only if file changed)
71
+ def write_file
72
+
73
+ # file_edited is false when there was no match in the whole file and thus no contents have changed.
74
+ if file_edited
75
+ backup_pathname = original_pathname + ".old"
76
+ File.copy(original_pathname, backup_pathname)
77
+ Tempfile.open("w") do |newfile|
78
+ contents.each do |line|
79
+ newfile.puts(line)
80
+ end
81
+ newfile.flush
82
+ FileUtils.mv(newfile.path, original_pathname)
83
+ end
84
+ end
85
+ self.file_edited = false
86
+
87
+ end
88
+
89
+ private
90
+
91
+ #helper method to do the match, replace, delete, and insert operations
92
+ #command is the switch of delete, replace, and insert ('d', 'r', 'i')
93
+ #method is to control operation on whole line or only the match (1 for line, 2 for match)
94
+ def search_match(regex, replace, command, method)
95
+
96
+ #convert regex to a Regexp object (if not already is one) and store it in exp.
97
+ exp = Regexp.new(regex)
98
+
99
+ #loop through contents and do the appropriate operation depending on 'command' and 'method'
100
+ new_contents = []
101
+
102
+ contents.each do |line|
103
+ if line.match(exp)
104
+ self.file_edited = true
105
+ case
106
+ when command == 'r'
107
+ new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
108
+ when command == 'd'
109
+ if method == 2
110
+ new_contents << line.gsub!(exp, "")
111
+ end
112
+ when command == 'i'
113
+ new_contents << line
114
+ new_contents << replace
115
+ end
116
+ else
117
+ new_contents << line
118
+ end
119
+ end
120
+
121
+ self.contents = new_contents
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,121 @@
1
+ #
2
+ # Author:: Nuo Yan (<nuo@opscode.com>)
3
+ # Copyright:: Copyright (c) 2009 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
+ require 'ftools'
19
+ require 'fileutils'
20
+ require 'tempfile'
21
+
22
+ class FileEdit
23
+
24
+ private
25
+
26
+ attr_accessor :original_pathname, :contents, :file_edited
27
+
28
+ public
29
+
30
+ def initialize(filepath)
31
+ @original_pathname = filepath
32
+ @file_edited = false
33
+
34
+ raise ArgumentError, "File doesn't exist" unless File.exist? @original_pathname
35
+ raise ArgumentError, "File is blank" unless (@contents = File.new(@original_pathname).readlines).length > 0
36
+ end
37
+
38
+ #search the file line by line and match each line with the given regex
39
+ #if matched, replace the whole line with newline.
40
+ def search_file_replace_line(regex, newline)
41
+ search_match(regex, newline, 'r', 1)
42
+ end
43
+
44
+ #search the file line by line and match each line with the given regex
45
+ #if matched, replace the match (all occurances) with the replace parameter
46
+ def search_file_replace(regex, replace)
47
+ search_match(regex, replace, 'r', 2)
48
+ end
49
+
50
+ #search the file line by line and match each line with the given regex
51
+ #if matched, delete the line
52
+ def search_file_delete_line(regex)
53
+ search_match(regex, " ", 'd', 1)
54
+ end
55
+
56
+ #search the file line by line and match each line with the given regex
57
+ #if matched, delete the match (all occurances) from the line
58
+ def search_file_delete(regex)
59
+ search_match(regex, " ", 'd', 2)
60
+ end
61
+
62
+ #search the file line by line and match each line with the given regex
63
+ #if matched, insert newline after each matching line
64
+ def insert_line_after_match(regex, newline)
65
+ search_match(regex, newline, 'i', 0)
66
+ end
67
+
68
+ #Make a copy of old_file and write new file out (only if file changed)
69
+ def write_file
70
+
71
+ # file_edited is false when there was no match in the whole file and thus no contents have changed.
72
+ if file_edited
73
+ backup_pathname = original_pathname + ".old"
74
+ File.copy(original_pathname, backup_pathname)
75
+ Tempfile.open("w") do |newfile|
76
+ contents.each do |line|
77
+ newfile.puts(line)
78
+ end
79
+ newfile.flush
80
+ FileUtils.mv(newfile.path, original_pathname)
81
+ end
82
+ end
83
+ self.file_edited = false
84
+
85
+ end
86
+
87
+ private
88
+
89
+ #helper method to do the match, replace, delete, and insert operations
90
+ #command is the switch of delete, replace, and insert ('d', 'r', 'i')
91
+ #method is to control operation on whole line or only the match (1 for line, 2 for match)
92
+ def search_match(regex, replace, command, method)
93
+
94
+ #convert regex to a Regexp object (if not already is one) and store it in exp.
95
+ exp = Regexp.new(regex)
96
+
97
+ #loop through contents and do the appropriate operation depending on 'command' and 'method'
98
+ new_contents = []
99
+
100
+ contents.each do |line|
101
+ if line.match(exp)
102
+ self.file_edited = true
103
+ case
104
+ when command == 'r'
105
+ new_contents << ((method == 1) ? replace : line.gsub!(exp, replace))
106
+ when command == 'd'
107
+ if method == 2
108
+ new_contents << line.gsub!(exp, "")
109
+ end
110
+ when command == 'i'
111
+ new_contents << line
112
+ new_contents << replace
113
+ end
114
+ else
115
+ new_contents << line
116
+ end
117
+ end
118
+
119
+ self.contents = new_contents
120
+ end
121
+ end
@@ -0,0 +1,231 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Nuo Yan (<nuo@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/config'
21
+ require 'chef/mixin/params_validate'
22
+ require 'chef/couchdb'
23
+ require 'digest/sha1'
24
+ require 'rubygems'
25
+ require 'json'
26
+
27
+ class Chef
28
+ class WebUIUser
29
+
30
+ attr_accessor :name, :salt, :validated, :password, :couchdb_rev, :admin, :openid
31
+
32
+ include Chef::Mixin::ParamsValidate
33
+
34
+ DESIGN_DOCUMENT = {
35
+ "version" => 3,
36
+ "language" => "javascript",
37
+ "views" => {
38
+ "all" => {
39
+ "map" => <<-EOJS
40
+ function(doc) {
41
+ if (doc.chef_type == "webui_user") {
42
+ emit(doc.name, doc);
43
+ }
44
+ }
45
+ EOJS
46
+ },
47
+ "all_id" => {
48
+ "map" => <<-EOJS
49
+ function(doc) {
50
+ if (doc.chef_type == "webui_user") {
51
+ emit(doc.name, doc.name);
52
+ }
53
+ }
54
+ EOJS
55
+ },
56
+ },
57
+ }
58
+
59
+ # Create a new Chef::WebUIUser object.
60
+ def initialize()
61
+ @name = nil
62
+ @salt = nil
63
+ @password = nil
64
+ @admin = false
65
+ @openid = nil
66
+ @couchdb_rev = nil
67
+ @couchdb = Chef::CouchDB.new
68
+ end
69
+
70
+ def name=(n)
71
+ @name = n.gsub(/\./, '_')
72
+ end
73
+
74
+ # Set the password for this object.
75
+ def set_password(password, confirm_password=password)
76
+ raise ArgumentError, "Passwords do not match" unless password == confirm_password
77
+ raise ArgumentError, "Password cannot be blank" if (password.nil? || password.length==0)
78
+ raise ArgumentError, "Password must be a minimum of 6 characters" if password.length < 6
79
+ @salt = generate_salt
80
+ @password = encrypt_password(@salt, password)
81
+ end
82
+
83
+ def set_openid(given_openid)
84
+ @openid = given_openid
85
+ end
86
+
87
+ def verify_password(given_password)
88
+ encrypt_password(@salt, given_password) == @password ? true : false
89
+ end
90
+
91
+ # Serialize this object as a hash
92
+ def to_json(*a)
93
+ attributes = Hash.new
94
+ recipes = Array.new
95
+ result = {
96
+ 'name' => @name,
97
+ 'json_class' => self.class.name,
98
+ 'salt' => @salt,
99
+ 'password' => @password,
100
+ 'openid' => @openid,
101
+ 'admin' => @admin,
102
+ 'chef_type' => 'webui_user',
103
+ }
104
+ result["_rev"] = @couchdb_rev if @couchdb_rev
105
+ result.to_json(*a)
106
+ end
107
+
108
+ # Create a Chef::WebUIUser from JSON
109
+ def self.json_create(o)
110
+ me = new
111
+ me.name = o["name"]
112
+ me.salt = o["salt"]
113
+ me.password = o["password"]
114
+ me.openid = o["openid"]
115
+ me.admin = o["admin"]
116
+ me.couchdb_rev = o["_rev"] if o.has_key?("_rev")
117
+ me
118
+ end
119
+
120
+ # List all the Chef::WebUIUser objects in the CouchDB. If inflate is set to true, you will get
121
+ # the full list of all registration objects. Otherwise, you'll just get the IDs
122
+ def self.cdb_list(inflate=false)
123
+ rs = Chef::CouchDB.new.list("users", inflate)
124
+ if inflate
125
+ rs["rows"].collect { |r| r["value"] }
126
+ else
127
+ rs["rows"].collect { |r| r["key"] }
128
+ end
129
+ end
130
+
131
+ def self.list(inflate=false)
132
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
133
+ if inflate
134
+ response = Hash.new
135
+ Chef::Search::Query.new.search(:user) do |n|
136
+ response[n.name] = n unless n.nil?
137
+ end
138
+ response
139
+ else
140
+ r.get_rest("users")
141
+ end
142
+ end
143
+
144
+ # Load an WebUIUser by name from CouchDB
145
+ def self.cdb_load(name)
146
+ Chef::CouchDB.new.load("webui_user", name)
147
+ end
148
+
149
+ # Load a User by name
150
+ def self.load(name)
151
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
152
+ r.get_rest("users/#{name}")
153
+ end
154
+
155
+
156
+ # Whether or not there is an WebUIUser with this key.
157
+ def self.has_key?(name)
158
+ Chef::CouchDB.new.has_key?("webui_user", name)
159
+ end
160
+
161
+ # Remove this WebUIUser from the CouchDB
162
+ def cdb_destroy
163
+ @couchdb.delete("webui_user", @name, @couchdb_rev)
164
+ end
165
+
166
+ # Remove this WebUIUser via the REST API
167
+ def destroy
168
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
169
+ r.delete_rest("users/#{@name}")
170
+ end
171
+
172
+ # Save this WebUIUser to the CouchDB
173
+ def cdb_save
174
+ results = @couchdb.store("webui_user", @name, self)
175
+ @couchdb_rev = results["rev"]
176
+ end
177
+
178
+ # Save this WebUIUser via the REST API
179
+ def save
180
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
181
+ begin
182
+ r.put_rest("users/#{@name}", self)
183
+ rescue Net::HTTPServerException => e
184
+ if e.response.code == "404"
185
+ r.post_rest("users", self)
186
+ else
187
+ raise e
188
+ end
189
+ end
190
+ self
191
+ end
192
+
193
+ # Create the WebUIUser via the REST API
194
+ def create
195
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
196
+ r.post_rest("users", self)
197
+ self
198
+ end
199
+
200
+ # Set up our CouchDB design document
201
+ def self.create_design_document
202
+ Chef::CouchDB.new.create_design_document("users", DESIGN_DOCUMENT)
203
+ end
204
+
205
+ #return true if an admin user exists. this is pretty expensive (O(n)), should think of a better way (nuo)
206
+ def self.admin_exist
207
+ users = self.cdb_list
208
+ users.each do |u|
209
+ user = self.cdb_load(u)
210
+ if user.admin
211
+ return user.name
212
+ end
213
+ end
214
+ nil
215
+ end
216
+
217
+ protected
218
+
219
+ def generate_salt
220
+ salt = Time.now.to_s
221
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
222
+ 1.upto(30) { |i| salt << chars[rand(chars.size-1)] }
223
+ salt
224
+ end
225
+
226
+ def encrypt_password(salt, password)
227
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
228
+ end
229
+
230
+ end
231
+ end