summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Morrow <jon@morrowmail.com>2015-04-10 12:02:30 -0700
committerJon Morrow <jon@morrowmail.com>2015-04-14 16:44:19 -0700
commit4dd42c8ea0c738489f9e4a0df20133a328ce06e5 (patch)
tree32e62d8d36871ab8dd2f480f56a31c532cc196cd
parent28620c815fabc1eba6e7a047f571d3be7a1efe52 (diff)
downloadchef-4dd42c8ea0c738489f9e4a0df20133a328ce06e5.tar.gz
Fixes 2140 - Honor Proxy from Env
This change adds support to Chef's core http libs to honor a proxy uri set in the environment not just chef/knife config. It also adds support for username and password both in uri and env. The order of precidence for values is uri, config, env.
-rw-r--r--lib/chef/http/basic_client.rb25
-rw-r--r--spec/unit/http/basic_client_spec.rb49
2 files changed, 64 insertions, 10 deletions
diff --git a/lib/chef/http/basic_client.rb b/lib/chef/http/basic_client.rb
index f0f5151dbd..076d152d16 100644
--- a/lib/chef/http/basic_client.rb
+++ b/lib/chef/http/basic_client.rb
@@ -97,7 +97,9 @@ class Chef
#adapted from buildr/lib/buildr/core/transports.rb
def proxy_uri
- proxy = Chef::Config["#{url.scheme}_proxy"]
+ proxy = Chef::Config["#{url.scheme}_proxy"] ||
+ env["#{url.scheme.upcase}_PROXY"] || env["#{url.scheme}_proxy"]
+
# Check if the proxy string contains a scheme. If not, add the url's scheme to the
# proxy before parsing. The regex /^.*:\/\// matches, for example, http://.
proxy = if proxy.match(/^.*:\/\//)
@@ -105,7 +107,8 @@ class Chef
else
URI.parse("#{url.scheme}://#{proxy}")
end if String === proxy
- excludes = Chef::Config[:no_proxy].to_s.split(/\s*,\s*/).compact
+ no_proxy = Chef::Config[:no_proxy] || env['NO_PROXY'] || env['no_proxy']
+ excludes = no_proxy.to_s.split(/\s*,\s*/).compact
excludes = excludes.map { |exclude| exclude =~ /:\d+$/ ? exclude : "#{exclude}:*" }
return proxy unless excludes.any? { |exclude| File.fnmatch(exclude, "#{host}:#{port}") }
end
@@ -126,18 +129,32 @@ class Chef
Chef::Config
end
+ def env
+ ENV
+ end
+
def http_client_builder
http_proxy = proxy_uri
if http_proxy.nil?
Net::HTTP
else
Chef::Log.debug("Using #{http_proxy.host}:#{http_proxy.port} for proxy")
- user = Chef::Config["#{url.scheme}_proxy_user"]
- pass = Chef::Config["#{url.scheme}_proxy_pass"]
+ user = http_proxy_user(http_proxy)
+ pass = http_proxy_pass(http_proxy)
Net::HTTP.Proxy(http_proxy.host, http_proxy.port, user, pass)
end
end
+ def http_proxy_user(http_proxy)
+ http_proxy.user || Chef::Config["#{url.scheme}_proxy_user"] ||
+ env["#{url.scheme.upcase}_PROXY_USER"] || env["#{url.scheme}_proxy_user"]
+ end
+
+ def http_proxy_pass(http_proxy)
+ http_proxy.password || Chef::Config["#{url.scheme}_proxy_pass"] ||
+ env["#{url.scheme.upcase}_PROXY_PASS"] || env["#{url.scheme}_proxy_pass"]
+ end
+
def configure_ssl(http_client)
http_client.use_ssl = true
ssl_policy.apply_to(http_client)
diff --git a/spec/unit/http/basic_client_spec.rb b/spec/unit/http/basic_client_spec.rb
index eb133f943e..32b32a5f4c 100644
--- a/spec/unit/http/basic_client_spec.rb
+++ b/spec/unit/http/basic_client_spec.rb
@@ -21,7 +21,7 @@ require 'chef/http/basic_client'
describe "HTTP Connection" do
let(:uri) { URI("https://example.com:4443") }
- subject { Chef::HTTP::BasicClient.new(uri) }
+ subject(:basic_client) { Chef::HTTP::BasicClient.new(uri) }
describe ".new" do
it "creates an instance" do
@@ -45,11 +45,6 @@ describe "HTTP Connection" do
let(:proxy_port) { 8080 }
let(:proxy) { "#{proxy_prefix}#{proxy_host}:#{proxy_port}" }
- before do
- Chef::Config["#{uri.scheme}_proxy"] = proxy
- Chef::Config[:no_proxy] = nil
- end
-
it "should contain the host" do
proxy_uri = subject.proxy_uri
expect(proxy_uri.host).to eq(proxy_host)
@@ -63,14 +58,56 @@ describe "HTTP Connection" do
context "when the config setting is normalized (does not contain the scheme)" do
include_examples "a proxy uri" do
+
let(:proxy_prefix) { "" }
+
+ before do
+ Chef::Config["#{uri.scheme}_proxy"] = proxy
+ Chef::Config[:no_proxy] = nil
+ end
+
end
end
context "when the config setting is not normalized (contains the scheme)" do
include_examples "a proxy uri" do
let(:proxy_prefix) { "#{uri.scheme}://" }
+
+ before do
+ Chef::Config["#{uri.scheme}_proxy"] = proxy
+ Chef::Config[:no_proxy] = nil
+ end
+
+ end
+ end
+
+ context "when the proxy is set by the environment" do
+
+ include_examples "a proxy uri" do
+
+ let(:env) do
+ {
+ "https_proxy" => "https://proxy.mycorp.com:8080",
+ "https_proxy_user" => "jane_username",
+ "https_proxy_pass" => "opensesame"
+ }
+ end
+
+ let(:proxy_uri) { URI.parse(env["https_proxy"]) }
+
+ before do
+ allow(basic_client).to receive(:env).and_return(env)
+ end
+
+ it "sets the proxy user" do
+ expect(basic_client.http_proxy_user(proxy_uri)).to eq("jane_username")
+ end
+
+ it "sets the proxy pass" do
+ expect(basic_client.http_proxy_pass(proxy_uri)).to eq("opensesame")
+ end
end
+
end
end
end