diff options
author | tyler-ball <tyleraball@gmail.com> | 2015-12-08 17:02:23 -0700 |
---|---|---|
committer | tyler-ball <tyleraball@gmail.com> | 2015-12-09 14:23:54 -0700 |
commit | 85d0407a16fa4dfc479d550a96355a6d11f4f551 (patch) | |
tree | 5be428017e0883fdcaa19c74308bb73783270071 | |
parent | 200c3e5b71ec269efffbfb97e94f1a7aada951af (diff) | |
download | chef-85d0407a16fa4dfc479d550a96355a6d11f4f551.tar.gz |
Moving the proxy export to environment varibles into Chef::Config
-rw-r--r-- | .travis.yml | 92 | ||||
-rw-r--r-- | chef-config/lib/chef-config/config.rb | 61 | ||||
-rw-r--r-- | chef-config/spec/unit/config_spec.rb | 108 | ||||
-rw-r--r-- | lib/chef/application.rb | 84 | ||||
-rw-r--r-- | lib/chef/application/apply.rb | 2 | ||||
-rw-r--r-- | lib/chef/knife.rb | 1 | ||||
-rw-r--r-- | lib/chef/knife/ssl_check.rb | 2 | ||||
-rw-r--r-- | spec/functional/application_spec.rb | 2 | ||||
-rw-r--r-- | spec/unit/application_spec.rb | 182 | ||||
-rw-r--r-- | spec/unit/mixin/proxified_socket_spec.rb | 4 |
10 files changed, 267 insertions, 271 deletions
diff --git a/.travis.yml b/.travis.yml index 6b8c0dfd33..78303d7591 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,22 +26,108 @@ env: matrix: include: + - rvm: 2.1 + sudo: true + - rvm: 2.2 + sudo: true - rvm: rbx sudo: true - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'chef-zero', github: 'chef/chef-zero'\"" + script: bundle exec rake chef_zero_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'cheffish', github: 'chef/cheffish'\"" + script: bundle exec rake cheffish_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'chef-provisioning', github: 'chef/chef-provisioning'\"" + script: bundle exec rake chef_provisioning_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'chef-provisioning-aws', github: 'chef/chef-provisioning-aws'\"" + script: bundle exec rake chef_provisioning_aws_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'chefspec'\"" + script: bundle exec rake chefspec_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'chef-sugar'\"" + script: bundle exec rake chef_sugar_spec + # Requires vagrant + # - rvm: 2.2 + # cache: + # env: "GEMFILE_MOD=\"gem 'chef-rewind'\"" + # script: bundle exec rake chef_rewind_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'foodcritic', github: 'acrmp/foodcritic', branch: 'v5.0.0'\"" + script: bundle exec rake foodcritic_spec + - rvm: 2.2 + before_install: + env: "GEMFILE_MOD=\"gem 'halite', github: 'poise/halite'\"" + script: bundle exec rake halite_spec + - rvm: 2.2 + env: "GEMFILE_MOD=\"gem 'poise', github: 'poise/poise'\"" + script: bundle exec rake poise_spec + ### START TEST KITCHEN ONLY ### + - rvm: 2.2 + gemfile: kitchen-tests/Gemfile + before_install: + - echo -n $DO_KEY_CHUNK_{0..30} >> ~/.ssh/id_aws.base64 + - cat ~/.ssh/id_aws.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_aws.pem + before_script: + - cd kitchen-tests + script: +# FIXME: we should fix centos-6 against AWS and then enable it here + - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen test ubuntu; fi + after_failure: + - cat .kitchen/logs/kitchen.log + after_script: + - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then bundle exec kitchen destroy ubuntu; fi + env: + - KITCHEN_YAML=.kitchen.travis.yml + - EC2_SSH_KEY_PATH=~/.ssh/id_aws.pem + - secure: VAauyVnAMWhqvnhJOJ/tCDn3XAdWqzbWiDVQPNBkqtm2SBIvhmZl2hlrusvw6YLU31Prdf8fSFhOSysVQQs/rJYrmD/1BfV79p6M7cGXYZ0nGWwldF81N296lyFoZLyrqtmG4G0cx3Pw2ojADFgFe+B5eTGlqJFD+z371g4RF/Y= + - secure: A+qtUF2LPJGkUAdvt04AwZMt69rzaeTyR0/1XEOAuntBKKXSCzddUzr5ePDc9QQ/57AWywKxhVLpnxk3QzKN7r7zerDxyIJBgklNDpNAKkeQjP3T6FpaKEIN9ROcpPtsM6FJ5Agb+bEQoRJF7s+ampO3wLV3XpTiWNuWkcAhv9A= + - secure: J8JIg15trrPgc8X/1DsaUWDQCdDWTvN/AorXzZ/ReudHS6G/KpoynZ5lTmKjlgFiFNE/TGMDv486pStGtIcarTKTuIEmNADdEWlAVH7bxclpayMjtppVuapRCkZWccs5gz5CJyhX7yhQCFTYoqVox9Y4qHGCluF3oqCcPRtCOOw= + - secure: NJYn0blTMwIoFxZlsoMWK8hPO/fi45rgWOqEImnjvSRk++5WL+GgjLBgLvEi7wCMkBijhIMWtnva60ojd4MrxeS7evrmGRjJKXnPuSKEsrGbArZPskBjCAcg+3PlnQQUkFf6hvbGD3HZlJtcbs4hrx8tbDT2Ie7bmQfqpsawKY4= + - secure: FipoX1VzZkzPUP6Gxd05DEva7cX6xKK2Wdq+Y18nNkyW2afPLXCNl5kCsNrgvbqAzbjKaP2M8+b0zwKjrFzNebqmmx1RRfZUJWUkNRF1EgE+tHytmMZW6tNcQlTlvA0KqXi4Dt6SIQ0l/DhwwNKZ80jmpiyYi/ErxIXzbVgVtYA= + - secure: T2MbE9twIkdaor796/lDioCgb2+FP3G8lXq+lIqnjaL22WMP8yKtkjNo8ggSlvQZE7MAQHqi5LISw5MU2MI6ImTU50/pgdWreM5Cx37WWYqntcbJ0Sz7v396KGJzeqbDql1fGolHDlykfi+OJzzbIGC8cjz7iAD2RUZU95wEC5s= + - secure: hWEQInvuanQavFCE3m6/q9BjNEFZQmLc94EWnBKTMiwUAdYgQQMLohN7K1Gc8irxYKp86F+P+XWE4lfDZNK3sqmxyk51TtT2EfmKWs+jSLq4+NBYQwXCpRELC5Irpm0GRCYthhsQSuarpVWss/0s0o7iJQaHxrSPcQiwDouIpwU= + - secure: OllJUaR/WUu+H0FIjU7vQxU10JT4d+/FZuTqnX6ZTcXN3dXCirnabYp/j+r5OBY3QeOojOyzGfHUWYEUGH/PTxcxYjrohtFTWht9N9x+SxfX2fLqieH/kRKyDmIidsY8qKChf/LD9f+SwpXRXND/PctKhNR4C5BH57fGUEqE9FU= + - secure: KgKnGtM4e+cVYfLn78eTWJ1q4ORv128abB72QBc/xiSh0rvxSIojVKZCXmRetQPXIl7NoIzU2IyjR1ABEZ+vA83PayTEsOr2KDRDgolSIgZSSiDFt4U2phQsxl4fX7wFv/jWlbxM2fysKBSIRAF57CwBjGhLjmpUO+5PdoR7N2s= + - secure: IgOx4STauKnJWENQGcn2iBp32XcNd2anNR0Fua0ugjudu1+CV+IxcIhI8ohOfZEXyVK4MGTF8uXWrYtoiwyExG4mTXqpRWJCgIkncqiWlfT+8BoAGWxCQhUYub3MaNZANPgebKPJhTPQ8OwNz09gPMNkewRfAqNF05eb8FU2kGA= + - secure: CPXP6g3c1FH4Zm4U19XaPvq9nnyNsQCXRkxiPcGqsJZsGG2QMgzPQyjiAuPqnWxxZHit/6NgzUszJC+skSgcTzDTeD6rOA0Wcxtbr/Un4RRxRnTcRc6mSEZqSu9RbAZMYur/mSQ9HDHnjFe1ok85He4s9jM1iFdgjtg1ToelEmA= + - secure: fp9pzNe09PIyZ/8NjbMPGW1zdG3Q/KhJ+stUKqA+FRopAMX/Hh24gFIVJhFOmfr4Vhn0J8sF7RsFaR1mdzcPewliOzKxknWhGEGMcG9LFCZcv+vVK0Fxs4nUzCRtaXUt08FpsRofG0iBvfapZ7YBhK7lslqGVI+fxCd3ZXmayG8= + - secure: NT/6qcecxmuKYOnw1Atc6hsyJlfB6XI2Z1lg7dE0PhlEVW2EpkckHjAc+5hgg8Zt7TifYm2qDQWJwblwPP0mMj3ra4ZIMaZAiG2kzQoZ5kthqwjAV9fatZvrDXi+jd9wBF2hPyiCokAQiTLmKTYjzY2FBqPO3VDLWdf9qZqRmxw= + - secure: MjIWyfquKANh/YeoyHGksdvAUQ4wc2tBCQmq1QcRhKwb7Sy6wcDk1nujDmnGE7HFpZUS6CyoZF7AMzJGFkCzrChpsLQYUP4hc7VjkXOLzi90vJUl+ANq7KPOmxC0MjKpgeHqCysRbTYbUsnJZfbbZbIZjCAjY0YCY2pGniXpvQc= + - secure: AsZLOiFrHkGsY6jp2ShI5kYz78V6PEUyizgtPCWTgevTRGWpdCq9csIEoqUBY+vMUxmQPC6IY4fwHkrRCbv/rJyhwRl/Rnwa3aw8bdD+YD17IxnpXKGXXUyXdTZmF7HzAkVgStehL+qWZ3x9TBdExIV37KVgrVw/b+S0QqBUlQo= + - secure: jwEnSquLreMM1M6N3gGpgTGHd8VtjBUTLDdkrokhiH1jHLpz7Hmr6xeajhZws+2sLtLiB7hYi6WsZBE5VcymBoObh9MeodO9Ve5/1z06lFmx1DyYV6euyo9WUkU2WpoVfu8k7O+eAvyrXXZVqm8Oz1p7Isb6Bh5+fJH2H8rhed4= + - secure: HOAK620U6mlS11XK+JtXTBk26Tt2vWO4shA/6Zit/y0/kAz7JnbXtup7FSysXliBoSv4YsxA6IbgZ8V0tuIXj+q7EcqtHMmQhqzMJG5jRKVhtGiFIhDmwmxJvdfIvwtZOO3mMk0OspLz24sWp8wCciYZMPj0hZJR04R9aWEO3cE= + - secure: DfTRP74UWWxA460XfLoJFgRLwoKbHWNIueL6qr982AnuAxeZFofsxCqxSxcSJmu67TxuPc+b201+BmanHKYmSauGS31t0F4QXk7lCTaT/x38mAPsWvMFkY8HEl56JhmzEp2hAKDB/t0/HItwmvxT1vd5WvNRSSojEVzChftV/zE= + - secure: JoCWsJzTgj+epgzmgbvV7/bdAPHwUGXZA7Jdvv9vIJ5lCo6h9WwCw6/KCvH+bHtrT/RfZmUmxouCxJCLKwts1ZrMmedTIXpMrQJo/YgWRp7ziFnLyZ8jG8bD7rep3ngq1x/cRGc3cZvYN6IK3GS6C27OviYLFsTw74AUnWTaFSo= + - secure: iXfl0WnAnfKurZUrMeV1yOoFiiZ+MKx/Zj6ZVP2++A9EOxxIxb/fS/gIOzSjBQwzrR+fJVHIlX0g42CiBKDQWUvIl5I8kZCVIP6AHa1jyzlmZE9lqSlojz3k5RPS7pW6nIX+z1NHMvtb3e5xeLv8y4J5kwZErqZ+YDJmBRtPxPU= + - secure: RhAW5kABDPB3GWKD+NCg05Kcd92F/+kg+0icXXN166DWQYUut3MLrSY80xNzkz5nXTI9EFU4fUqlKLDiF/kelr0Zp/zpCQAB54o4cu5FkZz0Bgs9k7yUdCRyz6Vt2ChV5cYI4JTn9bMaeXEaGlOjP1iE51rYT6KO6kKlwsEnjUc= + - secure: jy/3fC+UtrDcE/X6/IxkyT2SrYMKkiEMP1ht4d5mxvNA0Xxn43E16c6FNP0JWPpWRGRIP38vnQRB4yOPU9BXvRmmswVL9Ge4e/6flJvKwD5Rlqb2dfaGaHRYV9v8Nkdzl2FvZ9eBH5KHxgG19gCG6L3RXP/+zYwrr4AQdm0fpfw= + - secure: RYEwBWYVXRTEdUWhQxdWXo6tldlVx8pha9zB0rgafcUQxaatAefnRc4X4HXTQnqr2n9TZ2TQGpM8vte/wr6Pjc85VZbimWGzgrvn0kg4MwPR8ZYiEM5qQ/pUpj4+93rpA91PhCGvZoZTqOrXHm4kMPuKro5I6qA4BFUXuANeC/s= + - secure: gHSicpqkqcZT04QurSgszrAiI6HOCw1DBlfIIi9KAJj7mG5GijD/4AQ6HCmcRMbCDJ0nUuvm/kckASnRtF5+3xvIJnuoyyEfCZWxt1lhK2UbS87VU+pVdws/VzwpisXuKsh3H0uT8DDVkWPH/ZWDgfVa74eYDEHiQFjo+2xx5ZA= + - secure: Q42bco3JXEpyVbL2akiOsaCHnAagAFIb3TF6H5qJfaLLqmGs/XrrgxliNaVMfWVSwPT2wpQvg9UGF9x37No9bZBv33DgYcWExmXb/lvGPpkctX37+FTMzECQHxOuUbYPQA7ZEuJ4AA7bwgpMISUeSyz5XXz44KcXIrZK2GWH+X4= + - secure: hugd8NVukJc3redDvlOt6zhaqa63XLNMp/eIIlNllW8VfQ6CJ1P7KJPwgxH24sDyrw7rLzOkBl6R4kaVWsCLCFp+NE6yFFHl9wDkSdLC1OX1DMrJnDsogwUqqe+jX8dxePSy26MSTfG8eo9/NxN9uXr+tKaHoi6G7BRXDHtQ8dQ= + - secure: TRkW9pIuIYHXJmPlDYoddxIp2M2W2f7qBGNJKEMB5xrOezES7w9XTg2eQXrD8jBO+fUUmMnAaDAXZuU58nMysPXx3vhtZKncg8w5CyuXJk2P8nkdPh0u5nmRhEpWrLKtLwJrX48xmJhNQvQqDAyL5c9WUzlWJ4WJFgoP5IDWmLc= + - secure: QHuMdtFCvttiIOx6iS+lH4bKXZMwsgVQ6FPsUW5zJ7uw6mAEWKEil9xNk4aYV9FywinwUs4fnFlnIW/Gj1gLkUjm4DtxdmRZIlRXIbgsNch6H916TCPg4Q2oPsW2nVdXPjW/2jhkfLUiSnuhL+ylami1NF8Up7vokXknh/jFNZU= + - secure: GTfrUVmMQSxho3Ia4Y1ONqKvVMD34GHF2/TJb8UdQV7iH+nVxVXpy3nWaCXa9ri7lRzMefkoVLy0gKK13YoVd7w3d2S3/IfNakC85XfN6VuOzK/FDkA0WoPrgKjcQ64I+3dQ6cgrMWWTieKwRZy+Ve24iRbnN055Hk+VRMu6OGw= + - secure: SOMYGVfHLkHsH6koxpw68YQ4ydEo6YXPhHbrYGQbehUbFa6+OZzBcAJRJbKjyhD2AZRvNr2jB8XnjYKvVyDGQRpkWhGYZ7CpHqINpDsqKBsbiMe3/+KmKQqS+UKxNGefquoOvyQ1N8Xy77dkWYokRtGMEuR12RkZLonxiDW8Qyg= + - secure: bSsDg+dJnPFdFiC/tbb61HdLh/Q0z2RVVAReT1wvV1BN4fN4NydvkUGbQmyFNyyunLulEs+X0oFma9L0497nUlTnan8UOg9sIleTSybPX6E9xSKKCItH1GgDw8bM9Igez5OOrrePBD3altVrH+FmGx0dlTQgM/KZMN50BJ79cXw= + ### END TEST KITCHEN ONLY ### + - rvm: 2.2 sudo: required dist: trusty - cache: before_install: - sudo apt-get update - - sudo apt-get -y install squid3 git + - sudo apt-get -y install squid3 git curl env: global: - PROXY_TESTS_DIR=proxy_tests/files/default/scripts - PROXY_TESTS_REPO=$PROXY_TESTS_DIR/repo script: - bundle exec chef-client --version - - git clone -b tball/knife_tests https://github.com/chef/proxy_tests.git + - git clone https://github.com/chef/proxy_tests.git - rvmsudo -E bundle exec bash $PROXY_TESTS_DIR/run_tests.sh chef_client \* \* /tmp/out.txt after_script: - cat /tmp/out.txt diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb index 49d775232d..113bf481ff 100644 --- a/chef-config/lib/chef-config/config.rb +++ b/chef-config/lib/chef-config/config.rb @@ -26,6 +26,7 @@ require 'chef-config/logger' require 'chef-config/windows' require 'chef-config/path_helper' require 'mixlib/shellout' +require 'uri' module ChefConfig @@ -710,6 +711,66 @@ module ChefConfig config_context :chefdk do end + configurable(:http_proxy) + configurable(:http_proxy_user) + configurable(:http_proxy_pass) + configurable(:https_proxy) + configurable(:https_proxy_user) + configurable(:https_proxy_pass) + configurable(:ftp_proxy) + configurable(:ftp_proxy_user) + configurable(:ftp_proxy_pass) + configurable(:no_proxy) + + # Public method that users should call to export proxies to the appropriate + # environment variables. This method should be called after the config file is + # parsed and loaded. + # TODO add some post-file-parsing logic that automatically calls this so + # users don't have to + def self.export_proxies + export_proxy("http", http_proxy, http_proxy_user, http_proxy_pass) if http_proxy + export_proxy("https", https_proxy, https_proxy_user, https_proxy_pass) if https_proxy + export_proxy("ftp", ftp_proxy, ftp_proxy_user, ftp_proxy_pass) if ftp_proxy + export_no_proxy("no_proxy", no_proxy) if no_proxy + end + + # Builds a proxy uri and exports it to the appropriate environment variables. Examples: + # http://username:password@hostname:port + # https://username@hostname:port + # ftp://hostname:port + # when + # scheme = "http", "https", or "ftp" + # hostport = hostname:port or scheme://hostname:port + # user = username + # pass = password + # @api private + def self.export_proxy(scheme, path, user, pass) + path = "#{scheme}://#{path}" unless path.include?('://') + # URI.split returns the following parts: + # [scheme, userinfo, host, port, registry, path, opaque, query, fragment] + parts = URI.split(URI.encode(path)) + # URI::Generic.build requires an integer for the port, but URI::split gives + # returns a string for the port. + parts[3] = parts[3].to_i if parts[3] + if user && !user.empty? + userinfo = URI.encode(URI.encode(user), '@:') + if pass + userinfo << ":#{URI.encode(URI.encode(pass), '@:')}" + end + parts[1] = userinfo + end + + path = URI::Generic.build(parts).to_s + ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase] + ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase] + end + + # @api private + def self.export_no_proxy(value) + ENV['no_proxy'] = value unless ENV['no_proxy'] + ENV['NO_PROXY'] = value unless ENV['NO_PROXY'] + end + # Chef requires an English-language UTF-8 locale to function properly. We attempt # to use the 'locale -a' command and search through a list of preferences until we # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be diff --git a/chef-config/spec/unit/config_spec.rb b/chef-config/spec/unit/config_spec.rb index 4af5d4b7c7..0a3dca5b5a 100644 --- a/chef-config/spec/unit/config_spec.rb +++ b/chef-config/spec/unit/config_spec.rb @@ -571,6 +571,114 @@ RSpec.describe ChefConfig::Config do end end + describe "export_proxies" do + let(:http_proxy) { "http://localhost:7979" } + let(:https_proxy) { "https://localhost:7979" } + let(:ftp_proxy) { "ftp://localhost:7979" } + let(:proxy_user) { "http_user" } + let(:proxy_pass) { "http_pass" } + + context "when http_proxy, proxy_pass and proxy_user are set" do + before do + ChefConfig::Config.http_proxy = http_proxy + ChefConfig::Config.http_proxy_user = proxy_user + ChefConfig::Config.http_proxy_pass = proxy_pass + end + it "exports ENV['http_proxy']" do + expect(ENV).to receive(:[]=).with('http_proxy', "http://http_user:http_pass@localhost:7979") + expect(ENV).to receive(:[]=).with('HTTP_PROXY', "http://http_user:http_pass@localhost:7979") + ChefConfig::Config.export_proxies + end + end + + context "when https_proxy, proxy_pass and proxy_user are set" do + before do + ChefConfig::Config.https_proxy = https_proxy + ChefConfig::Config.https_proxy_user = proxy_user + ChefConfig::Config.https_proxy_pass = proxy_pass + end + it "exports ENV['https_proxy']" do + expect(ENV).to receive(:[]=).with('https_proxy', "https://http_user:http_pass@localhost:7979") + expect(ENV).to receive(:[]=).with('HTTPS_PROXY', "https://http_user:http_pass@localhost:7979") + ChefConfig::Config.export_proxies + end + end + + context "when ftp_proxy, proxy_pass and proxy_user are set" do + before do + ChefConfig::Config.ftp_proxy = ftp_proxy + ChefConfig::Config.ftp_proxy_user = proxy_user + ChefConfig::Config.ftp_proxy_pass = proxy_pass + end + it "exports ENV['ftp_proxy']" do + expect(ENV).to receive(:[]=).with('ftp_proxy', "ftp://http_user:http_pass@localhost:7979") + expect(ENV).to receive(:[]=).with('FTP_PROXY', "ftp://http_user:http_pass@localhost:7979") + ChefConfig::Config.export_proxies + end + end + + shared_examples "no user pass" do + it "does not populate the user or password" do + expect(ENV).to receive(:[]=).with('http_proxy', "http://localhost:7979") + expect(ENV).to receive(:[]=).with('HTTP_PROXY', "http://localhost:7979") + ChefConfig::Config.export_proxies + end + end + + context "when proxy_pass and proxy_user are passed as empty strings" do + before do + ChefConfig::Config.http_proxy = http_proxy + ChefConfig::Config.http_proxy_user = "" + ChefConfig::Config.http_proxy_pass = proxy_pass + end + include_examples "no user pass" + end + + context "when proxy_pass and proxy_user are not provided" do + before do + ChefConfig::Config.http_proxy = http_proxy + end + include_examples "no user pass" + end + + context "when the proxy is provided without a scheme" do + before do + ChefConfig::Config.http_proxy = "localhost:1111" + end + it "automatically adds the scheme to the proxy url" do + expect(ENV).to receive(:[]=).with('http_proxy', "http://localhost:1111") + expect(ENV).to receive(:[]=).with('HTTP_PROXY', "http://localhost:1111") + ChefConfig::Config.export_proxies + end + end + + shared_examples "no export" do + it "does not export any proxy settings" do + ChefConfig::Config.export_proxies + expect(ENV['http_proxy']).to eq(nil) + expect(ENV['https_proxy']).to eq(nil) + expect(ENV['ftp_proxy']).to eq(nil) + expect(ENV['no_proxy']).to eq(nil) + end + end + + context "when nothing is set" do + include_examples "no export" + end + + context "when all the users and passwords are set but no proxies are set" do + before do + ChefConfig::Config.http_proxy_user = proxy_user + ChefConfig::Config.http_proxy_pass = proxy_pass + ChefConfig::Config.https_proxy_user = proxy_user + ChefConfig::Config.https_proxy_pass = proxy_pass + ChefConfig::Config.ftp_proxy_user = proxy_user + ChefConfig::Config.ftp_proxy_pass = proxy_pass + end + include_examples "no export" + end + end + describe "allowing chefdk configuration outside of chefdk" do it "allows arbitrary settings in the chefdk config context" do diff --git a/lib/chef/application.rb b/lib/chef/application.rb index 970544c068..a2c415111e 100644 --- a/lib/chef/application.rb +++ b/lib/chef/application.rb @@ -17,7 +17,6 @@ # limitations under the License. require 'pp' -require 'uri' require 'socket' require 'chef/config' require 'chef/config_fetcher' @@ -47,7 +46,6 @@ class Chef def reconfigure configure_chef configure_logging - configure_proxy_environment_variables configure_encoding emit_warnings end @@ -85,6 +83,7 @@ class Chef def configure_chef parse_options load_config_file + Chef::Config.export_proxies end # Parse the config file @@ -180,14 +179,6 @@ class Chef end end - # Configure and set any proxy environment variables according to the config. - def configure_proxy_environment_variables - configure_http_proxy - configure_https_proxy - configure_ftp_proxy - configure_no_proxy - end - # Sets the default external encoding to UTF-8 (users can change this, but they shouldn't) def configure_encoding Encoding.default_external = Chef::Config[:ruby_encoding] @@ -302,79 +293,6 @@ class Chef Chef::Application.fatal!("Aborting due to error in '#{config_file_path}'", 2) end - # Set ENV['http_proxy'] - def configure_http_proxy - if http_proxy = Chef::Config[:http_proxy] - http_proxy_string = configure_proxy("http", http_proxy, - Chef::Config[:http_proxy_user], Chef::Config[:http_proxy_pass]) - env['http_proxy'] = http_proxy_string unless env['http_proxy'] - env['HTTP_PROXY'] = http_proxy_string unless env['HTTP_PROXY'] - end - end - - # Set ENV['https_proxy'] - def configure_https_proxy - if https_proxy = Chef::Config[:https_proxy] - https_proxy_string = configure_proxy("https", https_proxy, - Chef::Config[:https_proxy_user], Chef::Config[:https_proxy_pass]) - env['https_proxy'] = https_proxy_string unless env['https_proxy'] - env['HTTPS_PROXY'] = https_proxy_string unless env['HTTPS_PROXY'] - end - end - - # Set ENV['ftp_proxy'] - def configure_ftp_proxy - if ftp_proxy = Chef::Config[:ftp_proxy] - ftp_proxy_string = configure_proxy("ftp", ftp_proxy, - Chef::Config[:ftp_proxy_user], Chef::Config[:ftp_proxy_pass]) - env['ftp_proxy'] = ftp_proxy_string unless env['ftp_proxy'] - env['FTP_PROXY'] = ftp_proxy_string unless env['FTP_PROXY'] - end - end - - # Set ENV['no_proxy'] - def configure_no_proxy - if Chef::Config[:no_proxy] - env['no_proxy'] = Chef::Config[:no_proxy] unless env['no_proxy'] - env['NO_PROXY'] = Chef::Config[:no_proxy] unless env['NO_PROXY'] - end - end - - # Builds a proxy uri. Examples: - # http://username:password@hostname:port - # https://username@hostname:port - # ftp://hostname:port - # when - # scheme = "http", "https", or "ftp" - # hostport = hostname:port - # user = username - # pass = password - def configure_proxy(scheme, path, user, pass) - begin - path = "#{scheme}://#{path}" unless path.include?('://') - # URI.split returns the following parts: - # [scheme, userinfo, host, port, registry, path, opaque, query, fragment] - parts = URI.split(URI.encode(path)) - # URI::Generic.build requires an integer for the port, but URI::split gives - # returns a string for the port. - parts[3] = parts[3].to_i if parts[3] - if user - userinfo = URI.encode(URI.encode(user), '@:') - if pass - userinfo << ":#{URI.encode(URI.encode(pass), '@:')}" - end - parts[1] = userinfo - end - - return URI::Generic.build(parts).to_s - rescue URI::Error => e - # URI::Error messages generally include the offending string. Including a message - # for which proxy config item has the issue should help deduce the issue when - # the URI::Error message is vague. - raise Chef::Exceptions::BadProxyURI, "Cannot configure #{scheme} proxy. Does not comply with URI scheme. #{e.message}" - end - end - # This is a hook for testing def env ENV diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 4c559542f1..6a371c89c4 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -124,7 +124,7 @@ class Chef::Application::Apply < Chef::Application parse_options Chef::Config.merge!(config) configure_logging - configure_proxy_environment_variables + Chef::Config.export_proxies parse_json end diff --git a/lib/chef/knife.rb b/lib/chef/knife.rb index 6fa29bea16..5df24faa11 100644 --- a/lib/chef/knife.rb +++ b/lib/chef/knife.rb @@ -401,6 +401,7 @@ class Chef merge_configs apply_computed_config + Chef::Config.export_proxies # This has to be after apply_computed_config so that Mixlib::Log is configured Chef::Log.info("Using configuration from #{config[:config_file]}") if config[:config_file] end diff --git a/lib/chef/knife/ssl_check.rb b/lib/chef/knife/ssl_check.rb index 7b0a808bbb..38b4d81bb3 100644 --- a/lib/chef/knife/ssl_check.rb +++ b/lib/chef/knife/ssl_check.rb @@ -127,9 +127,7 @@ class Chef def verify_cert ui.msg("Connecting to host #{host}:#{port}") - ui.msg("TYLER DEBUGGING INFO1") verify_peer_socket.connect - ui.msg("TYLER DEBUGGING INFO2") true rescue OpenSSL::SSL::SSLError => e ui.error "The SSL certificate of #{host} could not be verified" diff --git a/spec/functional/application_spec.rb b/spec/functional/application_spec.rb index 00ff0f702a..fe656dca60 100644 --- a/spec/functional/application_spec.rb +++ b/spec/functional/application_spec.rb @@ -42,7 +42,7 @@ describe Chef::Application do Chef::Config[:ftp_proxy] = nil Chef::Config[:no_proxy] = nil - @app.configure_proxy_environment_variables + Chef::Config.export_proxies end it "saves built proxy to ENV which shell_out can use" do diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb index f5a2c72aa0..20b7e3a506 100644 --- a/spec/unit/application_spec.rb +++ b/spec/unit/application_spec.rb @@ -39,7 +39,6 @@ describe Chef::Application do @app = Chef::Application.new allow(@app).to receive(:configure_chef).and_return(true) allow(@app).to receive(:configure_logging).and_return(true) - allow(@app).to receive(:configure_proxy_environment_variables).and_return(true) end it "should configure chef" do @@ -52,11 +51,6 @@ describe Chef::Application do @app.reconfigure end - it "should configure environment variables" do - expect(@app).to receive(:configure_proxy_environment_variables).and_return(true) - @app.reconfigure - end - it 'should not receive set_specific_recipes' do expect(@app).to_not receive(:set_specific_recipes) @app.reconfigure @@ -101,6 +95,7 @@ describe Chef::Application do @app = Chef::Application.new #Chef::Config.stub(:merge!).and_return(true) allow(@app).to receive(:parse_options).and_return(true) + expect(Chef::Config).to receive(:export_proxies).and_return(true) end it "should parse the commandline options" do @@ -245,181 +240,6 @@ describe Chef::Application do end end - describe "when configuring environment variables" do - def configure_proxy_environment_variables_stubs - allow(@app).to receive(:configure_http_proxy).and_return(true) - allow(@app).to receive(:configure_https_proxy).and_return(true) - allow(@app).to receive(:configure_ftp_proxy).and_return(true) - allow(@app).to receive(:configure_no_proxy).and_return(true) - end - - shared_examples_for "setting ENV['http_proxy']" do - before do - Chef::Config[:http_proxy] = http_proxy - end - - it "should set ENV['http_proxy']" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://#{address}:#{port}") - end - - it "should set ENV['HTTP_PROXY']" do - @app.configure_proxy_environment_variables - expect(@env['HTTP_PROXY']).to eq("#{scheme}://#{address}:#{port}") - end - - describe "when Chef::Config[:http_proxy_user] is set" do - before do - Chef::Config[:http_proxy_user] = "username" - end - - it "should set ENV['http_proxy'] with the username" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://username@#{address}:#{port}") - expect(@env['HTTP_PROXY']).to eq("#{scheme}://username@#{address}:#{port}") - end - - context "when :http_proxy_user contains '@' and/or ':'" do - before do - Chef::Config[:http_proxy_user] = "my:usern@me" - end - - it "should set ENV['http_proxy'] with the escaped username" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://my%3Ausern%40me@#{address}:#{port}") - expect(@env['HTTP_PROXY']).to eq("#{scheme}://my%3Ausern%40me@#{address}:#{port}") - end - end - - describe "when Chef::Config[:http_proxy_pass] is set" do - before do - Chef::Config[:http_proxy_pass] = "password" - end - - it "should set ENV['http_proxy'] with the password" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://username:password@#{address}:#{port}") - expect(@env['HTTP_PROXY']).to eq("#{scheme}://username:password@#{address}:#{port}") - end - - context "when :http_proxy_pass contains '@' and/or ':'" do - before do - Chef::Config[:http_proxy_pass] = ":P@ssword101" - end - - it "should set ENV['http_proxy'] with the escaped password" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://username:%3AP%40ssword101@#{address}:#{port}") - expect(@env['HTTP_PROXY']).to eq("#{scheme}://username:%3AP%40ssword101@#{address}:#{port}") - end - end - end - end - - describe "when Chef::Config[:http_proxy_pass] is set (but not Chef::Config[:http_proxy_user])" do - before do - Chef::Config[:http_proxy_user] = nil - Chef::Config[:http_proxy_pass] = "password" - end - - it "should set ENV['http_proxy']" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq("#{scheme}://#{address}:#{port}") - expect(@env['HTTP_PROXY']).to eq("#{scheme}://#{address}:#{port}") - end - end - end - - describe "when configuring ENV['http_proxy']" do - before do - @env = {} - allow(@app).to receive(:env).and_return(@env) - - allow(@app).to receive(:configure_https_proxy).and_return(true) - allow(@app).to receive(:configure_ftp_proxy).and_return(true) - allow(@app).to receive(:configure_no_proxy).and_return(true) - end - - describe "when Chef::Config[:http_proxy] is not set" do - before do - Chef::Config[:http_proxy] = nil - end - - it "should not set ENV['http_proxy']" do - @app.configure_proxy_environment_variables - expect(@env).to eq({}) - end - end - - describe "when Chef::Config[:http_proxy] is set" do - context "when given an FQDN" do - let(:scheme) { "http" } - let(:address) { "proxy.example.org" } - let(:port) { 8080 } - let(:http_proxy) { "#{scheme}://#{address}:#{port}" } - - it_should_behave_like "setting ENV['http_proxy']" - end - - context "when given an HTTPS URL" do - let(:scheme) { "https" } - let(:address) { "proxy.example.org" } - let(:port) { 8080 } - let(:http_proxy) { "#{scheme}://#{address}:#{port}" } - - it_should_behave_like "setting ENV['http_proxy']" - end - - context "when given an IP" do - let(:scheme) { "http" } - let(:address) { "127.0.0.1" } - let(:port) { 22 } - let(:http_proxy) { "#{scheme}://#{address}:#{port}" } - - it_should_behave_like "setting ENV['http_proxy']" - end - - context "when given an IPv6" do - let(:scheme) { "http" } - let(:address) { "[2001:db8::1]" } - let(:port) { 80 } - let(:http_proxy) { "#{scheme}://#{address}:#{port}" } - - it_should_behave_like "setting ENV['http_proxy']" - end - - context "when given without including http://" do - let(:scheme) { "http" } - let(:address) { "proxy.example.org" } - let(:port) { 8181 } - let(:http_proxy) { "#{address}:#{port}" } - - it_should_behave_like "setting ENV['http_proxy']" - end - - context "when given the full proxy in :http_proxy only" do - before do - Chef::Config[:http_proxy] = "http://username:password@proxy.example.org:2222" - Chef::Config[:http_proxy_user] = nil - Chef::Config[:http_proxy_pass] = nil - end - - it "should set ENV['http_proxy']" do - @app.configure_proxy_environment_variables - expect(@env['http_proxy']).to eq(Chef::Config[:http_proxy]) - end - end - - context "when the config options aren't URI compliant" do - it "raises Chef::Exceptions::BadProxyURI" do - Chef::Config[:http_proxy] = "http://proxy.bad_example.org/:8080" - expect { @app.configure_proxy_environment_variables }.to raise_error(Chef::Exceptions::BadProxyURI) - end - end - end - end - end - describe "class method: fatal!" do before do allow(STDERR).to receive(:puts).with("FATAL: blah").and_return(true) diff --git a/spec/unit/mixin/proxified_socket_spec.rb b/spec/unit/mixin/proxified_socket_spec.rb index d999d09235..88f71ae48b 100644 --- a/spec/unit/mixin/proxified_socket_spec.rb +++ b/spec/unit/mixin/proxified_socket_spec.rb @@ -61,6 +61,8 @@ describe Chef::Mixin::ProxifiedSocket do context "when https_proxy is set" do before do + # I'm purposefully setting both of these because we prefer the https + # variable ENV['https_proxy'] = https_uri ENV['http_proxy'] = http_uri end @@ -69,6 +71,8 @@ describe Chef::Mixin::ProxifiedSocket do include_examples "proxified socket" context "when no_proxy is set" do + # This is testing that no_proxy is also provided to Proxified + # when it is set before do ENV['no_proxy'] = no_proxy_spec end |