chef 12.2.1-x86-mingw32 → 12.3.0.rc.0-x86-mingw32
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.
- checksums.yaml +4 -4
- data/ext/win32-eventlog/Rakefile +10 -6
- data/lib/chef.rb +1 -0
- data/lib/chef/application/apply.rb +5 -0
- data/lib/chef/application/client.rb +10 -0
- data/lib/chef/application/knife.rb +5 -1
- data/lib/chef/application/solo.rb +5 -0
- data/lib/chef/chef_class.rb +130 -0
- data/lib/chef/client.rb +15 -7
- data/lib/chef/config.rb +13 -0
- data/lib/chef/event_loggers/windows_eventlog.rb +11 -5
- data/lib/chef/http.rb +13 -3
- data/lib/chef/http/basic_client.rb +21 -4
- data/lib/chef/http/socketless_chef_zero_client.rb +207 -0
- data/lib/chef/knife.rb +3 -0
- data/lib/chef/knife/bootstrap.rb +1 -1
- data/lib/chef/knife/core/status_presenter.rb +12 -11
- data/lib/chef/knife/ssh.rb +3 -1
- data/lib/chef/knife/status.rb +32 -7
- data/lib/chef/local_mode.rb +13 -3
- data/lib/chef/mixin/provides.rb +32 -0
- data/lib/chef/platform/provider_priority_map.rb +16 -7
- data/lib/chef/platform/resource_priority_map.rb +37 -0
- data/lib/chef/policy_builder/expand_node_object.rb +14 -0
- data/lib/chef/policy_builder/policyfile.rb +0 -1
- data/lib/chef/provider.rb +5 -20
- data/lib/chef/provider/package/rubygems.rb +4 -1
- data/lib/chef/provider/service/macosx.rb +66 -30
- data/lib/chef/provider_resolver.rb +10 -5
- data/lib/chef/resource.rb +5 -39
- data/lib/chef/resource/gem_package.rb +5 -0
- data/lib/chef/resource/link.rb +1 -1
- data/lib/chef/resource/macosx_service.rb +59 -0
- data/lib/chef/resource/remote_file.rb +0 -4
- data/lib/chef/resource_resolver.rb +101 -0
- data/lib/chef/rest.rb +4 -5
- data/lib/chef/search/query.rb +1 -1
- data/lib/chef/server_api.rb +1 -0
- data/lib/chef/version.rb +1 -1
- data/spec/data/lwrp/providers/buck_passer.rb +2 -1
- data/spec/data/lwrp/resources/bar.rb +1 -1
- data/spec/data/{big_json.json → nested.json} +2 -2
- data/spec/functional/event_loggers/windows_eventlog_spec.rb +14 -0
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/integration/client/client_spec.rb +12 -1
- data/spec/integration/client/ipv6_spec.rb +1 -1
- data/spec/integration/knife/common_options_spec.rb +3 -3
- data/spec/integration/recipes/lwrp_inline_resources_spec.rb +1 -1
- data/spec/integration/solo/solo_spec.rb +7 -5
- data/spec/unit/application/client_spec.rb +10 -0
- data/spec/unit/chef_class_spec.rb +91 -0
- data/spec/unit/client_spec.rb +13 -0
- data/spec/unit/http/basic_client_spec.rb +43 -6
- data/spec/unit/http/socketless_chef_zero_client_spec.rb +174 -0
- data/spec/unit/http_spec.rb +14 -0
- data/spec/unit/json_compat_spec.rb +7 -20
- data/spec/unit/knife/ssh_spec.rb +18 -0
- data/spec/unit/knife/status_spec.rb +69 -3
- data/spec/unit/knife_spec.rb +5 -0
- data/spec/unit/provider/package/rubygems_spec.rb +19 -0
- data/spec/unit/provider/service/macosx_spec.rb +230 -203
- data/spec/unit/provider_resolver_spec.rb +1 -0
- data/spec/unit/recipe_spec.rb +48 -0
- data/spec/unit/resource/link_spec.rb +15 -0
- data/spec/unit/resource_spec.rb +6 -6
- data/spec/unit/rest_spec.rb +9 -0
- data/spec/unit/search/query_spec.rb +24 -0
- data/spec/unit/shell_spec.rb +3 -1
- metadata +16 -9
- data/spec/data/big_json_plus_one.json +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91f2fc1f5461db9f00c5bb861ba643c8ecba728e
|
4
|
+
data.tar.gz: f520f5bbb0057bec905346f923dc3f6cabab4780
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fdc2cbedacc39566ce05e9b4b448f992d7766eda5f5585d075437987db7058a675147d689a624c1b8f50416740c21643393713ce1fc06ebef0e1ca177969083
|
7
|
+
data.tar.gz: 010f4fae462cdeaf79d1bbbbd82bd7d01d19af19af6880b1e8d607ed8aae8bd44d6fa1ea9bfd99dd9a41a052ce1c05c4c7aa2dbaab55035925d3affdd807c0f4
|
data/ext/win32-eventlog/Rakefile
CHANGED
@@ -41,10 +41,14 @@ end
|
|
41
41
|
task :register => EVT_SHARED_OBJECT do
|
42
42
|
require 'win32/eventlog'
|
43
43
|
dll_file = File.expand_path(EVT_SHARED_OBJECT)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
begin
|
45
|
+
Win32::EventLog.add_event_source(
|
46
|
+
:source => "Application",
|
47
|
+
:key_name => "Chef",
|
48
|
+
:event_message_file => dll_file,
|
49
|
+
:category_message_file => dll_file
|
50
|
+
)
|
51
|
+
rescue Errno::EIO => e
|
52
|
+
puts "Skipping event log registration due to missing privileges: #{e}"
|
53
|
+
end
|
50
54
|
end
|
data/lib/chef.rb
CHANGED
@@ -85,6 +85,11 @@ class Chef::Application::Apply < Chef::Application
|
|
85
85
|
:default => !Chef::Platform.windows?,
|
86
86
|
:description => "Use colored output, defaults to enabled"
|
87
87
|
|
88
|
+
option :minimal_ohai,
|
89
|
+
:long => "--minimal-ohai",
|
90
|
+
:description => "Only run the bare minimum ohai plugins chef needs to function",
|
91
|
+
:boolean => true
|
92
|
+
|
88
93
|
attr_reader :json_attribs
|
89
94
|
|
90
95
|
def initialize
|
@@ -253,6 +253,16 @@ class Chef::Application::Client < Chef::Application
|
|
253
253
|
:description => "Enable audit-mode with `enabled`. Disable audit-mode with `disabled`. Skip converge and only perform audits with `audit-only`",
|
254
254
|
:proc => lambda { |mo| mo.gsub("-", "_").to_sym }
|
255
255
|
|
256
|
+
option :minimal_ohai,
|
257
|
+
:long => "--minimal-ohai",
|
258
|
+
:description => "Only run the bare minimum ohai plugins chef needs to function",
|
259
|
+
:boolean => true
|
260
|
+
|
261
|
+
option :listen,
|
262
|
+
:long => "--[no-]listen",
|
263
|
+
:description => "Whether a local mode (-z) server binds to a port",
|
264
|
+
:boolean => true
|
265
|
+
|
256
266
|
IMMEDIATE_RUN_SIGNAL = "1".freeze
|
257
267
|
|
258
268
|
attr_reader :chef_client_json
|
@@ -121,6 +121,11 @@ class Chef::Application::Knife < Chef::Application
|
|
121
121
|
:long => "--chef-zero-port PORT",
|
122
122
|
:description => "Port (or port range) to start chef-zero on. Port ranges like 1000,1010 or 8889-9999 will try all given ports until one works."
|
123
123
|
|
124
|
+
option :listen,
|
125
|
+
:long => "--[no-]listen",
|
126
|
+
:description => "Whether a local mode (-z) server binds to a port",
|
127
|
+
:boolean => true
|
128
|
+
|
124
129
|
option :version,
|
125
130
|
:short => "-v",
|
126
131
|
:long => "--version",
|
@@ -129,7 +134,6 @@ class Chef::Application::Knife < Chef::Application
|
|
129
134
|
:proc => lambda {|v| puts "Chef: #{::Chef::VERSION}"},
|
130
135
|
:exit => 0
|
131
136
|
|
132
|
-
|
133
137
|
# Run knife
|
134
138
|
def run
|
135
139
|
Mixlib::Log::Formatter.show_time = false
|
@@ -180,6 +180,11 @@ class Chef::Application::Solo < Chef::Application
|
|
180
180
|
:description => "Set maximum duration to wait for another client run to finish, default is indefinitely.",
|
181
181
|
:proc => lambda { |s| s.to_i }
|
182
182
|
|
183
|
+
option :minimal_ohai,
|
184
|
+
:long => "--minimal-ohai",
|
185
|
+
:description => "Only run the bare minimum ohai plugins chef needs to function",
|
186
|
+
:boolean => true
|
187
|
+
|
183
188
|
attr_reader :chef_client_json
|
184
189
|
|
185
190
|
def initialize
|
@@ -0,0 +1,130 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Lamont Granquist (<lamont@chef.io>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Chef Software, 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
|
+
# NOTE: This class is not intended for internal use by the chef-client code. Classes in
|
19
|
+
# chef-client should still have objects like the node and run_context injected into them
|
20
|
+
# via their initializers. This class is still global state and will complicate writing
|
21
|
+
# unit tests for internal Chef objects. It is intended to be used only by recipe code.
|
22
|
+
|
23
|
+
# NOTE: When adding require lines here you are creating tight coupling on a global that may be
|
24
|
+
# included in many different situations and ultimately that ends in tears with circular requires.
|
25
|
+
# Note the way that the run_context, provider_priority_map and resource_priority_map are "dependency
|
26
|
+
# injected" into this class by other objects and do not reference the class symbols in those files
|
27
|
+
# directly and we do not need to require those files here.
|
28
|
+
|
29
|
+
class Chef
|
30
|
+
class << self
|
31
|
+
|
32
|
+
#
|
33
|
+
# Public API
|
34
|
+
#
|
35
|
+
|
36
|
+
# Get the node object
|
37
|
+
#
|
38
|
+
# @return [Chef::Node] node object of the chef-client run
|
39
|
+
attr_reader :node
|
40
|
+
|
41
|
+
# Get the run context
|
42
|
+
#
|
43
|
+
# @return [Chef::RunContext] run_context of the chef-client run
|
44
|
+
attr_reader :run_context
|
45
|
+
|
46
|
+
# Get the array of providers associated with a resource_name for the current node
|
47
|
+
#
|
48
|
+
# @param resource_name [Symbol] name of the resource as a symbol
|
49
|
+
# @return [Array<Class>] Priority Array of Provider Classes to use for the resource_name on the node
|
50
|
+
def get_provider_priority_array(resource_name)
|
51
|
+
@provider_priority_map.get_priority_array(node, resource_name).dup
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get the array of resources associated with a resource_name for the current node
|
55
|
+
#
|
56
|
+
# @param resource_name [Symbol] name of the resource as a symbol
|
57
|
+
# @return [Array<Class>] Priority Array of Resource Classes to use for the resource_name on the node
|
58
|
+
def get_resource_priority_array(resource_name)
|
59
|
+
@resource_priority_map.get_priority_array(node, resource_name).dup
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set the array of providers associated with a resource_name for the current node
|
63
|
+
#
|
64
|
+
# @param resource_name [Symbol] name of the resource as a symbol
|
65
|
+
# @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node
|
66
|
+
# @param filter [Hash] Chef::Nodearray-style filter
|
67
|
+
# @return [Array<Class>] Modified Priority Array of Provider Classes to use for the resource_name on the node
|
68
|
+
def set_provider_priority_array(resource_name, priority_array, *filter)
|
69
|
+
@provider_priority_map.set_priority_array(resource_name, priority_array, *filter).dup
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get the array of resources associated with a resource_name for the current node
|
73
|
+
#
|
74
|
+
# @param resource_name [Symbol] name of the resource as a symbol
|
75
|
+
# @param priority_array [Array<Class>] Array of Classes to set as the priority for resource_name on the node
|
76
|
+
# @param filter [Hash] Chef::Nodearray-style filter
|
77
|
+
# @return [Array<Class>] Modified Priority Array of Resource Classes to use for the resource_name on the node
|
78
|
+
def set_resource_priority_array(resource_name, priority_array, *filter)
|
79
|
+
@resource_priority_map.set_priority_array(resource_name, priority_array, *filter).dup
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Dependency Injection API (Private not Public)
|
84
|
+
# [ in the ruby sense these have to be public methods, but they are
|
85
|
+
# *NOT* for public consumption ]
|
86
|
+
#
|
87
|
+
|
88
|
+
# Sets the resource_priority_map
|
89
|
+
#
|
90
|
+
# @api private
|
91
|
+
# @param resource_priority_map [Chef::Platform::ResourcePriorityMap]
|
92
|
+
def set_resource_priority_map(resource_priority_map)
|
93
|
+
@resource_priority_map = resource_priority_map
|
94
|
+
end
|
95
|
+
|
96
|
+
# Sets the provider_priority_map
|
97
|
+
#
|
98
|
+
# @api private
|
99
|
+
# @param provider_priority_map [Chef::Platform::providerPriorityMap]
|
100
|
+
def set_provider_priority_map(provider_priority_map)
|
101
|
+
@provider_priority_map = provider_priority_map
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sets the node object
|
105
|
+
#
|
106
|
+
# @api private
|
107
|
+
# @param node [Chef::Node]
|
108
|
+
def set_node(node)
|
109
|
+
@node = node
|
110
|
+
end
|
111
|
+
|
112
|
+
# Sets the run_context object
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
# @param run_context [Chef::RunContext]
|
116
|
+
def set_run_context(run_context)
|
117
|
+
@run_context = run_context
|
118
|
+
end
|
119
|
+
|
120
|
+
# Resets the internal state
|
121
|
+
#
|
122
|
+
# @api private
|
123
|
+
def reset!
|
124
|
+
@run_context = nil
|
125
|
+
@node = nil
|
126
|
+
@provider_priority_map = nil
|
127
|
+
@resource_priority_map = nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/chef/client.rb
CHANGED
@@ -166,6 +166,13 @@ class Chef
|
|
166
166
|
if new_runlist = args.delete(:runlist)
|
167
167
|
@json_attribs["run_list"] = new_runlist
|
168
168
|
end
|
169
|
+
|
170
|
+
# these slurp in the resource+provider world, so be exceedingly lazy about requiring them
|
171
|
+
require 'chef/platform/provider_priority_map' unless defined? Chef::Platform::ProviderPriorityMap
|
172
|
+
require 'chef/platform/resource_priority_map' unless defined? Chef::Platform::ResourcePriorityMap
|
173
|
+
|
174
|
+
Chef.set_provider_priority_map(Chef::Platform::ProviderPriorityMap.instance)
|
175
|
+
Chef.set_resource_priority_map(Chef::Platform::ResourcePriorityMap.instance)
|
169
176
|
end
|
170
177
|
|
171
178
|
def configure_formatters
|
@@ -224,21 +231,21 @@ class Chef
|
|
224
231
|
end
|
225
232
|
|
226
233
|
# Instantiates a Chef::Node object, possibly loading the node's prior state
|
227
|
-
# when using chef-client. Delegates to policy_builder
|
228
|
-
#
|
234
|
+
# when using chef-client. Delegates to policy_builder. Injects the built node
|
235
|
+
# into the Chef class.
|
229
236
|
#
|
230
|
-
#
|
231
|
-
# Chef::Node:: The node object for this chef run
|
237
|
+
# @return [Chef::Node] The node object for this Chef run
|
232
238
|
def load_node
|
233
239
|
policy_builder.load_node
|
234
240
|
@node = policy_builder.node
|
241
|
+
Chef.set_node(@node)
|
242
|
+
node
|
235
243
|
end
|
236
244
|
|
237
245
|
# Mutates the `node` object to prepare it for the chef run. Delegates to
|
238
246
|
# policy_builder
|
239
247
|
#
|
240
|
-
#
|
241
|
-
# Chef::Node:: The updated node object
|
248
|
+
# @return [Chef::Node] The updated node object
|
242
249
|
def build_node
|
243
250
|
policy_builder.build_node
|
244
251
|
@run_status = Chef::RunStatus.new(node, events)
|
@@ -272,7 +279,8 @@ class Chef
|
|
272
279
|
end
|
273
280
|
|
274
281
|
def run_ohai
|
275
|
-
|
282
|
+
filter = Chef::Config[:minimal_ohai] ? %w[fqdn machinename hostname platform platform_version os os_version] : nil
|
283
|
+
ohai.all_plugins(filter)
|
276
284
|
@events.ohai_completed(node)
|
277
285
|
end
|
278
286
|
|
data/lib/chef/config.rb
CHANGED
@@ -305,6 +305,14 @@ class Chef
|
|
305
305
|
|
306
306
|
default :pid_file, nil
|
307
307
|
|
308
|
+
# Whether Chef Zero local mode should bind to a port. All internal requests
|
309
|
+
# will go through the socketless code path regardless, so the socket is
|
310
|
+
# only needed if other processes will connect to the local mode server.
|
311
|
+
#
|
312
|
+
# For compatibility this is set to true but it will be changed to false in
|
313
|
+
# the future.
|
314
|
+
default :listen, true
|
315
|
+
|
308
316
|
config_context :chef_zero do
|
309
317
|
config_strict_mode true
|
310
318
|
default(:enabled) { Chef::Config.local_mode }
|
@@ -333,6 +341,11 @@ class Chef
|
|
333
341
|
# This can be removed when audit-mode is enabled by default.
|
334
342
|
default :audit_mode, :disabled
|
335
343
|
|
344
|
+
# Chef only needs ohai to run the hostname plugin for the most basic
|
345
|
+
# functionality. If the rest of the ohai plugins are not needed (like in
|
346
|
+
# most of our testing scenarios)
|
347
|
+
default :minimal_ohai, false
|
348
|
+
|
336
349
|
# Policyfile is an experimental feature where a node gets its run list and
|
337
350
|
# cookbook version set from a single document on the server instead of
|
338
351
|
# expanding the run list and having the server compute the cookbook version
|
@@ -88,15 +88,21 @@ class Chef
|
|
88
88
|
#Exception message: %4
|
89
89
|
#Exception backtrace: %5
|
90
90
|
def run_failed(e)
|
91
|
+
data =
|
92
|
+
if @run_status
|
93
|
+
[@run_status.run_id,
|
94
|
+
@run_status.elapsed_time.to_s]
|
95
|
+
else
|
96
|
+
["UNKNOWN", "UNKNOWN"]
|
97
|
+
end
|
98
|
+
|
91
99
|
@eventlog.report_event(
|
92
100
|
:event_type => ::Win32::EventLog::ERROR_TYPE,
|
93
101
|
:source => SOURCE,
|
94
102
|
:event_id => RUN_FAILED_EVENT_ID,
|
95
|
-
:data => [
|
96
|
-
|
97
|
-
|
98
|
-
e.message,
|
99
|
-
e.backtrace.join("\n")]
|
103
|
+
:data => data + [e.class.name,
|
104
|
+
e.message,
|
105
|
+
e.backtrace.join("\n")]
|
100
106
|
)
|
101
107
|
end
|
102
108
|
|
data/lib/chef/http.rb
CHANGED
@@ -25,6 +25,7 @@ require 'tempfile'
|
|
25
25
|
require 'net/https'
|
26
26
|
require 'uri'
|
27
27
|
require 'chef/http/basic_client'
|
28
|
+
require 'chef/http/socketless_chef_zero_client'
|
28
29
|
require 'chef/monkey_patches/net_http'
|
29
30
|
require 'chef/config'
|
30
31
|
require 'chef/platform/query_helpers'
|
@@ -196,14 +197,18 @@ class Chef
|
|
196
197
|
|
197
198
|
def http_client(base_url=nil)
|
198
199
|
base_url ||= url
|
199
|
-
|
200
|
+
if chef_zero_uri?(base_url)
|
201
|
+
SocketlessChefZeroClient.new(base_url)
|
202
|
+
else
|
203
|
+
BasicClient.new(base_url, :ssl_policy => Chef::HTTP::APISSLPolicy)
|
204
|
+
end
|
200
205
|
end
|
201
206
|
|
202
207
|
protected
|
203
208
|
|
204
209
|
def create_url(path)
|
205
210
|
return path if path.is_a?(URI)
|
206
|
-
if path =~ /^(http|https):\/\//i
|
211
|
+
if path =~ /^(http|https|chefzero):\/\//i
|
207
212
|
URI.parse(path)
|
208
213
|
elsif path.nil? or path.empty?
|
209
214
|
URI.parse(@url)
|
@@ -292,7 +297,7 @@ class Chef
|
|
292
297
|
http_attempts += 1
|
293
298
|
response, request, return_value = yield
|
294
299
|
# handle HTTP 50X Error
|
295
|
-
if response.kind_of?(Net::HTTPServerError)
|
300
|
+
if response.kind_of?(Net::HTTPServerError) && !Chef::Config.local_mode
|
296
301
|
if http_retry_count - http_attempts + 1 > 0
|
297
302
|
sleep_time = 1 + (2 ** http_attempts) + rand(2 ** http_attempts)
|
298
303
|
Chef::Log.error("Server returned error #{response.code} for #{url}, retrying #{http_attempts}/#{http_retry_count} in #{sleep_time}s")
|
@@ -351,6 +356,11 @@ class Chef
|
|
351
356
|
|
352
357
|
private
|
353
358
|
|
359
|
+
def chef_zero_uri?(uri)
|
360
|
+
uri = URI.parse(uri) unless uri.respond_to?(:scheme)
|
361
|
+
uri.scheme == "chefzero"
|
362
|
+
end
|
363
|
+
|
354
364
|
def redirected_to(response)
|
355
365
|
return nil unless response.kind_of?(Net::HTTPRedirection)
|
356
366
|
# Net::HTTPNotModified is undesired subclass of Net::HTTPRedirection so test for this
|
@@ -97,7 +97,9 @@ class Chef
|
|
97
97
|
|
98
98
|
#adapted from buildr/lib/buildr/core/transports.rb
|
99
99
|
def proxy_uri
|
100
|
-
proxy = Chef::Config["#{url.scheme}_proxy"]
|
100
|
+
proxy = Chef::Config["#{url.scheme}_proxy"] ||
|
101
|
+
env["#{url.scheme.upcase}_PROXY"] || env["#{url.scheme}_proxy"]
|
102
|
+
|
101
103
|
# Check if the proxy string contains a scheme. If not, add the url's scheme to the
|
102
104
|
# proxy before parsing. The regex /^.*:\/\// matches, for example, http://.
|
103
105
|
proxy = if proxy.match(/^.*:\/\//)
|
@@ -105,7 +107,8 @@ class Chef
|
|
105
107
|
else
|
106
108
|
URI.parse("#{url.scheme}://#{proxy}")
|
107
109
|
end if String === proxy
|
108
|
-
|
110
|
+
no_proxy = Chef::Config[:no_proxy] || env['NO_PROXY'] || env['no_proxy']
|
111
|
+
excludes = no_proxy.to_s.split(/\s*,\s*/).compact
|
109
112
|
excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
|
110
113
|
return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
|
111
114
|
end
|
@@ -126,18 +129,32 @@ class Chef
|
|
126
129
|
Chef::Config
|
127
130
|
end
|
128
131
|
|
132
|
+
def env
|
133
|
+
ENV
|
134
|
+
end
|
135
|
+
|
129
136
|
def http_client_builder
|
130
137
|
http_proxy = proxy_uri
|
131
138
|
if http_proxy.nil?
|
132
139
|
Net::HTTP
|
133
140
|
else
|
134
141
|
Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
|
135
|
-
user =
|
136
|
-
pass =
|
142
|
+
user = http_proxy_user(http_proxy)
|
143
|
+
pass = http_proxy_pass(http_proxy)
|
137
144
|
Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass)
|
138
145
|
end
|
139
146
|
end
|
140
147
|
|
148
|
+
def http_proxy_user(http_proxy)
|
149
|
+
http_proxy.user || Chef::Config["#{url.scheme}_proxy_user"] ||
|
150
|
+
env["#{url.scheme.upcase}_PROXY_USER"] || env["#{url.scheme}_proxy_user"]
|
151
|
+
end
|
152
|
+
|
153
|
+
def http_proxy_pass(http_proxy)
|
154
|
+
http_proxy.password || Chef::Config["#{url.scheme}_proxy_pass"] ||
|
155
|
+
env["#{url.scheme.upcase}_PROXY_PASS"] || env["#{url.scheme}_proxy_pass"]
|
156
|
+
end
|
157
|
+
|
141
158
|
def configure_ssl(http_client)
|
142
159
|
http_client.use_ssl = true
|
143
160
|
ssl_policy.apply_to(http_client)
|
@@ -0,0 +1,207 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Daniel DeLeo (<dan@chef.io>)
|
3
|
+
# Copyright:: Copyright (c) 2015 Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
# ---
|
19
|
+
# Some portions of the code in this file are verbatim copies of code from the
|
20
|
+
# fakeweb project: https://github.com/chrisk/fakeweb
|
21
|
+
#
|
22
|
+
# fakeweb is distributed under the MIT license, which is copied below:
|
23
|
+
# ---
|
24
|
+
#
|
25
|
+
# Copyright 2006-2010 Blaine Cook, Chris Kampmeier, and other contributors
|
26
|
+
#
|
27
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
28
|
+
# a copy of this software and associated documentation files (the
|
29
|
+
# "Software"), to deal in the Software without restriction, including
|
30
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
31
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
32
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
33
|
+
# the following conditions:
|
34
|
+
|
35
|
+
# The above copyright notice and this permission notice shall be
|
36
|
+
# included in all copies or substantial portions of the Software.
|
37
|
+
|
38
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
39
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
40
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
41
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
42
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
43
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
44
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
45
|
+
|
46
|
+
require 'chef_zero/server'
|
47
|
+
|
48
|
+
class Chef
|
49
|
+
class HTTP
|
50
|
+
|
51
|
+
# HTTP Client class that talks directly to Zero via the Rack interface.
|
52
|
+
class SocketlessChefZeroClient
|
53
|
+
|
54
|
+
# This module is extended into Net::HTTP Response objects created from
|
55
|
+
# Socketless Chef Zero responses.
|
56
|
+
module ResponseExts
|
57
|
+
|
58
|
+
# Net::HTTP raises an error if #read_body is called with a block or
|
59
|
+
# file argument after the body has already been read from the network.
|
60
|
+
#
|
61
|
+
# Since we always set the body to the string response from Chef Zero
|
62
|
+
# and set the `@read` indicator variable, we have to patch this method
|
63
|
+
# or else streaming-style responses won't work.
|
64
|
+
def read_body(dest = nil, &block)
|
65
|
+
if dest
|
66
|
+
raise "responses from socketless chef zero can't be written to specific destination"
|
67
|
+
end
|
68
|
+
|
69
|
+
if block_given?
|
70
|
+
block.call(@body)
|
71
|
+
else
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :url
|
79
|
+
|
80
|
+
# copied verbatim from webrick (2-clause BSD License)
|
81
|
+
#
|
82
|
+
# HTTP status codes and descriptions
|
83
|
+
STATUS_MESSAGE = {
|
84
|
+
100 => 'Continue',
|
85
|
+
101 => 'Switching Protocols',
|
86
|
+
200 => 'OK',
|
87
|
+
201 => 'Created',
|
88
|
+
202 => 'Accepted',
|
89
|
+
203 => 'Non-Authoritative Information',
|
90
|
+
204 => 'No Content',
|
91
|
+
205 => 'Reset Content',
|
92
|
+
206 => 'Partial Content',
|
93
|
+
207 => 'Multi-Status',
|
94
|
+
300 => 'Multiple Choices',
|
95
|
+
301 => 'Moved Permanently',
|
96
|
+
302 => 'Found',
|
97
|
+
303 => 'See Other',
|
98
|
+
304 => 'Not Modified',
|
99
|
+
305 => 'Use Proxy',
|
100
|
+
307 => 'Temporary Redirect',
|
101
|
+
400 => 'Bad Request',
|
102
|
+
401 => 'Unauthorized',
|
103
|
+
402 => 'Payment Required',
|
104
|
+
403 => 'Forbidden',
|
105
|
+
404 => 'Not Found',
|
106
|
+
405 => 'Method Not Allowed',
|
107
|
+
406 => 'Not Acceptable',
|
108
|
+
407 => 'Proxy Authentication Required',
|
109
|
+
408 => 'Request Timeout',
|
110
|
+
409 => 'Conflict',
|
111
|
+
410 => 'Gone',
|
112
|
+
411 => 'Length Required',
|
113
|
+
412 => 'Precondition Failed',
|
114
|
+
413 => 'Request Entity Too Large',
|
115
|
+
414 => 'Request-URI Too Large',
|
116
|
+
415 => 'Unsupported Media Type',
|
117
|
+
416 => 'Request Range Not Satisfiable',
|
118
|
+
417 => 'Expectation Failed',
|
119
|
+
422 => 'Unprocessable Entity',
|
120
|
+
423 => 'Locked',
|
121
|
+
424 => 'Failed Dependency',
|
122
|
+
426 => 'Upgrade Required',
|
123
|
+
428 => 'Precondition Required',
|
124
|
+
429 => 'Too Many Requests',
|
125
|
+
431 => 'Request Header Fields Too Large',
|
126
|
+
500 => 'Internal Server Error',
|
127
|
+
501 => 'Not Implemented',
|
128
|
+
502 => 'Bad Gateway',
|
129
|
+
503 => 'Service Unavailable',
|
130
|
+
504 => 'Gateway Timeout',
|
131
|
+
505 => 'HTTP Version Not Supported',
|
132
|
+
507 => 'Insufficient Storage',
|
133
|
+
511 => 'Network Authentication Required',
|
134
|
+
}
|
135
|
+
|
136
|
+
STATUS_MESSAGE.values.each {|v| v.freeze }
|
137
|
+
STATUS_MESSAGE.freeze
|
138
|
+
|
139
|
+
def initialize(base_url)
|
140
|
+
@url = base_url
|
141
|
+
end
|
142
|
+
|
143
|
+
def host
|
144
|
+
@url.hostname
|
145
|
+
end
|
146
|
+
|
147
|
+
def port
|
148
|
+
@url.port
|
149
|
+
end
|
150
|
+
|
151
|
+
def request(method, url, body, headers, &handler_block)
|
152
|
+
request = req_to_rack(method, url, body, headers)
|
153
|
+
res = ChefZero::SocketlessServerMap.request(port, request)
|
154
|
+
|
155
|
+
net_http_response = to_net_http(res[0], res[1], res[2])
|
156
|
+
|
157
|
+
yield net_http_response if block_given?
|
158
|
+
|
159
|
+
[self, net_http_response]
|
160
|
+
end
|
161
|
+
|
162
|
+
def req_to_rack(method, url, body, headers)
|
163
|
+
body_str = body || ""
|
164
|
+
{
|
165
|
+
"SCRIPT_NAME" => "",
|
166
|
+
"SERVER_NAME" => "localhost",
|
167
|
+
"REQUEST_METHOD" => method.to_s.upcase,
|
168
|
+
"PATH_INFO" => url.path,
|
169
|
+
"QUERY_STRING" => url.query,
|
170
|
+
"SERVER_PORT" => url.port,
|
171
|
+
"HTTP_HOST" => "localhost:#{url.port}",
|
172
|
+
"rack.url_scheme" => "chefzero",
|
173
|
+
"rack.input" => StringIO.new(body_str),
|
174
|
+
}
|
175
|
+
end
|
176
|
+
|
177
|
+
def to_net_http(code, headers, chunked_body)
|
178
|
+
body = chunked_body.join('')
|
179
|
+
msg = STATUS_MESSAGE[code] or raise "Cannot determine HTTP status message for code #{code}"
|
180
|
+
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
|
181
|
+
response.instance_variable_set(:@body, body)
|
182
|
+
headers.each do |name, value|
|
183
|
+
if value.respond_to?(:each)
|
184
|
+
value.each { |v| response.add_field(name, v) }
|
185
|
+
else
|
186
|
+
response[name] = value
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
response.instance_variable_set(:@read, true)
|
191
|
+
response.extend(ResponseExts)
|
192
|
+
response
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def headers_extracted_from_options
|
198
|
+
options.reject {|name, _| KNOWN_OPTIONS.include?(name) }.map { |name, value|
|
199
|
+
[name.to_s.split("_").map { |segment| segment.capitalize }.join("-"), value]
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|