chef 0.7.16 → 0.8.2

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 (180) hide show
  1. data/README.rdoc +11 -10
  2. data/bin/chef-client +2 -2
  3. data/bin/chef-solo +1 -1
  4. data/bin/knife +27 -0
  5. data/bin/shef +49 -0
  6. data/distro/README +2 -0
  7. data/distro/{debian → common}/man/man1/chef-indexer.1 +0 -0
  8. data/distro/{debian → common}/man/man1/chef-server.1 +0 -0
  9. data/distro/{debian → common}/man/man8/chef-client.8 +0 -0
  10. data/distro/{debian → common}/man/man8/chef-solo.8 +0 -0
  11. data/distro/common/man/man8/knife.8 +375 -0
  12. data/distro/redhat/etc/init.d/chef-client +8 -4
  13. data/distro/redhat/etc/init.d/chef-server +16 -15
  14. data/distro/redhat/etc/init.d/chef-server-webui +78 -0
  15. data/distro/redhat/etc/init.d/chef-solr +76 -0
  16. data/distro/redhat/etc/init.d/chef-solr-indexer +75 -0
  17. data/distro/redhat/etc/sysconfig/chef-client +10 -0
  18. data/distro/redhat/etc/sysconfig/chef-server +10 -0
  19. data/distro/redhat/etc/sysconfig/chef-server-webui +10 -0
  20. data/distro/redhat/etc/sysconfig/chef-solr +9 -0
  21. data/distro/redhat/etc/sysconfig/chef-solr-indexer +7 -0
  22. data/distro/suse/etc/init.d/chef-client +121 -0
  23. data/lib/chef.rb +1 -1
  24. data/lib/chef/api_client.rb +263 -0
  25. data/lib/chef/application.rb +1 -1
  26. data/lib/chef/application/client.rb +21 -3
  27. data/lib/chef/application/knife.rb +144 -0
  28. data/lib/chef/application/server.rb +2 -1
  29. data/lib/chef/application/solo.rb +9 -2
  30. data/lib/chef/cache.rb +61 -0
  31. data/lib/chef/cache/checksum.rb +70 -0
  32. data/lib/chef/certificate.rb +154 -0
  33. data/lib/chef/client.rb +123 -220
  34. data/lib/chef/compile.rb +9 -21
  35. data/lib/chef/config.rb +67 -10
  36. data/lib/chef/cookbook.rb +49 -22
  37. data/lib/chef/cookbook/metadata.rb +85 -5
  38. data/lib/chef/cookbook_loader.rb +4 -4
  39. data/lib/chef/couchdb.rb +99 -30
  40. data/lib/chef/daemon.rb +1 -1
  41. data/lib/chef/data_bag.rb +215 -0
  42. data/lib/chef/data_bag_item.rb +219 -0
  43. data/lib/chef/exceptions.rb +3 -0
  44. data/lib/chef/index_queue.rb +29 -0
  45. data/lib/chef/index_queue/amqp_client.rb +106 -0
  46. data/lib/chef/index_queue/consumer.rb +76 -0
  47. data/lib/chef/index_queue/indexable.rb +74 -0
  48. data/lib/chef/knife.rb +309 -0
  49. data/lib/chef/knife/client_bulk_delete.rb +40 -0
  50. data/lib/chef/knife/client_create.rb +62 -0
  51. data/lib/chef/knife/client_delete.rb +37 -0
  52. data/lib/chef/knife/client_edit.rb +37 -0
  53. data/lib/chef/knife/client_list.rb +40 -0
  54. data/lib/chef/knife/client_reregister.rb +48 -0
  55. data/lib/chef/knife/client_show.rb +42 -0
  56. data/lib/chef/knife/configure.rb +123 -0
  57. data/lib/chef/knife/cookbook_bulk_delete.rb +46 -0
  58. data/lib/chef/knife/cookbook_delete.rb +41 -0
  59. data/lib/chef/knife/cookbook_download.rb +57 -0
  60. data/lib/chef/knife/cookbook_list.rb +41 -0
  61. data/lib/chef/knife/cookbook_metadata.rb +87 -0
  62. data/lib/chef/knife/cookbook_show.rb +75 -0
  63. data/lib/chef/knife/cookbook_upload.rb +179 -0
  64. data/lib/chef/knife/data_bag_create.rb +43 -0
  65. data/lib/chef/knife/data_bag_delete.rb +43 -0
  66. data/lib/chef/knife/data_bag_edit.rb +49 -0
  67. data/lib/chef/knife/data_bag_list.rb +42 -0
  68. data/lib/chef/knife/data_bag_show.rb +40 -0
  69. data/lib/chef/knife/ec2_instance_data.rb +46 -0
  70. data/lib/chef/knife/index_rebuild.rb +51 -0
  71. data/lib/chef/knife/node_bulk_delete.rb +43 -0
  72. data/lib/chef/knife/node_create.rb +39 -0
  73. data/lib/chef/knife/node_delete.rb +36 -0
  74. data/lib/chef/knife/node_edit.rb +36 -0
  75. data/lib/chef/knife/node_from_file.rb +42 -0
  76. data/lib/chef/knife/node_list.rb +41 -0
  77. data/lib/chef/knife/node_run_list_add.rb +64 -0
  78. data/lib/chef/knife/node_run_list_remove.rb +45 -0
  79. data/lib/chef/knife/node_show.rb +46 -0
  80. data/lib/chef/knife/role_bulk_delete.rb +44 -0
  81. data/lib/chef/knife/role_create.rb +44 -0
  82. data/lib/chef/knife/role_delete.rb +36 -0
  83. data/lib/chef/knife/role_edit.rb +37 -0
  84. data/lib/chef/knife/role_from_file.rb +46 -0
  85. data/lib/chef/knife/role_list.rb +40 -0
  86. data/lib/chef/knife/role_show.rb +43 -0
  87. data/lib/chef/knife/search.rb +94 -0
  88. data/lib/chef/knife/ssh.rb +170 -0
  89. data/lib/chef/log.rb +30 -8
  90. data/lib/chef/mixin/checksum.rb +2 -7
  91. data/lib/chef/mixin/command.rb +32 -13
  92. data/lib/chef/mixin/convert_to_class_name.rb +15 -0
  93. data/lib/chef/mixin/deep_merge.rb +199 -11
  94. data/lib/chef/mixin/generate_url.rb +18 -9
  95. data/lib/chef/mixin/language.rb +29 -1
  96. data/lib/chef/mixin/language_include_attribute.rb +56 -0
  97. data/lib/chef/mixin/language_include_recipe.rb +53 -0
  98. data/lib/chef/mixin/params_validate.rb +25 -12
  99. data/lib/chef/mixin/recipe_definition_dsl_core.rb +2 -0
  100. data/lib/chef/mixin/template.rb +11 -1
  101. data/lib/chef/mixin/xml_escape.rb +87 -0
  102. data/lib/chef/node.rb +144 -122
  103. data/lib/chef/openid_registration.rb +12 -5
  104. data/lib/chef/platform.rb +89 -47
  105. data/lib/chef/provider/breakpoint.rb +36 -0
  106. data/lib/chef/provider/cron.rb +5 -6
  107. data/lib/chef/provider/deploy.rb +43 -10
  108. data/lib/chef/provider/deploy/revision.rb +2 -3
  109. data/lib/chef/provider/erl_call.rb +72 -0
  110. data/lib/chef/provider/file.rb +8 -4
  111. data/lib/chef/provider/git.rb +10 -5
  112. data/lib/chef/provider/group/dscl.rb +128 -0
  113. data/lib/chef/provider/http_request.rb +6 -2
  114. data/lib/chef/provider/ifconfig.rb +1 -0
  115. data/lib/chef/provider/link.rb +1 -1
  116. data/lib/chef/provider/log.rb +53 -0
  117. data/lib/chef/provider/mdadm.rb +88 -0
  118. data/lib/chef/provider/mount/mount.rb +1 -1
  119. data/lib/chef/provider/package.rb +1 -1
  120. data/lib/chef/provider/package/easy_install.rb +106 -0
  121. data/lib/chef/provider/package/pacman.rb +101 -0
  122. data/lib/chef/provider/package/portage.rb +1 -1
  123. data/lib/chef/provider/package/rpm.rb +10 -8
  124. data/lib/chef/provider/package/yum-dump.py +22 -3
  125. data/lib/chef/provider/package/yum.rb +32 -8
  126. data/lib/chef/provider/package/zypper.rb +132 -0
  127. data/lib/chef/provider/remote_directory.rb +58 -49
  128. data/lib/chef/provider/remote_file.rb +1 -1
  129. data/lib/chef/provider/route.rb +136 -80
  130. data/lib/chef/provider/ruby_block.rb +18 -1
  131. data/lib/chef/provider/service/arch.rb +109 -0
  132. data/lib/chef/provider/service/freebsd.rb +0 -1
  133. data/lib/chef/provider/service/simple.rb +2 -3
  134. data/lib/chef/provider/service/upstart.rb +191 -0
  135. data/lib/chef/provider/subversion.rb +12 -4
  136. data/lib/chef/provider/template.rb +85 -53
  137. data/lib/chef/provider/user.rb +1 -1
  138. data/lib/chef/provider/user/dscl.rb +277 -0
  139. data/lib/chef/provider/user/useradd.rb +1 -0
  140. data/lib/chef/recipe.rb +2 -41
  141. data/lib/chef/resource.rb +9 -3
  142. data/lib/chef/resource/breakpoint.rb +35 -0
  143. data/lib/chef/resource/deploy.rb +16 -2
  144. data/lib/chef/resource/easy_install_package.rb +41 -0
  145. data/lib/chef/resource/erl_call.rb +83 -0
  146. data/lib/chef/resource/freebsd_package.rb +35 -0
  147. data/lib/chef/resource/log.rb +62 -0
  148. data/lib/chef/resource/mdadm.rb +82 -0
  149. data/lib/chef/resource/pacman_package.rb +33 -0
  150. data/lib/chef/resource/ruby_block.rb +21 -2
  151. data/lib/chef/resource/scm.rb +8 -0
  152. data/lib/chef/resource/subversion.rb +1 -0
  153. data/lib/chef/resource/user.rb +5 -2
  154. data/lib/chef/resource/yum_package.rb +36 -0
  155. data/lib/chef/resource_collection.rb +17 -9
  156. data/lib/chef/resource_collection/stepable_iterator.rb +124 -0
  157. data/lib/chef/rest.rb +166 -81
  158. data/lib/chef/role.rb +114 -38
  159. data/lib/chef/run_list.rb +15 -6
  160. data/lib/chef/runner.rb +13 -11
  161. data/lib/chef/search/query.rb +60 -0
  162. data/lib/chef/shef.rb +220 -0
  163. data/lib/chef/shef/ext.rb +297 -0
  164. data/lib/chef/shef/shef_session.rb +175 -0
  165. data/lib/chef/streaming_cookbook_uploader.rb +187 -0
  166. data/lib/chef/tasks/chef_repo.rake +53 -155
  167. data/lib/chef/util/file_edit.rb +94 -96
  168. data/lib/chef/webui_user.rb +233 -0
  169. metadata +219 -63
  170. data/distro/debian/etc/init.d/chef-indexer +0 -175
  171. data/distro/redhat/etc/chef/client.rb +0 -16
  172. data/distro/redhat/etc/chef/indexer.rb +0 -10
  173. data/distro/redhat/etc/chef/server.rb +0 -22
  174. data/distro/redhat/etc/init.d/chef-indexer +0 -76
  175. data/lib/chef/application/indexer.rb +0 -141
  176. data/lib/chef/queue.rb +0 -145
  177. data/lib/chef/search.rb +0 -88
  178. data/lib/chef/search/result.rb +0 -64
  179. data/lib/chef/search_index.rb +0 -77
  180. data/lib/chef/util/fileedit.rb +0 -121
@@ -27,7 +27,7 @@ require 'chef/config'
27
27
  Dir[File.join(File.dirname(__FILE__), 'chef/mixin/**/*.rb')].sort.each { |lib| require lib }
28
28
 
29
29
  class Chef
30
- VERSION = '0.7.16'
30
+ VERSION = '0.8.2'
31
31
  end
32
32
 
33
33
  # Adds a Dir.glob to Ruby 1.8.5, for compat
@@ -0,0 +1,263 @@
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 'chef/certificate'
24
+ require 'chef/index_queue'
25
+ require 'extlib'
26
+ require 'json'
27
+
28
+ class Chef
29
+ class ApiClient
30
+
31
+ include Chef::Mixin::FromFile
32
+ include Chef::Mixin::ParamsValidate
33
+ include Chef::IndexQueue::Indexable
34
+
35
+
36
+ DESIGN_DOCUMENT = {
37
+ "version" => 1,
38
+ "language" => "javascript",
39
+ "views" => {
40
+ "all" => {
41
+ "map" => <<-EOJS
42
+ function(doc) {
43
+ if (doc.chef_type == "client") {
44
+ emit(doc.name, doc);
45
+ }
46
+ }
47
+ EOJS
48
+ },
49
+ "all_id" => {
50
+ "map" => <<-EOJS
51
+ function(doc) {
52
+ if (doc.chef_type == "client") {
53
+ emit(doc.name, doc.name);
54
+ }
55
+ }
56
+ EOJS
57
+ }
58
+ }
59
+ }
60
+
61
+ attr_accessor :couchdb_rev, :couchdb_id, :couchdb
62
+
63
+ # Create a new Chef::ApiClient object.
64
+ def initialize(couchdb=nil)
65
+ @name = ''
66
+ @public_key = nil
67
+ @private_key = nil
68
+ @couchdb_rev = nil
69
+ @couchdb_id = nil
70
+ @admin = false
71
+ @couchdb = (couchdb || Chef::CouchDB.new)
72
+ end
73
+
74
+ # Gets or sets the client name.
75
+ #
76
+ # @params [Optional String] The name must be alpha-numeric plus - and _.
77
+ # @return [String] The current value of the name.
78
+ def name(arg=nil)
79
+ set_or_return(
80
+ :name,
81
+ arg,
82
+ :regex => /^[\-[:alnum:]_\.]+$/
83
+ )
84
+ end
85
+
86
+ # Gets or sets whether this client is an admin.
87
+ #
88
+ # @params [Optional True/False] Should be true or false - default is false.
89
+ # @return [True/False] The current value
90
+ def admin(arg=nil)
91
+ set_or_return(
92
+ :admin,
93
+ arg,
94
+ :kind_of => [ TrueClass, FalseClass ]
95
+ )
96
+ end
97
+
98
+ # Gets or sets the public key.
99
+ #
100
+ # @params [Optional String] The string representation of the public key.
101
+ # @return [String] The current value.
102
+ def public_key(arg=nil)
103
+ set_or_return(
104
+ :public_key,
105
+ arg,
106
+ :kind_of => String
107
+ )
108
+ end
109
+
110
+ # Gets or sets the private key.
111
+ #
112
+ # @params [Optional String] The string representation of the private key.
113
+ # @return [String] The current value.
114
+ def private_key(arg=nil)
115
+ set_or_return(
116
+ :private_key,
117
+ arg,
118
+ :kind_of => String
119
+ )
120
+ end
121
+
122
+ # Creates a new public/private key pair, and populates the public_key and
123
+ # private_key attributes.
124
+ #
125
+ # @return [True]
126
+ def create_keys
127
+ results = Chef::Certificate.gen_keypair(self.name)
128
+ self.public_key(results[0].to_s)
129
+ self.private_key(results[1].to_s)
130
+ true
131
+ end
132
+
133
+ # The hash representation of the object. Includes the name and public_key,
134
+ # but never the private key.
135
+ #
136
+ # @return [Hash]
137
+ def to_hash
138
+ result = {
139
+ "name" => @name,
140
+ "public_key" => @public_key,
141
+ "admin" => @admin,
142
+ 'json_class' => self.class.name,
143
+ "chef_type" => "client"
144
+ }
145
+ result["_rev"] = @couchdb_rev if @couchdb_rev
146
+ result
147
+ end
148
+
149
+ # The JSON representation of the object.
150
+ #
151
+ # @return [String] the JSON string.
152
+ def to_json(*a)
153
+ to_hash.to_json(*a)
154
+ end
155
+
156
+ def self.json_create(o)
157
+ client = Chef::ApiClient.new
158
+ client.name(o["name"] || o["clientname"])
159
+ client.public_key(o["public_key"])
160
+ client.admin(o["admin"])
161
+ client.couchdb_rev = o["_rev"]
162
+ client.couchdb_id = o["_id"]
163
+ client.index_id = client.couchdb_id
164
+ client
165
+ end
166
+
167
+ # List all the Chef::ApiClient objects in the CouchDB. If inflate is set
168
+ # to true, you will get the full list of all ApiClients, fully inflated.
169
+ def self.cdb_list(inflate=false, couchdb=nil)
170
+ rs = (couchdb || Chef::CouchDB.new).list("clients", inflate)
171
+ lookup = (inflate ? "value" : "key")
172
+ rs["rows"].collect { |r| r[lookup] }
173
+ end
174
+
175
+ def self.list(inflate=false)
176
+ if inflate
177
+ response = Hash.new
178
+ Chef::Search::Query.new.search(:client) do |n|
179
+ n = self.json_create(n) if n.instance_of?(Hash)
180
+ response[n.name] = n
181
+ end
182
+ response
183
+ else
184
+ Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients")
185
+ end
186
+ end
187
+
188
+ # Load a client by name from CouchDB
189
+ #
190
+ # @params [String] The name of the client to load
191
+ # @return [Chef::ApiClient] The resulting Chef::ApiClient object
192
+ def self.cdb_load(name, couchdb=nil)
193
+ (couchdb || Chef::CouchDB.new).load("client", name)
194
+ end
195
+
196
+ # Load a client by name via the API
197
+ def self.load(name)
198
+ response = Chef::REST.new(Chef::Config[:chef_server_url]).get_rest("clients/#{name}")
199
+ if response.kind_of?(Chef::ApiClient)
200
+ response
201
+ else
202
+ client = Chef::ApiClient.new
203
+ client.name(response['clientname'])
204
+ client
205
+ end
206
+ end
207
+
208
+ # Remove this client from the CouchDB
209
+ #
210
+ # @params [String] The name of the client to delete
211
+ # @return [Chef::ApiClient] The last version of the object
212
+ def cdb_destroy
213
+ @couchdb.delete("client", @name, @couchdb_rev)
214
+ end
215
+
216
+ # Remove this client via the REST API
217
+ def destroy
218
+ Chef::REST.new(Chef::Config[:chef_server_url]).delete_rest("clients/#{@name}")
219
+ end
220
+
221
+ # Save this client to the CouchDB
222
+ def cdb_save
223
+ @couchdb_rev = @couchdb.store("client", @name, self)["rev"]
224
+ end
225
+
226
+ # Save this client via the REST API, returns a hash including the private key
227
+ def save(new_key=false, validation=false)
228
+ if validation
229
+ r = Chef::REST.new(Chef::Config[:chef_server_url], Chef::Config[:validation_client_name], Chef::Config[:validation_key])
230
+ else
231
+ r = Chef::REST.new(Chef::Config[:chef_server_url])
232
+ end
233
+ # First, try and create a new registration
234
+ begin
235
+ r.post_rest("clients", {:name => self.name, :admin => self.admin })
236
+ rescue Net::HTTPServerException => e
237
+ # If that fails, go ahead and try and update it
238
+ if e.response.code == "409"
239
+ r.put_rest("clients/#{name}", { :name => self.name, :admin => self.admin, :private_key => new_key })
240
+ else
241
+ raise e
242
+ end
243
+ end
244
+ end
245
+
246
+ # Create the client via the REST API
247
+ def create
248
+ Chef::REST.new(Chef::Config[:chef_server_url]).post_rest("clients", self)
249
+ end
250
+
251
+ # Set up our CouchDB design document
252
+ def self.create_design_document(couchdb=nil)
253
+ (couchdb ||= Chef::CouchDB.new).create_design_document("clients", DESIGN_DOCUMENT)
254
+ end
255
+
256
+ # As a string
257
+ def to_s
258
+ "client[#{@name}]"
259
+ end
260
+
261
+ end
262
+ end
263
+
@@ -68,7 +68,7 @@ class Chef::Application
68
68
  # Initialize and configure the logger
69
69
  def configure_logging
70
70
  Chef::Log.init(Chef::Config[:log_location])
71
- Chef::Log.level(Chef::Config[:log_level])
71
+ Chef::Log.level = Chef::Config[:log_level]
72
72
  end
73
73
 
74
74
  # Called prior to starting the application, by the run method
@@ -1,5 +1,6 @@
1
1
  #
2
2
  # Author:: AJ Christensen (<aj@opscode.com)
3
+ # Author:: Christopher Brown (<cb@opscode.com>)
3
4
  # Copyright:: Copyright (c) 2008 Opscode, Inc.
4
5
  # License:: Apache License, Version 2.0
5
6
  #
@@ -20,8 +21,7 @@ require 'chef/client'
20
21
  require 'chef/config'
21
22
  require 'chef/daemon'
22
23
  require 'chef/log'
23
- require 'net/http'
24
- require 'open-uri'
24
+ require 'chef/rest'
25
25
 
26
26
 
27
27
  class Chef::Application::Client < Chef::Application
@@ -44,6 +44,12 @@ class Chef::Application::Client < Chef::Application
44
44
  :description => "Set the log file location, defaults to STDOUT - recommended for daemonizing",
45
45
  :proc => nil
46
46
 
47
+ option :verbose_logging,
48
+ :short => "-V",
49
+ :long => "--verbose",
50
+ :description => "Ensures logging goes to STDOUT as well as to other configured log location(s).",
51
+ :proc => lambda { |p| true }
52
+
47
53
  option :help,
48
54
  :short => "-h",
49
55
  :long => "--help",
@@ -135,7 +141,13 @@ class Chef::Application::Client < Chef::Application
135
141
 
136
142
  if Chef::Config[:json_attribs]
137
143
  begin
138
- json_io = open(Chef::Config[:json_attribs])
144
+ json_io = case Chef::Config[:json_attribs]
145
+ when /^(http|https):\/\//
146
+ @rest = Chef::REST.new(Chef::Config[:json_attribs], nil, nil)
147
+ @rest.get_rest(Chef::Config[:json_attribs], true).open
148
+ else
149
+ open(Chef::Config[:json_attribs])
150
+ end
139
151
  rescue SocketError => error
140
152
  Chef::Application.fatal!("I cannot connect to #{Chef::Config[:json_attribs]}", 2)
141
153
  rescue Errno::ENOENT => error
@@ -148,11 +160,17 @@ class Chef::Application::Client < Chef::Application
148
160
 
149
161
  begin
150
162
  @chef_client_json = JSON.parse(json_io.read)
163
+ json_io.close unless json_io.closed?
151
164
  rescue JSON::ParserError => error
152
165
  Chef::Application.fatal!("Could not parse the provided JSON file (#{Chef::Config[:json_attribs]})!: " + error.message, 2)
153
166
  end
154
167
  end
155
168
  end
169
+
170
+ def configure_logging
171
+ super
172
+ Mixlib::Authentication::Log.logger = Chef::Log.logger
173
+ end
156
174
 
157
175
  # Setup an instance of the chef client
158
176
  # Why is this so ugly? surely the client should just read out of chef::config instead of needing the values to be assigned like this..
@@ -0,0 +1,144 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@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 'chef/knife'
19
+ require 'chef/application'
20
+ require 'chef/client'
21
+ require 'chef/config'
22
+ require 'chef/log'
23
+ require 'chef/node'
24
+ require 'chef/role'
25
+ require 'chef/data_bag'
26
+ require 'chef/data_bag_item'
27
+ require 'chef/rest'
28
+ require 'chef/search/query'
29
+ require 'tmpdir'
30
+ require 'uri'
31
+
32
+ class Chef::Application::Knife < Chef::Application
33
+
34
+ banner "Usage: #{$0} sub-command (options)"
35
+
36
+ option :config_file,
37
+ :short => "-c CONFIG",
38
+ :long => "--config CONFIG",
39
+ :default => File.join(ENV['HOME'], '.chef', 'knife.rb'),
40
+ :description => "The configuration file to use"
41
+
42
+ option :log_level,
43
+ :short => "-l LEVEL",
44
+ :long => "--log_level LEVEL",
45
+ :description => "Set the log level (debug, info, warn, error, fatal)",
46
+ :proc => lambda { |l| l.to_sym }
47
+
48
+ option :log_location,
49
+ :short => "-L LOGLOCATION",
50
+ :long => "--logfile LOGLOCATION",
51
+ :description => "Set the log file location, defaults to STDOUT",
52
+ :proc => nil
53
+
54
+ option :editor,
55
+ :short => "-e EDITOR",
56
+ :long => "--editor EDITOR",
57
+ :description => "Set the editor to use for interactive commands",
58
+ :default => ENV['EDITOR']
59
+
60
+ option :no_editor,
61
+ :short => "-n",
62
+ :long => "--no-editor",
63
+ :description => "Do not open EDITOR, just accept the data as is",
64
+ :boolean => true
65
+
66
+ option :help,
67
+ :short => "-h",
68
+ :long => "--help",
69
+ :description => "Show this message",
70
+ :on => :tail,
71
+ :boolean => true
72
+
73
+ option :node_name,
74
+ :short => "-u USER",
75
+ :long => "--user USER",
76
+ :description => "API Client Username"
77
+
78
+ option :client_key,
79
+ :short => "-k KEY",
80
+ :long => "--key KEY",
81
+ :description => "API Client Key"
82
+
83
+ option :chef_server_url,
84
+ :short => "-s URL",
85
+ :long => "--server-url URL",
86
+ :description => "Chef Server URL"
87
+
88
+ option :yes,
89
+ :short => "-y",
90
+ :long => "--yes",
91
+ :description => "Say yes to all prompts for confirmation"
92
+
93
+ option :print_after,
94
+ :short => "-p",
95
+ :long => "--print-after",
96
+ :description => "Show the data after a destructive operation"
97
+
98
+ option :version,
99
+ :short => "-v",
100
+ :long => "--version",
101
+ :description => "Show chef version",
102
+ :boolean => true,
103
+ :proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
104
+ :exit => 0
105
+
106
+ # Run knife
107
+ def run
108
+ validate_and_parse_options
109
+ knife = Chef::Knife.find_command(ARGV, self.class.options)
110
+ knife.run
111
+ end
112
+
113
+ private
114
+
115
+ def validate_and_parse_options
116
+ # Checking ARGV validity *before* parse_options because parse_options
117
+ # mangles ARGV in some situations
118
+ print_help_and_exit(2, "Sorry, you need to pass a sub-command first!") if no_subcommand_given?
119
+ print_help_and_exit if no_command_given?
120
+ end
121
+
122
+ def no_subcommand_given?
123
+ ARGV[0] =~ /^-/
124
+ end
125
+
126
+ def no_command_given?
127
+ ARGV.empty?
128
+ end
129
+
130
+ def print_help_and_exit(exitcode=1, fatal_message=nil)
131
+ Chef::Log.fatal(fatal_message) if fatal_message
132
+
133
+ begin
134
+ self.parse_options
135
+ rescue OptionParser::InvalidOption => e
136
+ puts "#{e}\n"
137
+ end
138
+ puts self.opt_parser
139
+ puts
140
+ Chef::Knife.list_commands
141
+ exit exitcode
142
+ end
143
+
144
+ end