tylerrick-chef 0.10.8

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 (450) hide show
  1. data/LICENSE +201 -0
  2. data/README.rdoc +171 -0
  3. data/bin/chef-client +26 -0
  4. data/bin/chef-solo +25 -0
  5. data/bin/knife +26 -0
  6. data/bin/shef +34 -0
  7. data/distro/README +2 -0
  8. data/distro/arch/etc/conf.d/chef-client.conf +5 -0
  9. data/distro/arch/etc/conf.d/chef-expander.conf +8 -0
  10. data/distro/arch/etc/conf.d/chef-server-webui.conf +10 -0
  11. data/distro/arch/etc/conf.d/chef-server.conf +10 -0
  12. data/distro/arch/etc/conf.d/chef-solr.conf +8 -0
  13. data/distro/arch/etc/rc.d/chef-client +76 -0
  14. data/distro/arch/etc/rc.d/chef-expander +78 -0
  15. data/distro/arch/etc/rc.d/chef-server +78 -0
  16. data/distro/arch/etc/rc.d/chef-server-webui +78 -0
  17. data/distro/arch/etc/rc.d/chef-solr +78 -0
  18. data/distro/common/html/chef-client.8.html +146 -0
  19. data/distro/common/html/chef-expander.8.html +164 -0
  20. data/distro/common/html/chef-expanderctl.8.html +146 -0
  21. data/distro/common/html/chef-server-webui.8.html +185 -0
  22. data/distro/common/html/chef-server.8.html +182 -0
  23. data/distro/common/html/chef-solo.8.html +191 -0
  24. data/distro/common/html/chef-solr.8.html +165 -0
  25. data/distro/common/html/knife-bootstrap.1.html +243 -0
  26. data/distro/common/html/knife-client.1.html +219 -0
  27. data/distro/common/html/knife-configure.1.html +170 -0
  28. data/distro/common/html/knife-cookbook-site.1.html +241 -0
  29. data/distro/common/html/knife-cookbook.1.html +384 -0
  30. data/distro/common/html/knife-data-bag.1.html +234 -0
  31. data/distro/common/html/knife-environment.1.html +267 -0
  32. data/distro/common/html/knife-exec.1.html +134 -0
  33. data/distro/common/html/knife-index.1.html +125 -0
  34. data/distro/common/html/knife-node.1.html +250 -0
  35. data/distro/common/html/knife-recipe.1.html +92 -0
  36. data/distro/common/html/knife-role.1.html +200 -0
  37. data/distro/common/html/knife-search.1.html +288 -0
  38. data/distro/common/html/knife-ssh.1.html +157 -0
  39. data/distro/common/html/knife-status.1.html +128 -0
  40. data/distro/common/html/knife-tag.1.html +137 -0
  41. data/distro/common/html/knife.1.html +321 -0
  42. data/distro/common/html/shef.1.html +283 -0
  43. data/distro/common/man/man1/knife-bootstrap.1 +197 -0
  44. data/distro/common/man/man1/knife-client.1 +99 -0
  45. data/distro/common/man/man1/knife-configure.1 +88 -0
  46. data/distro/common/man/man1/knife-cookbook-site.1 +145 -0
  47. data/distro/common/man/man1/knife-cookbook.1 +345 -0
  48. data/distro/common/man/man1/knife-data-bag.1 +130 -0
  49. data/distro/common/man/man1/knife-environment.1 +178 -0
  50. data/distro/common/man/man1/knife-exec.1 +46 -0
  51. data/distro/common/man/man1/knife-index.1 +29 -0
  52. data/distro/common/man/man1/knife-node.1 +134 -0
  53. data/distro/common/man/man1/knife-role.1 +88 -0
  54. data/distro/common/man/man1/knife-search.1 +280 -0
  55. data/distro/common/man/man1/knife-ssh.1 +83 -0
  56. data/distro/common/man/man1/knife-status.1 +29 -0
  57. data/distro/common/man/man1/knife-tag.1 +43 -0
  58. data/distro/common/man/man1/knife.1 +292 -0
  59. data/distro/common/man/man1/shef.1 +256 -0
  60. data/distro/common/man/man8/chef-client.8 +104 -0
  61. data/distro/common/man/man8/chef-expander.8 +97 -0
  62. data/distro/common/man/man8/chef-expanderctl.8 +62 -0
  63. data/distro/common/man/man8/chef-server-webui.8 +155 -0
  64. data/distro/common/man/man8/chef-server.8 +147 -0
  65. data/distro/common/man/man8/chef-solo.8 +158 -0
  66. data/distro/common/man/man8/chef-solr.8 +122 -0
  67. data/distro/common/markdown/README +3 -0
  68. data/distro/common/markdown/man1/knife-bootstrap.mkd +142 -0
  69. data/distro/common/markdown/man1/knife-client.mkd +103 -0
  70. data/distro/common/markdown/man1/knife-configure.mkd +70 -0
  71. data/distro/common/markdown/man1/knife-cookbook-site.mkd +123 -0
  72. data/distro/common/markdown/man1/knife-cookbook.mkd +263 -0
  73. data/distro/common/markdown/man1/knife-data-bag.mkd +117 -0
  74. data/distro/common/markdown/man1/knife-environment.mkd +151 -0
  75. data/distro/common/markdown/man1/knife-exec.mkd +37 -0
  76. data/distro/common/markdown/man1/knife-index.mkd +30 -0
  77. data/distro/common/markdown/man1/knife-node.mkd +130 -0
  78. data/distro/common/markdown/man1/knife-role.mkd +85 -0
  79. data/distro/common/markdown/man1/knife-search.mkd +180 -0
  80. data/distro/common/markdown/man1/knife-ssh.mkd +72 -0
  81. data/distro/common/markdown/man1/knife-status.mkd +36 -0
  82. data/distro/common/markdown/man1/knife-tag.mkd +39 -0
  83. data/distro/common/markdown/man1/knife.mkd +220 -0
  84. data/distro/common/markdown/man1/shef.mkd +189 -0
  85. data/distro/common/markdown/man8/chef-client.mkd +75 -0
  86. data/distro/common/markdown/man8/chef-expander.mkd +82 -0
  87. data/distro/common/markdown/man8/chef-expanderctl.mkd +58 -0
  88. data/distro/common/markdown/man8/chef-server-webui.mkd +121 -0
  89. data/distro/common/markdown/man8/chef-server.mkd +121 -0
  90. data/distro/common/markdown/man8/chef-solo.mkd +107 -0
  91. data/distro/common/markdown/man8/chef-solr.mkd +89 -0
  92. data/distro/debian/etc/default/chef-client +4 -0
  93. data/distro/debian/etc/default/chef-expander +8 -0
  94. data/distro/debian/etc/default/chef-server +9 -0
  95. data/distro/debian/etc/default/chef-server-webui +9 -0
  96. data/distro/debian/etc/default/chef-solr +8 -0
  97. data/distro/debian/etc/init.d/chef-client +185 -0
  98. data/distro/debian/etc/init.d/chef-expander +176 -0
  99. data/distro/debian/etc/init.d/chef-server +122 -0
  100. data/distro/debian/etc/init.d/chef-server-webui +123 -0
  101. data/distro/debian/etc/init.d/chef-solr +176 -0
  102. data/distro/debian/etc/init/chef-client.conf +17 -0
  103. data/distro/debian/etc/init/chef-expander.conf +17 -0
  104. data/distro/debian/etc/init/chef-server-webui.conf +17 -0
  105. data/distro/debian/etc/init/chef-server.conf +17 -0
  106. data/distro/debian/etc/init/chef-solr.conf +17 -0
  107. data/distro/redhat/etc/init.d/chef-client +110 -0
  108. data/distro/redhat/etc/init.d/chef-expander +104 -0
  109. data/distro/redhat/etc/init.d/chef-server +112 -0
  110. data/distro/redhat/etc/init.d/chef-server-webui +112 -0
  111. data/distro/redhat/etc/init.d/chef-solr +104 -0
  112. data/distro/redhat/etc/logrotate.d/chef-client +8 -0
  113. data/distro/redhat/etc/logrotate.d/chef-expander +8 -0
  114. data/distro/redhat/etc/logrotate.d/chef-server +8 -0
  115. data/distro/redhat/etc/logrotate.d/chef-server-webui +8 -0
  116. data/distro/redhat/etc/logrotate.d/chef-solr +8 -0
  117. data/distro/redhat/etc/sysconfig/chef-client +15 -0
  118. data/distro/redhat/etc/sysconfig/chef-expander +7 -0
  119. data/distro/redhat/etc/sysconfig/chef-server +14 -0
  120. data/distro/redhat/etc/sysconfig/chef-server-webui +14 -0
  121. data/distro/redhat/etc/sysconfig/chef-solr +8 -0
  122. data/lib/chef.rb +41 -0
  123. data/lib/chef/api_client.rb +271 -0
  124. data/lib/chef/application.rb +152 -0
  125. data/lib/chef/application/agent.rb +18 -0
  126. data/lib/chef/application/client.rb +285 -0
  127. data/lib/chef/application/knife.rb +188 -0
  128. data/lib/chef/application/solo.rb +218 -0
  129. data/lib/chef/applications.rb +4 -0
  130. data/lib/chef/certificate.rb +194 -0
  131. data/lib/chef/checksum.rb +167 -0
  132. data/lib/chef/checksum/storage.rb +18 -0
  133. data/lib/chef/checksum/storage/filesystem.rb +56 -0
  134. data/lib/chef/checksum_cache.rb +189 -0
  135. data/lib/chef/client.rb +366 -0
  136. data/lib/chef/config.rb +248 -0
  137. data/lib/chef/cookbook/chefignore.rb +66 -0
  138. data/lib/chef/cookbook/cookbook_collection.rb +45 -0
  139. data/lib/chef/cookbook/cookbook_version_loader.rb +173 -0
  140. data/lib/chef/cookbook/file_system_file_vendor.rb +56 -0
  141. data/lib/chef/cookbook/file_vendor.rb +48 -0
  142. data/lib/chef/cookbook/metadata.rb +629 -0
  143. data/lib/chef/cookbook/remote_file_vendor.rb +88 -0
  144. data/lib/chef/cookbook/syntax_check.rb +136 -0
  145. data/lib/chef/cookbook_loader.rb +121 -0
  146. data/lib/chef/cookbook_site_streaming_uploader.rb +244 -0
  147. data/lib/chef/cookbook_uploader.rb +154 -0
  148. data/lib/chef/cookbook_version.rb +1096 -0
  149. data/lib/chef/cookbook_version_selector.rb +168 -0
  150. data/lib/chef/couchdb.rb +246 -0
  151. data/lib/chef/daemon.rb +172 -0
  152. data/lib/chef/data_bag.rb +235 -0
  153. data/lib/chef/data_bag_item.rb +273 -0
  154. data/lib/chef/encrypted_data_bag_item.rb +139 -0
  155. data/lib/chef/environment.rb +455 -0
  156. data/lib/chef/exceptions.rb +154 -0
  157. data/lib/chef/file_access_control.rb +144 -0
  158. data/lib/chef/file_cache.rb +218 -0
  159. data/lib/chef/handler.rb +227 -0
  160. data/lib/chef/handler/error_report.rb +33 -0
  161. data/lib/chef/handler/json_file.rb +58 -0
  162. data/lib/chef/index_queue.rb +29 -0
  163. data/lib/chef/index_queue/amqp_client.rb +116 -0
  164. data/lib/chef/index_queue/consumer.rb +76 -0
  165. data/lib/chef/index_queue/indexable.rb +109 -0
  166. data/lib/chef/json_compat.rb +52 -0
  167. data/lib/chef/knife.rb +520 -0
  168. data/lib/chef/knife/bootstrap.rb +207 -0
  169. data/lib/chef/knife/bootstrap/archlinux-gems.erb +60 -0
  170. data/lib/chef/knife/bootstrap/centos5-gems.erb +56 -0
  171. data/lib/chef/knife/bootstrap/fedora13-gems.erb +43 -0
  172. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +49 -0
  173. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +50 -0
  174. data/lib/chef/knife/client_bulk_delete.rb +65 -0
  175. data/lib/chef/knife/client_create.rb +79 -0
  176. data/lib/chef/knife/client_delete.rb +46 -0
  177. data/lib/chef/knife/client_edit.rb +45 -0
  178. data/lib/chef/knife/client_list.rb +42 -0
  179. data/lib/chef/knife/client_reregister.rb +58 -0
  180. data/lib/chef/knife/client_show.rb +52 -0
  181. data/lib/chef/knife/configure.rb +149 -0
  182. data/lib/chef/knife/configure_client.rb +50 -0
  183. data/lib/chef/knife/cookbook_bulk_delete.rb +72 -0
  184. data/lib/chef/knife/cookbook_create.rb +274 -0
  185. data/lib/chef/knife/cookbook_delete.rb +151 -0
  186. data/lib/chef/knife/cookbook_download.rb +137 -0
  187. data/lib/chef/knife/cookbook_list.rb +47 -0
  188. data/lib/chef/knife/cookbook_metadata.rb +107 -0
  189. data/lib/chef/knife/cookbook_metadata_from_file.rb +44 -0
  190. data/lib/chef/knife/cookbook_show.rb +102 -0
  191. data/lib/chef/knife/cookbook_site_download.rb +70 -0
  192. data/lib/chef/knife/cookbook_site_install.rb +148 -0
  193. data/lib/chef/knife/cookbook_site_list.rb +62 -0
  194. data/lib/chef/knife/cookbook_site_search.rb +51 -0
  195. data/lib/chef/knife/cookbook_site_share.rb +114 -0
  196. data/lib/chef/knife/cookbook_site_show.rb +57 -0
  197. data/lib/chef/knife/cookbook_site_unshare.rb +56 -0
  198. data/lib/chef/knife/cookbook_site_vendor.rb +46 -0
  199. data/lib/chef/knife/cookbook_test.rb +93 -0
  200. data/lib/chef/knife/cookbook_upload.rb +240 -0
  201. data/lib/chef/knife/core/bootstrap_context.rb +100 -0
  202. data/lib/chef/knife/core/cookbook_scm_repo.rb +148 -0
  203. data/lib/chef/knife/core/generic_presenter.rb +191 -0
  204. data/lib/chef/knife/core/node_editor.rb +127 -0
  205. data/lib/chef/knife/core/node_presenter.rb +136 -0
  206. data/lib/chef/knife/core/object_loader.rb +75 -0
  207. data/lib/chef/knife/core/subcommand_loader.rb +112 -0
  208. data/lib/chef/knife/core/text_formatter.rb +100 -0
  209. data/lib/chef/knife/core/ui.rb +216 -0
  210. data/lib/chef/knife/data_bag_create.rb +93 -0
  211. data/lib/chef/knife/data_bag_delete.rb +51 -0
  212. data/lib/chef/knife/data_bag_edit.rb +94 -0
  213. data/lib/chef/knife/data_bag_from_file.rb +87 -0
  214. data/lib/chef/knife/data_bag_list.rb +46 -0
  215. data/lib/chef/knife/data_bag_show.rb +81 -0
  216. data/lib/chef/knife/environment_create.rb +53 -0
  217. data/lib/chef/knife/environment_delete.rb +45 -0
  218. data/lib/chef/knife/environment_edit.rb +45 -0
  219. data/lib/chef/knife/environment_from_file.rb +50 -0
  220. data/lib/chef/knife/environment_list.rb +42 -0
  221. data/lib/chef/knife/environment_show.rb +46 -0
  222. data/lib/chef/knife/exec.rb +51 -0
  223. data/lib/chef/knife/help.rb +103 -0
  224. data/lib/chef/knife/help_topics.rb +4 -0
  225. data/lib/chef/knife/index_rebuild.rb +50 -0
  226. data/lib/chef/knife/node_bulk_delete.rb +80 -0
  227. data/lib/chef/knife/node_create.rb +50 -0
  228. data/lib/chef/knife/node_delete.rb +47 -0
  229. data/lib/chef/knife/node_edit.rb +72 -0
  230. data/lib/chef/knife/node_from_file.rb +50 -0
  231. data/lib/chef/knife/node_list.rb +46 -0
  232. data/lib/chef/knife/node_run_list_add.rb +67 -0
  233. data/lib/chef/knife/node_run_list_remove.rb +48 -0
  234. data/lib/chef/knife/node_show.rb +73 -0
  235. data/lib/chef/knife/recipe_list.rb +32 -0
  236. data/lib/chef/knife/role_bulk_delete.rb +70 -0
  237. data/lib/chef/knife/role_create.rb +55 -0
  238. data/lib/chef/knife/role_delete.rb +47 -0
  239. data/lib/chef/knife/role_edit.rb +48 -0
  240. data/lib/chef/knife/role_from_file.rb +56 -0
  241. data/lib/chef/knife/role_list.rb +43 -0
  242. data/lib/chef/knife/role_show.rb +54 -0
  243. data/lib/chef/knife/search.rb +141 -0
  244. data/lib/chef/knife/ssh.rb +367 -0
  245. data/lib/chef/knife/status.rb +104 -0
  246. data/lib/chef/knife/tag_create.rb +52 -0
  247. data/lib/chef/knife/tag_delete.rb +60 -0
  248. data/lib/chef/knife/tag_list.rb +47 -0
  249. data/lib/chef/log.rb +39 -0
  250. data/lib/chef/mash.rb +211 -0
  251. data/lib/chef/mixin/check_helper.rb +31 -0
  252. data/lib/chef/mixin/checksum.rb +32 -0
  253. data/lib/chef/mixin/command.rb +163 -0
  254. data/lib/chef/mixin/command/unix.rb +215 -0
  255. data/lib/chef/mixin/command/windows.rb +76 -0
  256. data/lib/chef/mixin/convert_to_class_name.rb +63 -0
  257. data/lib/chef/mixin/create_path.rb +57 -0
  258. data/lib/chef/mixin/deep_merge.rb +225 -0
  259. data/lib/chef/mixin/deprecation.rb +65 -0
  260. data/lib/chef/mixin/from_file.rb +50 -0
  261. data/lib/chef/mixin/get_source_from_package.rb +42 -0
  262. data/lib/chef/mixin/language.rb +163 -0
  263. data/lib/chef/mixin/language_include_attribute.rb +61 -0
  264. data/lib/chef/mixin/language_include_recipe.rb +52 -0
  265. data/lib/chef/mixin/params_validate.rb +225 -0
  266. data/lib/chef/mixin/recipe_definition_dsl_core.rb +78 -0
  267. data/lib/chef/mixin/shell_out.rb +41 -0
  268. data/lib/chef/mixin/template.rb +95 -0
  269. data/lib/chef/mixin/xml_escape.rb +140 -0
  270. data/lib/chef/mixins.rb +15 -0
  271. data/lib/chef/monkey_patches/dir.rb +36 -0
  272. data/lib/chef/monkey_patches/numeric.rb +15 -0
  273. data/lib/chef/monkey_patches/object.rb +9 -0
  274. data/lib/chef/monkey_patches/regexp.rb +34 -0
  275. data/lib/chef/monkey_patches/string.rb +49 -0
  276. data/lib/chef/monkey_patches/tempfile.rb +64 -0
  277. data/lib/chef/nil_argument.rb +3 -0
  278. data/lib/chef/node.rb +677 -0
  279. data/lib/chef/node/attribute.rb +487 -0
  280. data/lib/chef/openid_registration.rb +187 -0
  281. data/lib/chef/platform.rb +434 -0
  282. data/lib/chef/provider.rb +124 -0
  283. data/lib/chef/provider/breakpoint.rb +36 -0
  284. data/lib/chef/provider/cookbook_file.rb +100 -0
  285. data/lib/chef/provider/cron.rb +186 -0
  286. data/lib/chef/provider/cron/solaris.rb +195 -0
  287. data/lib/chef/provider/deploy.rb +418 -0
  288. data/lib/chef/provider/deploy/revision.rb +80 -0
  289. data/lib/chef/provider/deploy/timestamped.rb +33 -0
  290. data/lib/chef/provider/directory.rb +72 -0
  291. data/lib/chef/provider/env.rb +152 -0
  292. data/lib/chef/provider/env/windows.rb +75 -0
  293. data/lib/chef/provider/erl_call.rb +101 -0
  294. data/lib/chef/provider/execute.rb +65 -0
  295. data/lib/chef/provider/file.rb +226 -0
  296. data/lib/chef/provider/git.rb +243 -0
  297. data/lib/chef/provider/group.rb +133 -0
  298. data/lib/chef/provider/group/aix.rb +70 -0
  299. data/lib/chef/provider/group/dscl.rb +121 -0
  300. data/lib/chef/provider/group/gpasswd.rb +53 -0
  301. data/lib/chef/provider/group/groupadd.rb +91 -0
  302. data/lib/chef/provider/group/pw.rb +84 -0
  303. data/lib/chef/provider/group/suse.rb +53 -0
  304. data/lib/chef/provider/group/usermod.rb +57 -0
  305. data/lib/chef/provider/group/windows.rb +79 -0
  306. data/lib/chef/provider/http_request.rb +122 -0
  307. data/lib/chef/provider/ifconfig.rb +195 -0
  308. data/lib/chef/provider/link.rb +164 -0
  309. data/lib/chef/provider/log.rb +54 -0
  310. data/lib/chef/provider/mdadm.rb +91 -0
  311. data/lib/chef/provider/mount.rb +114 -0
  312. data/lib/chef/provider/mount/mount.rb +240 -0
  313. data/lib/chef/provider/mount/windows.rb +81 -0
  314. data/lib/chef/provider/ohai.rb +42 -0
  315. data/lib/chef/provider/package.rb +200 -0
  316. data/lib/chef/provider/package/apt.rb +145 -0
  317. data/lib/chef/provider/package/dpkg.rb +115 -0
  318. data/lib/chef/provider/package/easy_install.rb +136 -0
  319. data/lib/chef/provider/package/freebsd.rb +125 -0
  320. data/lib/chef/provider/package/macports.rb +105 -0
  321. data/lib/chef/provider/package/pacman.rb +101 -0
  322. data/lib/chef/provider/package/portage.rb +135 -0
  323. data/lib/chef/provider/package/rpm.rb +104 -0
  324. data/lib/chef/provider/package/rubygems.rb +465 -0
  325. data/lib/chef/provider/package/solaris.rb +130 -0
  326. data/lib/chef/provider/package/yum-dump.py +286 -0
  327. data/lib/chef/provider/package/yum.rb +1173 -0
  328. data/lib/chef/provider/package/zypper.rb +144 -0
  329. data/lib/chef/provider/remote_directory.rb +137 -0
  330. data/lib/chef/provider/remote_file.rb +118 -0
  331. data/lib/chef/provider/route.rb +193 -0
  332. data/lib/chef/provider/ruby_block.rb +34 -0
  333. data/lib/chef/provider/script.rb +55 -0
  334. data/lib/chef/provider/service.rb +122 -0
  335. data/lib/chef/provider/service/arch.rb +116 -0
  336. data/lib/chef/provider/service/debian.rb +130 -0
  337. data/lib/chef/provider/service/freebsd.rb +154 -0
  338. data/lib/chef/provider/service/gentoo.rb +53 -0
  339. data/lib/chef/provider/service/init.rb +71 -0
  340. data/lib/chef/provider/service/insserv.rb +52 -0
  341. data/lib/chef/provider/service/invokercd.rb +35 -0
  342. data/lib/chef/provider/service/redhat.rb +60 -0
  343. data/lib/chef/provider/service/simple.rb +120 -0
  344. data/lib/chef/provider/service/solaris.rb +85 -0
  345. data/lib/chef/provider/service/systemd.rb +102 -0
  346. data/lib/chef/provider/service/upstart.rb +198 -0
  347. data/lib/chef/provider/service/windows.rb +155 -0
  348. data/lib/chef/provider/subversion.rb +197 -0
  349. data/lib/chef/provider/template.rb +104 -0
  350. data/lib/chef/provider/user.rb +186 -0
  351. data/lib/chef/provider/user/dscl.rb +280 -0
  352. data/lib/chef/provider/user/pw.rb +113 -0
  353. data/lib/chef/provider/user/useradd.rb +137 -0
  354. data/lib/chef/provider/user/windows.rb +124 -0
  355. data/lib/chef/providers.rb +95 -0
  356. data/lib/chef/recipe.rb +129 -0
  357. data/lib/chef/resource.rb +609 -0
  358. data/lib/chef/resource/apt_package.rb +34 -0
  359. data/lib/chef/resource/bash.rb +33 -0
  360. data/lib/chef/resource/breakpoint.rb +35 -0
  361. data/lib/chef/resource/conditional.rb +90 -0
  362. data/lib/chef/resource/cookbook_file.rb +45 -0
  363. data/lib/chef/resource/cron.rb +188 -0
  364. data/lib/chef/resource/csh.rb +33 -0
  365. data/lib/chef/resource/deploy.rb +389 -0
  366. data/lib/chef/resource/deploy_revision.rb +40 -0
  367. data/lib/chef/resource/directory.rb +76 -0
  368. data/lib/chef/resource/dpkg_package.rb +34 -0
  369. data/lib/chef/resource/easy_install_package.rb +57 -0
  370. data/lib/chef/resource/env.rb +58 -0
  371. data/lib/chef/resource/erl_call.rb +83 -0
  372. data/lib/chef/resource/execute.rb +127 -0
  373. data/lib/chef/resource/file.rb +99 -0
  374. data/lib/chef/resource/freebsd_package.rb +35 -0
  375. data/lib/chef/resource/gem_package.rb +53 -0
  376. data/lib/chef/resource/git.rb +46 -0
  377. data/lib/chef/resource/group.rb +78 -0
  378. data/lib/chef/resource/http_request.rb +61 -0
  379. data/lib/chef/resource/ifconfig.rb +144 -0
  380. data/lib/chef/resource/link.rb +78 -0
  381. data/lib/chef/resource/log.rb +62 -0
  382. data/lib/chef/resource/macports_package.rb +29 -0
  383. data/lib/chef/resource/mdadm.rb +82 -0
  384. data/lib/chef/resource/mount.rb +134 -0
  385. data/lib/chef/resource/ohai.rb +40 -0
  386. data/lib/chef/resource/package.rb +80 -0
  387. data/lib/chef/resource/pacman_package.rb +33 -0
  388. data/lib/chef/resource/perl.rb +33 -0
  389. data/lib/chef/resource/portage_package.rb +33 -0
  390. data/lib/chef/resource/python.rb +33 -0
  391. data/lib/chef/resource/remote_directory.rb +109 -0
  392. data/lib/chef/resource/remote_file.rb +83 -0
  393. data/lib/chef/resource/route.rb +135 -0
  394. data/lib/chef/resource/rpm_package.rb +34 -0
  395. data/lib/chef/resource/ruby.rb +33 -0
  396. data/lib/chef/resource/ruby_block.rb +40 -0
  397. data/lib/chef/resource/scm.rb +147 -0
  398. data/lib/chef/resource/script.rb +60 -0
  399. data/lib/chef/resource/service.rb +151 -0
  400. data/lib/chef/resource/solaris_package.rb +36 -0
  401. data/lib/chef/resource/subversion.rb +36 -0
  402. data/lib/chef/resource/template.rb +69 -0
  403. data/lib/chef/resource/timestamped_deploy.rb +31 -0
  404. data/lib/chef/resource/user.rb +130 -0
  405. data/lib/chef/resource/yum_package.rb +63 -0
  406. data/lib/chef/resource_collection.rb +217 -0
  407. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  408. data/lib/chef/resource_definition.rb +67 -0
  409. data/lib/chef/resource_definition_list.rb +38 -0
  410. data/lib/chef/resources.rb +64 -0
  411. data/lib/chef/rest.rb +400 -0
  412. data/lib/chef/rest/auth_credentials.rb +71 -0
  413. data/lib/chef/rest/cookie_jar.rb +31 -0
  414. data/lib/chef/rest/rest_request.rb +213 -0
  415. data/lib/chef/role.rb +343 -0
  416. data/lib/chef/run_context.rb +126 -0
  417. data/lib/chef/run_list.rb +165 -0
  418. data/lib/chef/run_list/run_list_expansion.rb +193 -0
  419. data/lib/chef/run_list/run_list_item.rb +92 -0
  420. data/lib/chef/run_list/versioned_recipe_list.rb +68 -0
  421. data/lib/chef/run_status.rb +121 -0
  422. data/lib/chef/runner.rb +105 -0
  423. data/lib/chef/sandbox.rb +153 -0
  424. data/lib/chef/search/query.rb +65 -0
  425. data/lib/chef/shef.rb +327 -0
  426. data/lib/chef/shef/ext.rb +569 -0
  427. data/lib/chef/shef/model_wrapper.rb +120 -0
  428. data/lib/chef/shef/shef_rest.rb +28 -0
  429. data/lib/chef/shef/shef_session.rb +285 -0
  430. data/lib/chef/shell_out.rb +249 -0
  431. data/lib/chef/shell_out/unix.rb +223 -0
  432. data/lib/chef/shell_out/windows.rb +588 -0
  433. data/lib/chef/solr_query.rb +187 -0
  434. data/lib/chef/solr_query/lucene.treetop +150 -0
  435. data/lib/chef/solr_query/lucene_nodes.rb +285 -0
  436. data/lib/chef/solr_query/query_transform.rb +65 -0
  437. data/lib/chef/solr_query/solr_http_request.rb +132 -0
  438. data/lib/chef/streaming_cookbook_uploader.rb +201 -0
  439. data/lib/chef/tasks/chef_repo.rake +334 -0
  440. data/lib/chef/util/file_edit.rb +122 -0
  441. data/lib/chef/util/windows.rb +56 -0
  442. data/lib/chef/util/windows/net_group.rb +101 -0
  443. data/lib/chef/util/windows/net_use.rb +121 -0
  444. data/lib/chef/util/windows/net_user.rb +198 -0
  445. data/lib/chef/util/windows/volume.rb +59 -0
  446. data/lib/chef/version.rb +23 -0
  447. data/lib/chef/version_class.rb +70 -0
  448. data/lib/chef/version_constraint.rb +116 -0
  449. data/lib/chef/webui_user.rb +231 -0
  450. metadata +764 -0
@@ -0,0 +1,76 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
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
+ class Chef
20
+ module IndexQueue
21
+ module Consumer
22
+ module ClassMethods
23
+ def expose(*methods)
24
+ @exposed_methods = Array(@exposed_methods)
25
+ @exposed_methods += methods
26
+ end
27
+
28
+ def exposed_methods
29
+ @exposed_methods || []
30
+ end
31
+
32
+ def whitelisted?(method_name)
33
+ exposed_methods.include?(method_name)
34
+ end
35
+ end
36
+
37
+ def self.included(including_class)
38
+ including_class.send(:extend, ClassMethods)
39
+ end
40
+
41
+ def run
42
+ Chef::Log.debug("Starting Index Queue Consumer")
43
+ AmqpClient.instance.queue # triggers connection setup
44
+
45
+ begin
46
+ AmqpClient.instance.queue.subscribe(:ack => true, :timeout => false) do |message|
47
+ call_action_for_message(message)
48
+ end
49
+ rescue Bunny::ConnectionError, Errno::ECONNRESET, Bunny::ServerDownError
50
+ AmqpClient.instance.disconnected!
51
+ Chef::Log.warn "Connection to rabbitmq lost. attempting to reconnect"
52
+ sleep 1
53
+ retry
54
+ end
55
+ end
56
+ alias :start :run
57
+
58
+ def call_action_for_message(message)
59
+ amqp_payload = Chef::JSONCompat.from_json(message[:payload], :create_additions => false, :max_nesting => false)
60
+ action = amqp_payload["action"].to_sym
61
+ app_payload = amqp_payload["payload"]
62
+ assert_method_whitelisted(action)
63
+ send(action, app_payload)
64
+ end
65
+
66
+ private
67
+
68
+ def assert_method_whitelisted(method_name)
69
+ unless self.class.whitelisted?(method_name)
70
+ raise ArgumentError, "non-exposed method #{method_name} called via index queue"
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,109 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@kallistec.com>)
3
+ # Author:: Seth Falcon (<seth@opscode.com>)
4
+ # Copyright:: Copyright (c) 2009 Daniel DeLeo
5
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
6
+ # License:: Apache License, Version 2.0
7
+ #
8
+ # Licensed under the Apache License, Version 2.0 (the "License");
9
+ # you may not use this file except in compliance with the License.
10
+ # You may obtain a copy of the License at
11
+ #
12
+ # http://www.apache.org/licenses/LICENSE-2.0
13
+ #
14
+ # Unless required by applicable law or agreed to in writing, software
15
+ # distributed under the License is distributed on an "AS IS" BASIS,
16
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ # See the License for the specific language governing permissions and
18
+ # limitations under the License.
19
+ #
20
+ require 'chef/json_compat'
21
+
22
+ class Chef
23
+ module IndexQueue
24
+ module Indexable
25
+
26
+ module ClassMethods
27
+
28
+ def index_object_type(explicit_type_name=nil)
29
+ @index_object_type = explicit_type_name.to_s if explicit_type_name
30
+ @index_object_type
31
+ end
32
+
33
+ # Resets all metadata used for indexing to nil. Used for testing
34
+ def reset_index_metadata!
35
+ @index_object_type = nil
36
+ end
37
+
38
+ end
39
+
40
+ def self.included(including_class)
41
+ including_class.send(:extend, ClassMethods)
42
+ end
43
+
44
+ attr_accessor :index_id
45
+
46
+ def index_object_type
47
+ self.class.index_object_type || Mixin::ConvertToClassName.snake_case_basename(self.class.name)
48
+ end
49
+
50
+ def with_indexer_metadata(indexer_metadata={})
51
+ # changing input param symbol keys to strings, as the keys in hash that goes to solr are expected to be strings [cb]
52
+ # Ruby 1.9 hates you, cb [dan]
53
+ with_metadata = {}
54
+ indexer_metadata.each_key do |key|
55
+ with_metadata[key.to_s] = indexer_metadata[key]
56
+ end
57
+
58
+ with_metadata["type"] ||= self.index_object_type
59
+ with_metadata["id"] ||= self.index_id
60
+ with_metadata["database"] ||= Chef::Config[:couchdb_database]
61
+ with_metadata["item"] ||= self.to_hash
62
+ with_metadata["enqueued_at"] ||= Time.now.utc.to_i
63
+
64
+ raise ArgumentError, "Type, Id, or Database missing in index operation: #{with_metadata.inspect}" if (with_metadata["id"].nil? or with_metadata["type"].nil?)
65
+ with_metadata
66
+ end
67
+
68
+ def add_to_index(metadata={})
69
+ Chef::Log.debug("Pushing item to index queue for addition: #{self.with_indexer_metadata(metadata)}")
70
+ object_with_metadata = with_indexer_metadata(metadata)
71
+ obj_id = object_with_metadata["id"]
72
+ obj = {:action => :add, :payload => self.with_indexer_metadata(metadata)}
73
+
74
+ publish_object(obj_id, obj)
75
+ end
76
+
77
+ def delete_from_index(metadata={})
78
+ Chef::Log.debug("Pushing item to index queue for deletion: #{self.with_indexer_metadata(metadata)}")
79
+ object_with_metadata = with_indexer_metadata(metadata)
80
+ obj_id = object_with_metadata["id"]
81
+ obj = {:action => :delete, :payload => self.with_indexer_metadata(metadata)}
82
+
83
+ publish_object(obj_id, obj)
84
+ end
85
+
86
+ private
87
+
88
+ # Uses the publisher to update the object's queue. If
89
+ # Chef::Config[:persistent_queue] is true, the update is wrapped
90
+ # in a transaction.
91
+ def publish_object(object_id, object)
92
+ publisher = AmqpClient.instance
93
+ begin
94
+ publisher.amqp_client.tx_select if Chef::Config[:persistent_queue]
95
+ publisher.queue_for_object(object_id) do |queue|
96
+ queue.publish(Chef::JSONCompat.to_json(object), :persistent => Chef::Config[:persistent_queue])
97
+ end
98
+ publisher.amqp_client.tx_commit if Chef::Config[:persistent_queue]
99
+ rescue
100
+ publisher.amqp_client.tx_rollback if Chef::Config[:persistent_queue]
101
+ raise
102
+ end
103
+
104
+ true
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,52 @@
1
+ #
2
+ # Author:: Tim Hinderliter (<tim@opscode.com>)
3
+ # Copyright:: Copyright (c) 2010 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
+ # Wrapper class for interacting with JSON.
19
+
20
+ require 'json'
21
+
22
+ class Chef
23
+ class JSONCompat
24
+ JSON_MAX_NESTING = 1000
25
+
26
+ class <<self
27
+ # See CHEF-1292/PL-538. Increase the max nesting for JSON, which defaults
28
+ # to 19, and isn't enough for some (for example, a Node within a Node)
29
+ # structures.
30
+ def opts_add_max_nesting(opts)
31
+ if opts.nil? || !opts.has_key?(:max_nesting)
32
+ opts = opts.nil? ? Hash.new : opts.clone
33
+ opts[:max_nesting] = JSON_MAX_NESTING
34
+ end
35
+ opts
36
+ end
37
+
38
+ # Just call the JSON gem's parse method with a modified :max_nesting field
39
+ def from_json(source, opts = {})
40
+ ::JSON.parse(source, opts_add_max_nesting(opts))
41
+ end
42
+
43
+ def to_json(obj, opts = nil)
44
+ obj.to_json(opts_add_max_nesting(opts))
45
+ end
46
+
47
+ def to_json_pretty(obj, opts = nil)
48
+ ::JSON.pretty_generate(obj, opts_add_max_nesting(opts))
49
+ end
50
+ end
51
+ end
52
+ end
data/lib/chef/knife.rb ADDED
@@ -0,0 +1,520 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Author:: Christopher Brown (<cb@opscode.com>)
4
+ # Copyright:: Copyright (c) 2009 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 'forwardable'
21
+ require 'chef/version'
22
+ require 'mixlib/cli'
23
+ require 'chef/mixin/convert_to_class_name'
24
+ require 'chef/knife/core/subcommand_loader'
25
+ require 'chef/knife/core/ui'
26
+ require 'chef/rest'
27
+ require 'pp'
28
+
29
+ class Chef
30
+ class Knife
31
+
32
+ Chef::REST::RESTRequest.user_agent = "Chef Knife#{Chef::REST::RESTRequest::UA_COMMON}"
33
+
34
+ include Mixlib::CLI
35
+ extend Chef::Mixin::ConvertToClassName
36
+ extend Forwardable
37
+
38
+ # Backwards Compat:
39
+ # Ideally, we should not vomit all of these methods into this base class;
40
+ # instead, they should be accessed by hitting the ui object directly.
41
+ def_delegator :@ui, :stdout
42
+ def_delegator :@ui, :stderr
43
+ def_delegator :@ui, :stdin
44
+ def_delegator :@ui, :msg
45
+ def_delegator :@ui, :ask_question
46
+ def_delegator :@ui, :pretty_print
47
+ def_delegator :@ui, :output
48
+ def_delegator :@ui, :format_list_for_display
49
+ def_delegator :@ui, :format_for_display
50
+ def_delegator :@ui, :format_cookbook_list_for_display
51
+ def_delegator :@ui, :edit_data
52
+ def_delegator :@ui, :edit_object
53
+ def_delegator :@ui, :confirm
54
+
55
+ attr_accessor :name_args
56
+ attr_accessor :ui
57
+
58
+ def self.ui
59
+ @ui ||= Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
60
+ end
61
+
62
+ def self.msg(msg="")
63
+ ui.msg(msg)
64
+ end
65
+
66
+ def self.reset_subcommands!
67
+ @@subcommands = {}
68
+ @subcommands_by_category = nil
69
+ end
70
+
71
+ def self.inherited(subclass)
72
+ unless subclass.unnamed?
73
+ subcommands[subclass.snake_case_name] = subclass
74
+ end
75
+ end
76
+
77
+ # Explicitly set the category for the current command to +new_category+
78
+ # The category is normally determined from the first word of the command
79
+ # name, but some commands make more sense using two or more words
80
+ # ===Arguments
81
+ # new_category::: A String to set the category to (see examples)
82
+ # ===Examples:
83
+ # Data bag commands would be in the 'data' category by default. To put them
84
+ # in the 'data bag' category:
85
+ # category('data bag')
86
+ def self.category(new_category)
87
+ @category = new_category
88
+ end
89
+
90
+ def self.subcommand_category
91
+ @category || snake_case_name.split('_').first unless unnamed?
92
+ end
93
+
94
+ def self.snake_case_name
95
+ convert_to_snake_case(name.split('::').last) unless unnamed?
96
+ end
97
+
98
+ def self.common_name
99
+ snake_case_name.split('_').join(' ')
100
+ end
101
+
102
+ # Does this class have a name? (Classes created via Class.new don't)
103
+ def self.unnamed?
104
+ name.nil? || name.empty?
105
+ end
106
+
107
+ def self.subcommand_loader
108
+ @subcommand_loader ||= Knife::SubcommandLoader.new(chef_config_dir)
109
+ end
110
+
111
+ def self.load_commands
112
+ @commands_loaded ||= subcommand_loader.load_commands
113
+ end
114
+
115
+ def self.subcommands
116
+ @@subcommands ||= {}
117
+ end
118
+
119
+ def self.subcommands_by_category
120
+ unless @subcommands_by_category
121
+ @subcommands_by_category = Hash.new { |hash, key| hash[key] = [] }
122
+ subcommands.each do |snake_cased, klass|
123
+ @subcommands_by_category[klass.subcommand_category] << snake_cased
124
+ end
125
+ end
126
+ @subcommands_by_category
127
+ end
128
+
129
+ # Print the list of subcommands knife knows about. If +preferred_category+
130
+ # is given, only subcommands in that category are shown
131
+ def self.list_commands(preferred_category=nil)
132
+ load_commands
133
+
134
+ category_desc = preferred_category ? preferred_category + " " : ''
135
+ msg "Available #{category_desc}subcommands: (for details, knife SUB-COMMAND --help)\n\n"
136
+
137
+ if preferred_category && subcommands_by_category.key?(preferred_category)
138
+ commands_to_show = {preferred_category => subcommands_by_category[preferred_category]}
139
+ else
140
+ commands_to_show = subcommands_by_category
141
+ end
142
+
143
+ commands_to_show.sort.each do |category, commands|
144
+ next if category =~ /deprecated/i
145
+ msg "** #{category.upcase} COMMANDS **"
146
+ commands.each do |command|
147
+ msg subcommands[command].banner if subcommands[command]
148
+ end
149
+ msg
150
+ end
151
+ end
152
+
153
+ # Run knife for the given +args+ (ARGV), adding +options+ to the list of
154
+ # CLI options that the subcommand knows how to handle.
155
+ # ===Arguments
156
+ # args::: usually ARGV
157
+ # options::: A Mixlib::CLI option parser hash. These +options+ are how
158
+ # subcommands know about global knife CLI options
159
+ def self.run(args, options={})
160
+ load_commands
161
+ subcommand_class = subcommand_class_from(args)
162
+ subcommand_class.options = options.merge!(subcommand_class.options)
163
+ subcommand_class.load_deps unless want_help?(args)
164
+ instance = subcommand_class.new(args)
165
+ instance.configure_chef
166
+ instance.run_with_pretty_exceptions
167
+ end
168
+
169
+ def self.guess_category(args)
170
+ category_words = args.select {|arg| arg =~ /^(([[:alnum:]])[[:alnum:]\_\-]+)$/ }
171
+ category_words.map! {|w| w.split('-')}.flatten!
172
+ matching_category = nil
173
+ while (!matching_category) && (!category_words.empty?)
174
+ candidate_category = category_words.join(' ')
175
+ matching_category = candidate_category if subcommands_by_category.key?(candidate_category)
176
+ matching_category || category_words.pop
177
+ end
178
+ matching_category
179
+ end
180
+
181
+ def self.subcommand_class_from(args)
182
+ command_words = args.select {|arg| arg =~ /^(([[:alnum:]])[[:alnum:]\_\-]+)$/ }
183
+
184
+ subcommand_class = nil
185
+
186
+ while ( !subcommand_class ) && ( !command_words.empty? )
187
+ snake_case_class_name = command_words.join("_")
188
+ unless subcommand_class = subcommands[snake_case_class_name]
189
+ command_words.pop
190
+ end
191
+ end
192
+ # see if we got the command as e.g., knife node-list
193
+ subcommand_class ||= subcommands[args.first.gsub('-', '_')]
194
+ subcommand_class || subcommand_not_found!(args)
195
+ end
196
+
197
+ def self.deps(&block)
198
+ @dependency_loader = block
199
+ end
200
+
201
+ def self.load_deps
202
+ @dependency_loader && @dependency_loader.call
203
+ end
204
+
205
+ private
206
+
207
+ OFFICIAL_PLUGINS = %w[ec2 rackspace windows openstack terremark bluebox]
208
+
209
+ # :nodoc:
210
+ # Error out and print usage. probably becuase the arguments given by the
211
+ # user could not be resolved to a subcommand.
212
+ def self.subcommand_not_found!(args)
213
+ unless want_help?(args)
214
+ ui.fatal("Cannot find sub command for: '#{args.join(' ')}'")
215
+ end
216
+
217
+ if category_commands = guess_category(args)
218
+ list_commands(category_commands)
219
+ elsif missing_plugin = ( OFFICIAL_PLUGINS.find {|plugin| plugin == args[0]} )
220
+ ui.info("The #{missing_plugin} commands were moved to plugins in Chef 0.10")
221
+ ui.info("You can install the plugin with `(sudo) gem install knife-#{missing_plugin}")
222
+ else
223
+ list_commands
224
+ end
225
+
226
+ exit 10
227
+ end
228
+
229
+ # :nodoc:
230
+ # TODO: duplicated with chef/application/knife
231
+ # all logic should be removed from that and Chef::Knife should own it.
232
+ def self.want_help?(args)
233
+ (args.any? { |arg| arg =~ /^(:?(:?\-\-)?help|\-h)$/})
234
+ end
235
+
236
+ @@chef_config_dir = nil
237
+
238
+ # search upward from current_dir until .chef directory is found
239
+ def self.chef_config_dir
240
+ if @@chef_config_dir.nil? # share this with subclasses
241
+ @@chef_config_dir = false
242
+ full_path = Dir.pwd.split(File::SEPARATOR)
243
+ (full_path.length - 1).downto(0) do |i|
244
+ canidate_directory = File.join(full_path[0..i] + [".chef" ])
245
+ if File.exist?(canidate_directory) && File.directory?(canidate_directory)
246
+ @@chef_config_dir = canidate_directory
247
+ break
248
+ end
249
+ end
250
+ end
251
+ @@chef_config_dir
252
+ end
253
+
254
+
255
+ public
256
+
257
+ # Create a new instance of the current class configured for the given
258
+ # arguments and options
259
+ def initialize(argv=[])
260
+ super() # having to call super in initialize is the most annoying anti-pattern :(
261
+ @ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, config)
262
+
263
+ command_name_words = self.class.snake_case_name.split('_')
264
+
265
+ # Mixlib::CLI ignores the embedded name_args
266
+ @name_args = parse_options(argv)
267
+ @name_args.delete(command_name_words.join('-'))
268
+ @name_args.reject! { |name_arg| command_name_words.delete(name_arg) }
269
+
270
+ # knife node run_list add requires that we have extra logic to handle
271
+ # the case that command name words could be joined by an underscore :/
272
+ command_name_words = command_name_words.join('_')
273
+ @name_args.reject! { |name_arg| command_name_words == name_arg }
274
+
275
+ if config[:help]
276
+ msg opt_parser
277
+ exit 1
278
+ end
279
+ end
280
+
281
+ def parse_options(args)
282
+ super
283
+ rescue OptionParser::InvalidOption => e
284
+ puts "Error: " + e.to_s
285
+ show_usage
286
+ exit(1)
287
+ end
288
+
289
+ def configure_chef
290
+ unless config[:config_file]
291
+ if self.class.chef_config_dir
292
+ candidate_config = File.expand_path('knife.rb',self.class.chef_config_dir)
293
+ config[:config_file] = candidate_config if File.exist?(candidate_config)
294
+ end
295
+ # If we haven't set a config yet and $HOME is set, and the home
296
+ # knife.rb exists, use it:
297
+ if (!config[:config_file]) && ENV['HOME'] && File.exist?(File.join(ENV['HOME'], '.chef', 'knife.rb'))
298
+ config[:config_file] = File.join(ENV['HOME'], '.chef', 'knife.rb')
299
+ end
300
+ end
301
+
302
+ # Don't try to load a knife.rb if it doesn't exist.
303
+ if config[:config_file]
304
+ read_config_file(config[:config_file])
305
+ else
306
+ # ...but do log a message if no config was found.
307
+ Chef::Config[:color] = config[:color] && !config[:no_color]
308
+ ui.warn("No knife configuration file found")
309
+ end
310
+
311
+ Chef::Config[:color] = config[:color] && !config[:no_color]
312
+
313
+ case config[:verbosity]
314
+ when 0
315
+ Chef::Config[:log_level] = :error
316
+ when 1
317
+ Chef::Config[:log_level] = :info
318
+ else
319
+ Chef::Config[:log_level] = :debug
320
+ end
321
+
322
+ Chef::Config[:node_name] = config[:node_name] if config[:node_name]
323
+ Chef::Config[:client_key] = config[:client_key] if config[:client_key]
324
+ Chef::Config[:chef_server_url] = config[:chef_server_url] if config[:chef_server_url]
325
+ Chef::Config[:environment] = config[:environment] if config[:environment]
326
+
327
+ # Expand a relative path from the config directory. Config from command
328
+ # line should already be expanded, and absolute paths will be unchanged.
329
+ if Chef::Config[:client_key] && config[:config_file]
330
+ Chef::Config[:client_key] = File.expand_path(Chef::Config[:client_key], File.dirname(config[:config_file]))
331
+ end
332
+
333
+ Mixlib::Log::Formatter.show_time = false
334
+ Chef::Log.init(Chef::Config[:log_location])
335
+ Chef::Log.level(Chef::Config[:log_level] || :error)
336
+
337
+ Chef::Log.debug("Using configuration from #{config[:config_file]}")
338
+
339
+ if Chef::Config[:node_name].nil?
340
+ #raise ArgumentError, "No user specified, pass via -u or specifiy 'node_name' in #{config[:config_file] ? config[:config_file] : "~/.chef/knife.rb"}"
341
+ end
342
+ end
343
+
344
+ def read_config_file(file)
345
+ Chef::Config.from_file(file)
346
+ rescue SyntaxError => e
347
+ ui.error "You have invalid ruby syntax in your config file #{file}"
348
+ ui.info(ui.color(e.message, :red))
349
+ if file_line = e.message[/#{Regexp.escape(file)}:[\d]+/]
350
+ line = file_line[/:([\d]+)$/, 1].to_i
351
+ highlight_config_error(file, line)
352
+ end
353
+ exit 1
354
+ rescue Exception => e
355
+ ui.error "You have an error in your config file #{file}"
356
+ ui.info "#{e.class.name}: #{e.message}"
357
+ filtered_trace = e.backtrace.grep(/#{Regexp.escape(file)}/)
358
+ filtered_trace.each {|line| ui.msg(" " + ui.color(line, :red))}
359
+ if !filtered_trace.empty?
360
+ line_nr = filtered_trace.first[/#{Regexp.escape(file)}:([\d]+)/, 1]
361
+ highlight_config_error(file, line_nr.to_i)
362
+ end
363
+
364
+ exit 1
365
+ end
366
+
367
+ def highlight_config_error(file, line)
368
+ config_file_lines = []
369
+ IO.readlines(file).each_with_index {|l, i| config_file_lines << "#{(i + 1).to_s.rjust(3)}: #{l.chomp}"}
370
+ if line == 1
371
+ lines = config_file_lines[0..3]
372
+ lines[0] = ui.color(lines[0], :red)
373
+ else
374
+ lines = config_file_lines[Range.new(line - 2, line)]
375
+ lines[1] = ui.color(lines[1], :red)
376
+ end
377
+ ui.msg ""
378
+ ui.msg ui.color(" # #{file}", :white)
379
+ lines.each {|l| ui.msg(l)}
380
+ ui.msg ""
381
+ end
382
+
383
+ def show_usage
384
+ stdout.puts("USAGE: " + self.opt_parser.to_s)
385
+ end
386
+
387
+ def run_with_pretty_exceptions
388
+ unless self.respond_to?(:run)
389
+ ui.error "You need to add a #run method to your knife command before you can use it"
390
+ end
391
+ run
392
+ rescue Exception => e
393
+ raise if config[:verbosity] == 2
394
+ humanize_exception(e)
395
+ exit 100
396
+ end
397
+
398
+ def humanize_exception(e)
399
+ case e
400
+ when SystemExit
401
+ raise # make sure exit passes through.
402
+ when Net::HTTPServerException, Net::HTTPFatalError
403
+ humanize_http_exception(e)
404
+ when Errno::ECONNREFUSED, Timeout::Error, Errno::ETIMEDOUT, SocketError
405
+ ui.error "Network Error: #{e.message}"
406
+ ui.info "Check your knife configuration and network settings"
407
+ when NameError, NoMethodError
408
+ ui.error "knife encountered an unexpected error"
409
+ ui.info "This may be a bug in the '#{self.class.common_name}' knife command or plugin"
410
+ ui.info "Please collect the output of this command with the `-VV` option before filing a bug report."
411
+ ui.info "Exception: #{e.class.name}: #{e.message}"
412
+ when Chef::Exceptions::PrivateKeyMissing
413
+ ui.error "Your private key could not be loaded from #{api_key}"
414
+ ui.info "Check your configuration file and ensure that your private key is readable"
415
+ else
416
+ ui.error "#{e.class.name}: #{e.message}"
417
+ end
418
+ end
419
+
420
+ def humanize_http_exception(e)
421
+ response = e.response
422
+ case response
423
+ when Net::HTTPUnauthorized
424
+ ui.error "Failed to authenticate to #{server_url} as #{username} with key #{api_key}"
425
+ ui.info "Response: #{format_rest_error(response)}"
426
+ when Net::HTTPForbidden
427
+ ui.error "You authenticated successfully to #{server_url} as #{username} but you are not authorized for this action"
428
+ ui.info "Response: #{format_rest_error(response)}"
429
+ when Net::HTTPBadRequest
430
+ ui.error "The data in your request was invalid"
431
+ ui.info "Response: #{format_rest_error(response)}"
432
+ when Net::HTTPNotFound
433
+ ui.error "The object you are looking for could not be found"
434
+ ui.info "Response: #{format_rest_error(response)}"
435
+ when Net::HTTPInternalServerError
436
+ ui.error "internal server error"
437
+ ui.info "Response: #{format_rest_error(response)}"
438
+ when Net::HTTPBadGateway
439
+ ui.error "bad gateway"
440
+ ui.info "Response: #{format_rest_error(response)}"
441
+ when Net::HTTPServiceUnavailable
442
+ ui.error "Service temporarily unavailable"
443
+ ui.info "Response: #{format_rest_error(response)}"
444
+ else
445
+ ui.error response.message
446
+ ui.info "Response: #{format_rest_error(response)}"
447
+ end
448
+ end
449
+
450
+ def username
451
+ Chef::Config[:node_name]
452
+ end
453
+
454
+ def api_key
455
+ Chef::Config[:client_key]
456
+ end
457
+
458
+ # Parses JSON from the error response sent by Chef Server and returns the
459
+ # error message
460
+ #--
461
+ # TODO: this code belongs in Chef::REST
462
+ def format_rest_error(response)
463
+ Array(Chef::JSONCompat.from_json(response.body)["error"]).join('; ')
464
+ rescue Exception
465
+ response.body
466
+ end
467
+
468
+ def create_object(object, pretty_name=nil, &block)
469
+ output = edit_data(object)
470
+
471
+ if Kernel.block_given?
472
+ output = block.call(output)
473
+ else
474
+ output.save
475
+ end
476
+
477
+ pretty_name ||= output
478
+
479
+ self.msg("Created #{pretty_name}")
480
+
481
+ output(output) if config[:print_after]
482
+ end
483
+
484
+ def delete_object(klass, name, delete_name=nil, &block)
485
+ confirm("Do you really want to delete #{name}")
486
+
487
+ if Kernel.block_given?
488
+ object = block.call
489
+ else
490
+ object = klass.load(name)
491
+ object.destroy
492
+ end
493
+
494
+ output(format_for_display(object)) if config[:print_after]
495
+
496
+ obj_name = delete_name ? "#{delete_name}[#{name}]" : object
497
+ self.msg("Deleted #{obj_name}")
498
+ end
499
+
500
+ def rest
501
+ @rest ||= begin
502
+ require 'chef/rest'
503
+ Chef::REST.new(Chef::Config[:chef_server_url])
504
+ end
505
+ end
506
+
507
+ def noauth_rest
508
+ @rest ||= begin
509
+ require 'chef/rest'
510
+ Chef::REST.new(Chef::Config[:chef_server_url], false, false)
511
+ end
512
+ end
513
+
514
+ def server_url
515
+ Chef::Config[:chef_server_url]
516
+ end
517
+
518
+ end
519
+ end
520
+