vagrant-proxyconf 1.5.2 → 2.0.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +15 -14
  4. data/CHANGELOG.md +19 -0
  5. data/Gemfile +25 -7
  6. data/LICENSE.txt +1 -1
  7. data/README.md +117 -18
  8. data/Rakefile +1 -27
  9. data/development/Dockerfile +40 -0
  10. data/development/README.md +2 -0
  11. data/development/Vagrantfile.example +156 -9
  12. data/development/install-c7.sh +46 -0
  13. data/development/install-debian.sh +55 -0
  14. data/development/tinyproxy.conf +333 -0
  15. data/lib/vagrant-proxyconf/action.rb +15 -7
  16. data/lib/vagrant-proxyconf/action/base.rb +47 -5
  17. data/lib/vagrant-proxyconf/action/configure_apt_proxy.rb +17 -0
  18. data/lib/vagrant-proxyconf/action/configure_chef_proxy.rb +32 -27
  19. data/lib/vagrant-proxyconf/action/configure_docker_proxy.rb +113 -12
  20. data/lib/vagrant-proxyconf/action/configure_env_proxy.rb +58 -11
  21. data/lib/vagrant-proxyconf/action/configure_git_proxy.rb +25 -9
  22. data/lib/vagrant-proxyconf/action/configure_npm_proxy.rb +14 -6
  23. data/lib/vagrant-proxyconf/action/configure_pear_proxy.rb +15 -8
  24. data/lib/vagrant-proxyconf/action/configure_svn_proxy.rb +15 -8
  25. data/lib/vagrant-proxyconf/action/configure_yum_proxy.rb +16 -0
  26. data/lib/vagrant-proxyconf/cap/linux/chef_proxy_conf.rb +17 -0
  27. data/lib/vagrant-proxyconf/cap/linux/docker_proxy_conf.rb +2 -1
  28. data/lib/vagrant-proxyconf/cap/linux/yum_proxy_conf.rb +19 -0
  29. data/lib/vagrant-proxyconf/cap/util.rb +4 -5
  30. data/lib/vagrant-proxyconf/capability.rb +10 -0
  31. data/lib/vagrant-proxyconf/config.rb +20 -0
  32. data/lib/vagrant-proxyconf/config/chef_proxy.rb +25 -0
  33. data/lib/vagrant-proxyconf/config/docker_proxy.rb +25 -0
  34. data/lib/vagrant-proxyconf/config/git_proxy.rb +3 -0
  35. data/lib/vagrant-proxyconf/config/npm_proxy.rb +25 -0
  36. data/lib/vagrant-proxyconf/config/pear_proxy.rb +19 -0
  37. data/lib/vagrant-proxyconf/version.rb +1 -1
  38. data/locales/en.yml +38 -0
  39. data/resources/yum_config.awk +1 -0
  40. data/spec/spec_helper.rb +27 -9
  41. data/spec/unit/fixtures/docker_client_config_json_enabled_proxy +9 -0
  42. data/spec/unit/fixtures/docker_client_config_json_no_proxy +5 -0
  43. data/spec/unit/fixtures/etc_environment_only_http_proxy.conf +9 -0
  44. data/spec/unit/fixtures/yum_with_repository_and_proxy_containing_special_chars.conf +10 -0
  45. data/spec/unit/vagrant-proxyconf/action/base_spec.rb +191 -0
  46. data/spec/unit/vagrant-proxyconf/action/configure_apt_proxy_spec.rb +162 -0
  47. data/spec/unit/vagrant-proxyconf/action/configure_chef_proxy_spec.rb +32 -0
  48. data/spec/unit/vagrant-proxyconf/action/configure_docker_proxy_spec.rb +489 -0
  49. data/spec/unit/vagrant-proxyconf/action/configure_env_proxy_spec.rb +105 -4
  50. data/spec/unit/vagrant-proxyconf/action/configure_git_proxy_spec.rb +116 -0
  51. data/spec/unit/vagrant-proxyconf/action/configure_npm_proxy_spec.rb +67 -0
  52. data/spec/unit/vagrant-proxyconf/action/configure_pear_proxy_spec.rb +116 -0
  53. data/spec/unit/vagrant-proxyconf/action/configure_svn_proxy_spec.rb +85 -0
  54. data/spec/unit/vagrant-proxyconf/action/configure_yum_proxy_spec.rb +100 -0
  55. data/spec/unit/vagrant-proxyconf/cap/linux/docker_proxy_conf_spec.rb +1 -1
  56. data/spec/unit/vagrant-proxyconf/cap/util_spec.rb +2 -2
  57. data/spec/unit/vagrant-proxyconf/config/key_mixin_spec.rb +1 -1
  58. data/spec/unit/vagrant-proxyconf/resources/yum_config_spec.rb +14 -0
  59. data/travis/before_install +26 -0
  60. metadata +24 -4
@@ -14,10 +14,15 @@ module VagrantPlugins
14
14
  def call(env)
15
15
  @machine = env[:machine]
16
16
 
17
- if disabled? || !config.enabled?
18
- logger.info I18n.t("vagrant_proxyconf.#{config_name}.not_enabled")
17
+ if skip?
18
+ logger.info I18n.t("vagrant_proxyconf.#{config_name}.skip")
19
+ env[:ui].info I18n.t("vagrant_proxyconf.#{config_name}.skip")
19
20
  elsif !supported?
20
21
  logger.info I18n.t("vagrant_proxyconf.#{config_name}.not_supported")
22
+ elsif disabled?
23
+ logger.info I18n.t("vagrant_proxyconf.#{config_name}.not_enabled")
24
+ env[:ui].info I18n.t("vagrant_proxyconf.#{config_name}.unconfiguring") if supported?
25
+ unconfigure_machine
21
26
  else
22
27
  env[:ui].info I18n.t("vagrant_proxyconf.#{config_name}.configuring")
23
28
  configure_machine
@@ -66,6 +71,10 @@ module VagrantPlugins
66
71
  write_config(config)
67
72
  end
68
73
 
74
+ # Unconfigures the VM, expected to be added to overriden
75
+ def unconfigure_machine
76
+ end
77
+
69
78
  # Writes the config to the VM
70
79
  #
71
80
  # @param opts [Hash] optional file options
@@ -109,16 +118,49 @@ module VagrantPlugins
109
118
  def disabled?
110
119
  enabled = @machine.config.proxy.enabled
111
120
  return true if enabled == false || enabled == ''
121
+ return false if enabled == true
122
+
123
+ app_name = config_name.gsub(/_proxy/, '').to_sym
124
+
125
+ if enabled.respond_to?(:key)
126
+ return false if enabled.has_key?(app_name) == false
127
+
128
+ # if boolean value, return original behavior as mentioned in Readme
129
+ return enabled[app_name] == false if [true, false].include?(enabled[app_name])
130
+
131
+ return false if enabled[app_name].has_key?(:skip) == false
132
+
133
+ # otherwise assume new behavior using :enabled as a new hash key
134
+ return enabled[app_name][:enabled] == false
135
+ end
136
+
137
+ false
138
+ end
139
+
140
+ def skip?
141
+ enabled = @machine.config.proxy.enabled
142
+ return true if enabled == false || enabled == ''
143
+ return false if enabled == true
112
144
 
113
145
  app_name = config_name.gsub(/_proxy/, '').to_sym
114
- return enabled[app_name] == false if enabled.respond_to?(:key)
146
+
147
+ if enabled.respond_to?(:key)
148
+ return false if enabled.has_key?(app_name) == false
149
+
150
+ # if boolean value, return original behavior as mentioned in Readme
151
+ return enabled[app_name] == false if [true, false].include?(enabled[app_name])
152
+
153
+ return false if enabled[app_name].has_key?(:skip) == false
154
+
155
+ # otherwise assume new behavior using :enabled as a new hash key
156
+ return enabled[app_name][:skip] == true
157
+ end
115
158
 
116
159
  false
117
160
  end
118
161
 
119
162
  def supported?
120
- @machine.guest.capability?(cap_name) &&
121
- @machine.guest.capability(cap_name)
163
+ @machine.guest.capability?(cap_name) && @machine.guest.capability(cap_name)
122
164
  end
123
165
 
124
166
  def config_path
@@ -8,6 +8,23 @@ module VagrantPlugins
8
8
  def config_name
9
9
  'apt_proxy'
10
10
  end
11
+
12
+ private
13
+
14
+ def unconfigure_machine
15
+ if !supported?
16
+ logger.info "apt_proxy is not supported on '#{@machine.guest.name}'"
17
+ return false
18
+ end
19
+
20
+ logger.info "apt_proxy is supported on '#{@machine.guest.name}'"
21
+
22
+ # if we get here then machine should support unconfiguring
23
+ @machine.communicate.sudo("rm -f #{config_path}")
24
+
25
+ true
26
+ end
27
+
11
28
  end
12
29
  end
13
30
  end
@@ -1,48 +1,34 @@
1
1
  require_relative '../logger'
2
2
  require_relative '../userinfo_uri'
3
+ require_relative 'base'
3
4
 
4
5
  module VagrantPlugins
5
6
  module ProxyConf
6
7
  class Action
7
8
  # Action for configuring Chef provisioners
8
- class ConfigureChefProxy
9
+ class ConfigureChefProxy < Base
9
10
 
10
11
  # Array of Chef provisioner types which include proxy configuration
11
12
  CHEF_PROVISIONER_TYPES = [:chef_client, :chef_solo, :chef_zero]
12
13
 
13
- def initialize(app, env)
14
- @app = app
14
+ def config_name
15
+ 'chef_proxy'
15
16
  end
16
17
 
17
- def call(env)
18
- @machine = env[:machine]
19
-
20
- if chef_provisioners.empty?
21
- logger.info I18n.t("vagrant_proxyconf.chef_proxy.no_provisioners")
22
- elsif !config.enabled?
23
- logger.info I18n.t("vagrant_proxyconf.chef_proxy.not_enabled")
24
- else
25
- env[:ui].info I18n.t("vagrant_proxyconf.chef_proxy.configuring")
26
- configure_chef_provisioners
27
- end
18
+ private
28
19
 
29
- @app.call env
20
+ def configure_machine
21
+ configure_chef_provisioners
30
22
  end
31
23
 
32
- private
24
+ def unconfigure_machine
25
+ configure_chef_provisioners
33
26
 
34
- # @return [Log4r::Logger]
35
- def logger
36
- ProxyConf.logger
27
+ true
37
28
  end
38
29
 
39
- # @return [Config::Proxy] the `config.proxy` configuration
40
- def config
41
- return @config if @config
42
-
43
- config = @machine.config.proxy
44
- config.finalize! if Gem::Version.new(Vagrant::VERSION) < Gem::Version.new('1.2.5')
45
- @config = config
30
+ def supported?
31
+ super && !chef_provisioners.empty?
46
32
  end
47
33
 
48
34
  # @return [Array] all Chef provisioners
@@ -67,6 +53,14 @@ module VagrantPlugins
67
53
  #
68
54
  # @param chef [VagrantPlugins::Chef::Config::Base] the Chef provisioner configuration
69
55
  def configure_chef(chef)
56
+ if disabled?
57
+ logger.info("chef_proxy is not enabled so we should unconfigure it")
58
+ unconfigure_chef_proxy(chef, 'http')
59
+ unconfigure_chef_proxy(chef, 'https')
60
+ return
61
+ end
62
+
63
+ logger.info("chef_proxy is enabled so we should configure it")
70
64
  configure_chef_proxy(chef, 'http', config.http)
71
65
  configure_chef_proxy(chef, 'https', config.https)
72
66
  chef.no_proxy ||= config.no_proxy if config.no_proxy
@@ -76,13 +70,24 @@ module VagrantPlugins
76
70
  # @param scheme [String] the http protocol (http or https)
77
71
  # @param uri [String] the URI with optional userinfo
78
72
  def configure_chef_proxy(chef, scheme, uri)
79
- if uri && !chef.public_send("#{scheme}_proxy")
73
+ if uri && !chef.public_send("#{scheme}_proxy") && !disabled?
80
74
  u = UserinfoURI.new(uri)
81
75
  chef.public_send("#{scheme}_proxy_user=", u.user)
82
76
  chef.public_send("#{scheme}_proxy_pass=", u.pass)
83
77
  chef.public_send("#{scheme}_proxy=", u.uri)
78
+ logger.info("chef_proxy has been successfully configured")
84
79
  end
85
80
  end
81
+
82
+ # @param chef [VagrantPlugins::Chef::Config::Base] the Chef provisioner configuration
83
+ # @param scheme [String] the http protocol (http or https)
84
+ def unconfigure_chef_proxy(chef, scheme)
85
+ chef.public_send("#{scheme}_proxy_user=", nil)
86
+ chef.public_send("#{scheme}_proxy_pass=", nil)
87
+ chef.public_send("#{scheme}_proxy=", nil)
88
+ chef.no_proxy = nil
89
+ logger.info("chef_proxy has been successfully unconfigured")
90
+ end
86
91
  end
87
92
  end
88
93
  end
@@ -13,15 +13,86 @@ module VagrantPlugins
13
13
 
14
14
  private
15
15
 
16
- def config
17
- # Use global proxy config
18
- @config ||= finalize_config(@machine.config.proxy)
19
- end
20
-
21
16
  def configure_machine
17
+ return if !supported?
18
+
22
19
  logger.info('Writing the proxy configuration to docker config')
23
20
  detect_export
24
21
  write_docker_config
22
+ update_docker_client_config
23
+
24
+ true
25
+ end
26
+
27
+ def unconfigure_machine
28
+ return if !supported?
29
+
30
+ config.http = nil
31
+ config.https = nil
32
+ config.no_proxy = nil
33
+
34
+ write_docker_config
35
+ update_docker_client_config
36
+
37
+ true
38
+ end
39
+
40
+ def docker_client_config_path
41
+ return @docker_client_config_path if @docker_client_config_path
42
+ return if !supports_config_json?
43
+
44
+ @docker_client_config_path = "/tmp/vagrant-proxyconf-docker-config.json"
45
+
46
+ @machine.communicate.tap do |comm|
47
+ if comm.test("[ -f /etc/docker/config.json ]")
48
+ comm.download("/etc/docker/config.json", @docker_client_config_path)
49
+ else
50
+ File.write(@docker_client_config_path, Hash.new)
51
+ end
52
+ end
53
+
54
+ @docker_client_config_path
55
+ end
56
+
57
+ def update_docker_client_config
58
+ return if !supports_config_json? || !docker_client_config_path
59
+
60
+ content = File.read(@docker_client_config_path)
61
+ data = JSON.load(content)
62
+
63
+ if disabled?
64
+ data['proxies'] = {
65
+ 'default' => {}
66
+ }
67
+ else
68
+ data['proxies'] = {
69
+ 'default' => {
70
+ 'httpProxy' => config.http,
71
+ 'httpsProxy' => config.https,
72
+ 'noProxy' => config.no_proxy,
73
+ }
74
+ }
75
+ end
76
+
77
+ config_json = JSON.pretty_generate(data)
78
+
79
+ File.write(@docker_client_config_path, config_json)
80
+
81
+ @machine.communicate.tap do |comm|
82
+ comm.upload(@docker_client_config_path, @docker_client_config_path)
83
+ comm.sudo("mv #{@docker_client_config_path} /etc/docker/config.json")
84
+ comm.sudo("chown root:root /etc/docker/config.json")
85
+ comm.sudo("rm -f #{@docker_client_config_path}")
86
+
87
+ comm.sudo("sed -i.bak -e '/^DOCKER_CONFIG/d' /etc/environment")
88
+ if !disabled?
89
+ comm.sudo("echo DOCKER_CONFIG=/etc/docker >> /etc/environment")
90
+ end
91
+ end
92
+
93
+ File.unlink(@docker_client_config_path) if File.exists?(@docker_client_config_path)
94
+
95
+ config_json
25
96
  end
26
97
 
27
98
  def docker
@@ -32,13 +103,39 @@ module VagrantPlugins
32
103
  end
33
104
  end
34
105
 
106
+ def docker_version
107
+ return if !supported?
108
+ return @version if @version
109
+
110
+ @version = nil
111
+ @machine.communicate.execute('docker --version') do |type, data|
112
+ version = data.sub(',', '').split(' ').select {|i| i.match /^\d+\.\d+/}
113
+ @version = version[0].split(".").map {|i| i.to_i} unless version.empty?
114
+ end
115
+
116
+ return @version
117
+ end
118
+
119
+ def supports_config_json?
120
+ return false if !supported? || !docker_version
121
+
122
+ major, minor, patch = @version
123
+
124
+ # https://docs.docker.com/network/proxy/#configure-the-docker-client
125
+ # if docker version >= 17.07 it supports config.json
126
+ return true if major >= 17 && minor >= 7
127
+
128
+ # docker version < 17.07 so it does not support config.json
129
+ return false
130
+ end
131
+
35
132
  def write_docker_config
36
133
  tmp = "/tmp/vagrant-proxyconf"
37
134
  path = config_path
38
135
 
39
136
  @machine.communicate.tap do |comm|
40
137
  sed_script = docker_sed_script
41
- local_tmp = tempfile(docker_config)
138
+ local_tmp = !disabled? ? tempfile(docker_config) : tempfile("")
42
139
 
43
140
  comm.sudo("rm -f #{tmp}", error_check: false)
44
141
  comm.upload(local_tmp.path, tmp)
@@ -62,7 +159,7 @@ module VagrantPlugins
62
159
 
63
160
  def detect_export
64
161
  @machine.communicate.tap do |comm|
65
- comm.test('which systemctl') ? @export = '' : @export = 'export '
162
+ comm.test('command -v systemctl') ? @export = '' : @export = 'export '
66
163
  end
67
164
  end
68
165
 
@@ -75,18 +172,22 @@ module VagrantPlugins
75
172
  def docker_sed_script
76
173
  <<-SED.gsub(/^\s+/, '')
77
174
  /^#{@export}HTTP_PROXY=/ d
78
- /^#{@export}NO_PROXY=/ d
79
175
  /^#{@export}http_proxy=/ d
176
+ /^#{@export}HTTPS_PROXY=/ d
177
+ /^#{@export}https_proxy=/ d
178
+ /^#{@export}NO_PROXY=/ d
80
179
  /^#{@export}no_proxy=/ d
81
180
  SED
82
181
  end
83
182
 
84
183
  def docker_config
85
184
  <<-CONFIG.gsub(/^\s+/, '')
86
- #{@export}HTTP_PROXY=#{config.http || ''}
87
- #{@export}NO_PROXY=#{config.no_proxy || ''}
88
- #{@export}http_proxy=#{config.http || ''}
89
- #{@export}no_proxy=#{config.no_proxy || ''}
185
+ #{@export}HTTP_PROXY=\"#{config.http || ''}\"
186
+ #{@export}http_proxy=\"#{config.http || ''}\"
187
+ #{@export}HTTPS_PROXY=\"#{config.https || ''}\"
188
+ #{@export}https_proxy=\"#{config.https || ''}\"
189
+ #{@export}NO_PROXY=\"#{config.no_proxy || ''}\"
190
+ #{@export}no_proxy=\"#{config.no_proxy || ''}\"
90
191
  CONFIG
91
192
  end
92
193
  end
@@ -23,11 +23,30 @@ module VagrantPlugins
23
23
  end
24
24
  end
25
25
 
26
+ def unconfigure_machine
27
+ if windows_guest?
28
+ raise NotImplementedError, 'Sorry but I do not know how to disable a windows proxy yet, please open a feature request'
29
+ end
30
+
31
+ logger.info('Unconfiguring and or removing proxy configuration files')
32
+ unconfigure_linux
33
+ end
34
+
35
+ def unconfigure_linux
36
+ @machine.communicate.tap do |comm|
37
+ comm.sudo("rm -f /etc/sudoers.d/proxy")
38
+ comm.sudo("rm -f #{config_path}")
39
+ end
40
+
41
+ write_environment_config
42
+ end
43
+
26
44
  def configure_machine_windows
27
45
  set_windows_proxy('http_proxy', config.http)
28
46
  set_windows_proxy('https_proxy', config.https)
29
47
  set_windows_proxy('ftp_proxy', config.ftp)
30
48
  set_windows_proxy('no_proxy', config.no_proxy)
49
+ set_windows_system_proxy(config.http)
31
50
  end
32
51
 
33
52
  def set_windows_proxy(key, value)
@@ -40,6 +59,26 @@ module VagrantPlugins
40
59
  end
41
60
  end
42
61
 
62
+ def set_windows_system_proxy(proxy)
63
+ if proxy
64
+ path = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
65
+
66
+ proxy1 = "cmd.exe /C reg add \"#{path}\" /v ProxyEnable /t REG_DWORD /d 1 /f"
67
+ proxy2 = "cmd.exe /C reg add \"#{path}\" /v ProxyServer /t REG_SZ /d #{config.http.inspect} /f"
68
+ proxy3 = "cmd.exe /C reg add \"#{path}\" /v ProxyOverride /t REG_SZ /d #{config.no_proxy.inspect} /f"
69
+ proxy4 = "cmd.exe /C reg add \"#{path}\" /v AutoDetect /t REG_DWORD /d 0 /f"
70
+
71
+ logger.info('Setting system proxy settings')
72
+
73
+ @machine.communicate.sudo(proxy1)
74
+ @machine.communicate.sudo(proxy2)
75
+ @machine.communicate.sudo(proxy3)
76
+ @machine.communicate.sudo(proxy4)
77
+ else
78
+ logger.info("Not setting system proxy settings")
79
+ end
80
+ end
81
+
43
82
  def windows_guest?
44
83
  @machine.config.vm.guest.eql?(:windows)
45
84
  end
@@ -62,13 +101,15 @@ module VagrantPlugins
62
101
  comm.sudo("rm -f #{tmp}", error_check: false)
63
102
  comm.upload(local_tmp.path, tmp)
64
103
  comm.sudo("touch #{path}")
65
- comm.sudo("sed -e '#{sed_script}' #{path} > #{path}.new")
104
+ comm.sudo("sed -e '#{sed_script}' -e '/^$/d' #{path} > #{path}.new")
66
105
  comm.sudo("cat #{tmp} >> #{path}.new")
67
106
  comm.sudo("chmod 0644 #{path}.new")
68
107
  comm.sudo("chown root:root #{path}.new")
69
108
  comm.sudo("mv -f #{path}.new #{path}")
70
109
  comm.sudo("rm -f #{tmp}")
71
110
  end
111
+
112
+ true
72
113
  end
73
114
 
74
115
  def environment_sed_script
@@ -85,16 +126,22 @@ module VagrantPlugins
85
126
  end
86
127
 
87
128
  def environment_config
88
- <<-CONFIG.gsub(/^\s+/, '')
89
- HTTP_PROXY=#{config.http || ''}
90
- HTTPS_PROXY=#{config.https || ''}
91
- FTP_PROXY=#{config.ftp || ''}
92
- NO_PROXY=#{config.no_proxy || ''}
93
- http_proxy=#{config.http || ''}
94
- https_proxy=#{config.https || ''}
95
- ftp_proxy=#{config.ftp || ''}
96
- no_proxy=#{config.no_proxy || ''}
97
- CONFIG
129
+ return "" if disabled?
130
+
131
+ env_config = Hash.new
132
+ env_config["FTP_PROXY"] = config.ftp if config.ftp
133
+ env_config["HTTP_PROXY"] = config.http if config.http
134
+ env_config["HTTPS_PROXY"] = config.https if config.https
135
+ env_config["NO_PROXY"] = config.no_proxy if config.no_proxy
136
+
137
+ config_items = env_config.map do |k,v|
138
+ <<-CONFIG.gsub(/^\s+/, '')
139
+ #{k.upcase}="#{v}"
140
+ #{k.downcase}="#{v}"
141
+ CONFIG
142
+ end
143
+
144
+ config_items.join("\n")
98
145
  end
99
146
  end
100
147
  end