vagrant-proxyconf 0.3.0 → 0.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # 0.4.0.rc1 / 2013-08-30
2
+
3
+ - BREAKING: Environment variables for Apt config renamed to `VAGRANT_APT_HTTP_PROXY` etc. ([GH-15][])
4
+ - Configure all supported programs with a single `config.proxy` configuration or `VAGRANT_HTTP_PROXY` etc. environment variables ([GH-14][], [GH-17][])
5
+ - Add support for global `*_proxy` environment variables via `config.env_proxy` ([GH-6][])
6
+ - Configure the VM also on `vagrant provision` ([GH-12][])
7
+ * Hook to all commands that trigger provisioning action
8
+ - Ensure the proxies are configured before [vagrant-omnibus](https://github.com/schisamo/vagrant-omnibus) ([GH-13][])
9
+
1
10
  # 0.3.0 / 2013-07-12
2
11
 
3
12
  - Support the [AWS provider](https://github.com/mitchellh/vagrant-aws) ([GH-10][])
@@ -24,8 +33,14 @@
24
33
 
25
34
  [GH-2]: https://github.com/tmatilai/vagrant-proxyconf/issues/2 "Issue 2"
26
35
  [GH-5]: https://github.com/tmatilai/vagrant-proxyconf/issues/5 "Issue 5"
36
+ [GH-6]: https://github.com/tmatilai/vagrant-proxyconf/issues/6 "Issue 6"
27
37
  [GH-7]: https://github.com/tmatilai/vagrant-proxyconf/issues/7 "Issue 7"
28
38
  [GH-8]: https://github.com/tmatilai/vagrant-proxyconf/issues/8 "Issue 8"
29
39
  [GH-9]: https://github.com/tmatilai/vagrant-proxyconf/issues/9 "Issue 9"
30
40
  [GH-10]: https://github.com/tmatilai/vagrant-proxyconf/issues/10 "Issue 10"
31
41
  [GH-11]: https://github.com/tmatilai/vagrant-proxyconf/issues/11 "Issue 11"
42
+ [GH-12]: https://github.com/tmatilai/vagrant-proxyconf/issues/12 "Issue 12"
43
+ [GH-13]: https://github.com/tmatilai/vagrant-proxyconf/issues/13 "Issue 13"
44
+ [GH-14]: https://github.com/tmatilai/vagrant-proxyconf/issues/14 "Issue 14"
45
+ [GH-15]: https://github.com/tmatilai/vagrant-proxyconf/issues/15 "Issue 15"
46
+ [GH-17]: https://github.com/tmatilai/vagrant-proxyconf/issues/17 "Issue 17"
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem 'rake'
7
7
  gem 'rspec', '~> 2.11'
8
8
  gem 'simplecov', '~> 0.7', :require => false
9
9
  gem 'tailor', '~> 1.2'
10
- gem 'vagrant', github: 'mitchellh/vagrant', ref: 'v1.2.2'
10
+ gem 'vagrant', github: 'mitchellh/vagrant', ref: 'v1.2.7'
11
11
 
12
12
  group :development do
13
13
  gem 'guard-rspec'
data/README.md CHANGED
@@ -12,11 +12,12 @@
12
12
  [gemnasium]: https://gemnasium.com/tmatilai/vagrant-proxyconf
13
13
  [codeclimate]: https://codeclimate.com/github/tmatilai/vagrant-proxyconf
14
14
 
15
- A [Vagrant](http://www.vagrantup.com/) plugin that configures the virtual machine to use specified proxies for package managers etc.
15
+ A [Vagrant](http://www.vagrantup.com/) plugin that configures the virtual machine to use specified proxies.
16
16
 
17
17
  At this state we support:
18
18
 
19
- * [APT](http://en.wikipedia.org/wiki/Advanced_Packaging_Tool) proxy/cacher
19
+ * Generic `*_proxy` environment variables that many programs support
20
+ * APT proxy/cacher
20
21
 
21
22
  Support is planned for other package managers (at least yum).
22
23
 
@@ -41,12 +42,99 @@ vagrant plugin install vagrant-proxyconf
41
42
 
42
43
  ## Usage
43
44
 
44
- The plugin hooks itself to `vagrant up`, `vagrant reload` and `vagrant rebuild` commands.
45
+ The plugin hooks itself to all Vagrant commands triggering provisioning (e.g. `vagrant up`, `vagrant provision`, etc.). The proxy configurations are written just before provisioners are run.
45
46
 
46
- Proxy settings can be configured in Vagrantfile. In the common case that you want to use the same configuration in all Vagrant machines, you can use _$HOME/.vagrant.d/Vagrantfile_ or environment variables. Package manager specific settings are only used on supporting platforms (i.e. Apt configuration on Debian based systems), so there is no harm using global configuration.
47
+ Proxy settings can be configured in Vagrantfile. In the common case that you want to use the same configuration in all Vagrant machines, you can use _$HOME/.vagrant.d/Vagrantfile_ or environment variables. Platform specific settings are only used on virtual machines that support them (i.e. Apt configuration on Debian based systems), so there is no harm using global configuration.
47
48
 
48
49
  Project specific Vagrantfile overrides global settings. Environment variables override both.
49
50
 
51
+ ### Default/global configuration
52
+
53
+ It's a common case that you want all possible connections to pass through the same proxy. This will set the default values for all other proxy configuration keys.
54
+
55
+ #### Example Vagrantfile
56
+
57
+ ```ruby
58
+ Vagrant.configure("2") do |config|
59
+ config.proxy.http = "http://192.168.0.2:3128/"
60
+ config.proxy.https = "http://192.168.0.2:3128/"
61
+ config.proxy.no_proxy = "localhost,127.0.0.1,.example.com"
62
+ # ... other stuff
63
+ end
64
+ ```
65
+
66
+ #### Configuration keys
67
+
68
+ * `config.proxy.http` - The proxy for HTTP URIs
69
+ * `config.proxy.https` - The proxy for HTTPS URIs
70
+ * `config.proxy.ftp` - The proxy for FTS URIs
71
+ * `config.proxy.no_proxy` - A comma separated list of hosts or domains which do not use proxies.
72
+
73
+ #### Possible values
74
+
75
+ * If all keys are unset or `nil`, no configuration is written.
76
+ * A proxy should be specified in the form of _protocol://[user:pass@]host[:port]_.
77
+ * Empty string (`""`) or `false` in any setting also force the configuration files to be written, but without configuration for that key. Can be used to clear the old configuration and/or override a global setting.
78
+
79
+ #### Environment variables
80
+
81
+ * `VAGRANT_HTTP_PROXY`
82
+ * `VAGRANT_HTTPS_PROXY`
83
+ * `VAGRANT_FTP_PROXY`
84
+ * `VAGRANT_NO_PROXY`
85
+
86
+ These also override the Vagrantfile configuration. To disable or remove the proxy use an empty value.
87
+
88
+ For example to spin up a VM, run:
89
+
90
+ ```sh
91
+ VAGRANT_HTTP_PROXY="http://proxy.example.com:8080" vagrant up
92
+ ```
93
+
94
+ ### Global `*_proxy` environment variables
95
+
96
+ Many programs (wget, curl, yum, etc.) can be configured to use proxies with `<protocol>_proxy` or `<PROTOCOL>_PROXY` environment variables. This configuration will be written to _/etc/profile.d/proxy.sh_ on the guest.
97
+
98
+ #### Example Vagrantfile
99
+
100
+ ```ruby
101
+ Vagrant.configure("2") do |config|
102
+ config.env_proxy.http = "http://192.168.33.200:8888/"
103
+ config.env_proxy.https = "$http_proxy"
104
+ config.env_proxy.no_proxy = "localhost,127.0.0.1,.example.com"
105
+ # ... other stuff
106
+ end
107
+ ```
108
+
109
+ #### Configuration keys
110
+
111
+ * `config.env_proxy.http` - The proxy for HTTP URIs
112
+ * `config.env_proxy.https` - The proxy for HTTPS URIs
113
+ * `config.env_proxy.ftp` - The proxy for FTS URIs
114
+ * `config.env_proxy.no_proxy` - A comma separated list of hosts or domains which do not use proxies.
115
+
116
+ #### Possible values
117
+
118
+ * If all keys are unset or `nil`, no configuration is written.
119
+ * A proxy can be specified in the form of _protocol://[user:pass@]host[:port]_.
120
+ * The values are used as specified, so you can use for example variables that will be evaluated by the shell on the VM.
121
+ * Empty string (`""`) or `false` in any setting also force the configuration file to be written, but without configuration for that key. Can be used to clear the old configuration and/or override a global setting.
122
+
123
+ #### Environment variables
124
+
125
+ * `VAGRANT_ENV_HTTP_PROXY`
126
+ * `VAGRANT_ENV_HTTPS_PROXY`
127
+ * `VAGRANT_ENV_FTP_PROXY`
128
+ * `VAGRANT_ENV_NO_PROXY`
129
+
130
+ These also override the Vagrantfile configuration. To disable or remove the proxy use an empty value.
131
+
132
+ For example to spin up a VM, run:
133
+
134
+ ```sh
135
+ VAGRANT_ENV_HTTP_PROXY="http://proxy.example.com:8080" vagrant up
136
+ ```
137
+
50
138
  ### Apt
51
139
 
52
140
  Configures Apt to use the specified proxy settings. The configuration will be written to _/etc/apt/apt.conf.d/01proxy_ on the guest.
@@ -77,16 +165,16 @@ end
77
165
 
78
166
  #### Environment variables
79
167
 
80
- * `APT_PROXY_HTTP`
81
- * `APT_PROXY_HTTPS`
82
- * `APT_PROXY_FTP`
168
+ * `VAGRANT_APT_HTTP_PROXY`
169
+ * `VAGRANT_APT_HTTPS_PROXY`
170
+ * `VAGRANT_APT_FTP_PROXY`
83
171
 
84
172
  These also override the Vagrantfile configuration. To disable or remove the proxy use "DIRECT" or an empty value.
85
173
 
86
174
  For example to spin up a VM, run:
87
175
 
88
176
  ```sh
89
- APT_PROXY_HTTP="proxy.example.com:8080" vagrant up
177
+ VAGRANT_APT_HTTP_PROXY="proxy.example.com:8080" vagrant up
90
178
  ```
91
179
 
92
180
  #### Running apt-cacher-ng on a Vagrant box
data/Rakefile CHANGED
@@ -30,7 +30,7 @@ Tailor::RakeTask.new do |task|
30
30
  end
31
31
 
32
32
  Cane::RakeTask.new(:cane) do |task|
33
- task.style_measure = 100
33
+ task.style_measure = 140
34
34
  task.options[:color] = true
35
35
  end
36
36
 
@@ -11,7 +11,7 @@
11
11
  3. Test, hack, edit _Vagrantfile_ and test again:
12
12
 
13
13
  VAGRANT_LOG=debug bundle exec vagrant reload
14
- APT_PROXY_HTTP="foo:8080" bundle exec vagrant reload
14
+ VAGRANT_APT_HTTP_PROXY="foo:8080" bundle exec vagrant provision
15
15
  # ...
16
16
 
17
17
  4. Goto 3.
@@ -0,0 +1,90 @@
1
+ require 'log4r'
2
+ require 'tempfile'
3
+ require 'vagrant'
4
+
5
+ module VagrantPlugins
6
+ module ProxyConf
7
+ class Action
8
+ # Base class for proxy configuration Actions
9
+ class Base
10
+ attr_reader :logger
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @logger = Log4r::Logger.new('vagrant::proxyconf')
15
+ end
16
+
17
+ def call(env)
18
+ @app.call env
19
+
20
+ machine = env[:machine]
21
+ config = config(machine)
22
+
23
+ if !config.enabled?
24
+ logger.debug I18n.t("vagrant_proxyconf.#{config_name}.not_enabled")
25
+ elsif !supported?(machine)
26
+ env[:ui].info I18n.t("vagrant_proxyconf.#{config_name}.not_supported")
27
+ else
28
+ env[:ui].info I18n.t("vagrant_proxyconf.#{config_name}.configuring")
29
+ write_config(machine, config)
30
+ end
31
+ end
32
+
33
+ # @return [String] the name of the configuration section
34
+ def config_name
35
+ raise NotImplementedError, "Must be implemented by the inheriting class"
36
+ end
37
+
38
+ private
39
+
40
+ # @return [Vagrant::Plugin::V2::Config] the configuration
41
+ def config(machine)
42
+ config = machine.config.send(config_name.to_sym)
43
+ finalize_config(config)
44
+ config.merge_defaults(default_config(machine))
45
+ end
46
+
47
+ # @return [Vagrant::Plugin::V2::Config] the default configuration
48
+ def default_config(machine)
49
+ config = machine.config.proxy
50
+ finalize_config(config)
51
+ end
52
+
53
+ def finalize_config(config)
54
+ # Vagrant pre 1.2.5 does not call `finalize!` if the configuration
55
+ # key is not used in Vagrantfiles.
56
+ # https://github.com/tmatilai/vagrant-proxyconf/issues/2
57
+ config.finalize! if Gem::Version.new(Vagrant::VERSION) < Gem::Version.new('1.2.5')
58
+ config
59
+ end
60
+
61
+ def write_config(machine, config)
62
+ logger.debug "Configuration:\n#{config}"
63
+
64
+ temp = Tempfile.new("vagrant")
65
+ temp.binmode
66
+ temp.write(config)
67
+ temp.close
68
+
69
+ machine.communicate.tap do |comm|
70
+ comm.upload(temp.path, "/tmp/vagrant-proxyconf")
71
+ comm.sudo("cat /tmp/vagrant-proxyconf > #{config_path(machine)}")
72
+ comm.sudo("rm /tmp/vagrant-proxyconf")
73
+ end
74
+ end
75
+
76
+ def cap_name
77
+ "#{config_name}_conf".to_sym
78
+ end
79
+
80
+ def supported?(machine)
81
+ machine.guest.capability?(cap_name)
82
+ end
83
+
84
+ def config_path(machine)
85
+ machine.guest.capability(cap_name)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -1,61 +1,12 @@
1
- require 'log4r'
2
- require 'tempfile'
1
+ require_relative 'base'
3
2
 
4
3
  module VagrantPlugins
5
4
  module ProxyConf
6
5
  class Action
7
6
  # Action for configuring Apt on the guest
8
- class ConfigureAptProxy
9
- attr_reader :logger
10
-
11
- def initialize(app, env)
12
- @app = app
13
- @logger = Log4r::Logger.new('vagrant::proxyconf::action::configure_apt_proxy')
14
- end
15
-
16
- def call(env)
17
- @app.call env
18
-
19
- proxy_config = env[:machine].config.apt_proxy
20
-
21
- # Vagrant does not seem to call `finalize!` if the configuration
22
- # key is not used in Vagrantfiles.
23
- # https://github.com/tmatilai/vagrant-proxyconf/issues/2
24
- proxy_config.finalize!
25
-
26
- if !proxy_config.enabled?
27
- logger.debug "apt_proxy not enabled or configured"
28
- elsif !proxy_conf_capability?(env[:machine])
29
- env[:ui].info "Skipping Apt proxy config as the machine does not support it"
30
- else
31
- env[:ui].info "Configuring proxy for Apt..."
32
- write_apt_proxy_conf(env[:machine], proxy_config)
33
- end
34
- end
35
-
36
- private
37
-
38
- def write_apt_proxy_conf(machine, config)
39
- logger.debug "Configuration:\n#{config}"
40
-
41
- temp = Tempfile.new("vagrant")
42
- temp.binmode
43
- temp.write(config)
44
- temp.close
45
-
46
- machine.communicate.tap do |comm|
47
- comm.upload(temp.path, "/tmp/vagrant-apt-proxy-conf")
48
- comm.sudo("cat /tmp/vagrant-apt-proxy-conf > #{proxy_conf_path(machine)}")
49
- comm.sudo("rm /tmp/vagrant-apt-proxy-conf")
50
- end
51
- end
52
-
53
- def proxy_conf_capability?(machine)
54
- machine.guest.capability?(:apt_proxy_conf)
55
- end
56
-
57
- def proxy_conf_path(machine)
58
- machine.guest.capability(:apt_proxy_conf)
7
+ class ConfigureAptProxy < Base
8
+ def config_name
9
+ 'apt_proxy'
59
10
  end
60
11
  end
61
12
  end
@@ -0,0 +1,14 @@
1
+ require_relative 'base'
2
+
3
+ module VagrantPlugins
4
+ module ProxyConf
5
+ class Action
6
+ # Action for configuring proxy environment variables on the guest
7
+ class ConfigureEnvProxy < Base
8
+ def config_name
9
+ 'env_proxy'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module VagrantPlugins
2
+ module ProxyConf
3
+ module Cap
4
+ module Linux
5
+ # Capability for Env proxy configuration
6
+ module EnvProxyConf
7
+ # @return [String] the path to the configuration file
8
+ def self.env_proxy_conf(machine)
9
+ '/etc/profile.d/proxy.sh'
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,4 +1,5 @@
1
1
  require 'vagrant'
2
+ require_relative 'key_mixin'
2
3
 
3
4
  module VagrantPlugins
4
5
  module ProxyConf
@@ -7,55 +8,32 @@ module VagrantPlugins
7
8
  #
8
9
  # @!parse class AptProxy < Vagrant::Plugin::V2::Config; end
9
10
  class AptProxy < Vagrant.plugin('2', :config)
11
+ include KeyMixin
12
+ # @!parse extend KeyMixin::ClassMethods
13
+
14
+ # @!attribute
10
15
  # @return [String] the HTTP proxy
11
- attr_accessor :http
16
+ key :http, env_var: 'VAGRANT_APT_HTTP_PROXY'
12
17
 
18
+ # @!attribute
13
19
  # @return [String] the HTTPS proxy
14
- attr_accessor :https
20
+ key :https, env_var: 'VAGRANT_APT_HTTPS_PROXY'
15
21
 
22
+ # @!attribute
16
23
  # @return [String] the FTP proxy
17
- attr_accessor :ftp
18
-
19
- def initialize
20
- @http = UNSET_VALUE
21
- @https = UNSET_VALUE
22
- @ftp = UNSET_VALUE
23
- end
24
-
25
- def finalize!
26
- @http = override_from_env_var('http', @http)
27
- @http = nil if @http == UNSET_VALUE
28
-
29
- @https = override_from_env_var('https', @https)
30
- @https = nil if @https == UNSET_VALUE
31
-
32
- @ftp = override_from_env_var('ftp', @ftp)
33
- @ftp = nil if @ftp == UNSET_VALUE
34
- end
35
-
36
- def enabled?
37
- !http.nil? || !https.nil? || !ftp.nil?
38
- end
39
-
40
- # @return [String] the full configuration stanza
41
- def to_s
42
- %w[http https ftp].map { |proto| config_for(proto) }.join
43
- end
24
+ key :ftp, env_var: 'VAGRANT_APT_FTP_PROXY'
44
25
 
45
26
  private
46
27
 
47
- def override_from_env_var(proto, default)
48
- ENV.fetch("APT_PROXY_#{proto.upcase}", default)
49
- end
50
-
51
- def config_for(proto)
52
- ConfigValue.new(proto, send(proto.to_sym))
28
+ # (see KeyMixin#config_for)
29
+ def config_for(key, value)
30
+ ConfigLine.new(key.name, value)
53
31
  end
54
32
 
55
- # Helper for building configuration lines
33
+ # Helper for constructing a configuration line for apt.conf
56
34
  #
57
35
  # @api private
58
- class ConfigValue
36
+ class ConfigLine
59
37
 
60
38
  attr_reader :proto, :value
61
39
 
@@ -68,7 +46,7 @@ module VagrantPlugins
68
46
 
69
47
  # @return [String] the full Apt configuration line
70
48
  def to_s
71
- set? ? %Q{Acquire::#{proto}::Proxy "#{proxy_uri}";\n} : ""
49
+ %Q{Acquire::#{proto}::Proxy "#{direct || proxy_uri}";\n} if set?
72
50
  end
73
51
 
74
52
  private
@@ -77,12 +55,12 @@ module VagrantPlugins
77
55
  value && !value.empty?
78
56
  end
79
57
 
80
- def direct?
81
- value.upcase == "DIRECT"
58
+ def direct
59
+ "DIRECT" if value.upcase == "DIRECT"
82
60
  end
83
61
 
84
62
  def proxy_uri
85
- direct? ? "DIRECT" : "#{prefix}#{value}#{suffix}"
63
+ "#{prefix}#{value}#{suffix}"
86
64
  end
87
65
 
88
66
  def prefix
@@ -0,0 +1,46 @@
1
+ require 'vagrant'
2
+ require_relative 'key_mixin'
3
+
4
+ module VagrantPlugins
5
+ module ProxyConf
6
+ module Config
7
+ # Configuration for generic `<protocol>_proxy` environment variables
8
+ #
9
+ # @!parse class EnvProxy < Vagrant::Plugin::V2::Config; end
10
+ class EnvProxy < Vagrant.plugin('2', :config)
11
+ include KeyMixin
12
+ # @!parse extend KeyMixin::ClassMethods
13
+
14
+ # @!attribute
15
+ # @return [String] the HTTP proxy
16
+ key :http, env_var: 'VAGRANT_ENV_HTTP_PROXY'
17
+
18
+ # @!attribute
19
+ # @return [String] the HTTPS proxy
20
+ key :https, env_var: 'VAGRANT_ENV_HTTPS_PROXY'
21
+
22
+ # @!attribute
23
+ # @return [String] the FTP proxy
24
+ key :ftp, env_var: 'VAGRANT_ENV_FTP_PROXY'
25
+
26
+ # @!attribute
27
+ # @return [String] a comma separated list of hosts or domains which do not use proxies
28
+ key :no_proxy, env_var: 'VAGRANT_ENV_NO_PROXY'
29
+
30
+ private
31
+
32
+ # (see KeyMixin#config_for)
33
+ def config_for(key, value)
34
+ if value && !value.empty?
35
+ var = env_variable_name(key)
36
+ [var.upcase, var.downcase].map { |v| "export #{v}=#{value}\n" }.join
37
+ end
38
+ end
39
+
40
+ def env_variable_name(key)
41
+ key.name == :no_proxy ? "no_proxy" : "#{key.name}_proxy"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ module VagrantPlugins
2
+ module ProxyConf
3
+ module Config
4
+ # Configuration key specifications
5
+ class Key
6
+ # @return [Symbol] the configuration key name
7
+ attr_reader :name
8
+
9
+ # @return [String, nil] the default value for the key
10
+ attr_reader :default
11
+
12
+ # @return [String, nil] the environment variable name
13
+ attr_reader :env_var
14
+
15
+ # @param name [Symbol, String] the key name
16
+ # @param opts [Hash] optional key properties
17
+ # @option opts [String, nil] :default (nil) the default value
18
+ # @option opts [String, nil] :env_var (nil) the environment variable
19
+ # that overrides the configuration
20
+ def initialize(name, opts = {})
21
+ @name = name.to_sym
22
+ @default = opts[:default]
23
+ @env_var = opts[:env_var]
24
+ end
25
+
26
+ # @yield if environment variable is not specified or set
27
+ # @yieldparam default [String, nil] the {#default} value of the key
28
+ # @yieldreturn [String, nil] the default value to be returned
29
+ # @return [String] the value from the environment variable or the
30
+ # return value of the block or {#default}
31
+ def value_from_env_var
32
+ if env_var && ENV.key?(env_var)
33
+ ENV[env_var]
34
+ elsif block_given?
35
+ yield default
36
+ else
37
+ default
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,122 @@
1
+ require_relative 'key'
2
+
3
+ module VagrantPlugins
4
+ module ProxyConf
5
+ module Config
6
+ # Helper module for Config classes.
7
+ #
8
+ # Handles mapping to environment variables, setting default values,
9
+ # and constructing the configuration file stanza.
10
+ module KeyMixin
11
+
12
+ # Methods for the including class to specify and access the configuration keys.
13
+ module ClassMethods
14
+ # @!attribute [r] keys
15
+ # @return [Array<Key>] the configuration keys for the class
16
+ def keys
17
+ @keys ||= []
18
+ end
19
+
20
+ # Defines a configuration key for the class.
21
+ # Creates `attr_accessor` for the key name and adds a {Key} to {#keys}.
22
+ # @param (see Key#initialize)
23
+ # @option (see Key#initialize)
24
+ def key(name, opts = {})
25
+ self.class_eval { attr_accessor name }
26
+ keys << Key.new(name, opts)
27
+ end
28
+ end
29
+
30
+ # Extends the including class with {ClassMethods}
31
+ def self.included(base)
32
+ base.extend ClassMethods
33
+ end
34
+
35
+ # Initializes all keys to `UNSET_VALUE`
36
+ def initialize
37
+ super
38
+ keys.each do |key|
39
+ set(key, self.class::UNSET_VALUE)
40
+ end
41
+ end
42
+
43
+ # Overrides values from specified environment variables, and sets them
44
+ # to default values if no configuration was found
45
+ def finalize!
46
+ super
47
+ keys.each { |key| set(key, resolve_value(key)) }
48
+ end
49
+
50
+ # @return [Boolean] true if any of the configuration keys has a non-nil value
51
+ def enabled?
52
+ keys.any? { |key| set?(key) }
53
+ end
54
+
55
+ # Returns the full configuration stanza
56
+ # Calls {#config_for} for each key.
57
+ #
58
+ # @return [String]
59
+ def to_s
60
+ keys.map { |key| config_for(key, get(key)).to_s }.join
61
+ end
62
+
63
+ # Returns a configuration line/stanza for the specified key and value.
64
+ # The returned line should include linefeed `\\n` if not empty.
65
+ # The default implementations returns "<key>=<value>\\n".
66
+ #
67
+ # @param key [Key] the configuration key
68
+ # @param value [String, nil] the configuration value
69
+ # @return [#to_s] the configuration line(s)
70
+ def config_for(key, value)
71
+ "#{key}=#{value}\n"
72
+ end
73
+
74
+ # Returns a new instance of this class where all nil keys are
75
+ # replaced from the specified default config
76
+ #
77
+ # @param defaults [KeyMixin] the default configuration
78
+ # @return [KeyMixin]
79
+ def merge_defaults(defaults)
80
+ result = dup
81
+ keys.each do |key|
82
+ if !set?(key) && defaults.key?(key)
83
+ result.set(key, defaults.get(key))
84
+ end
85
+ end
86
+ result
87
+ end
88
+
89
+ protected
90
+
91
+ def keys
92
+ self.class.keys
93
+ end
94
+
95
+ def key?(key)
96
+ keys.any? { |k| k.name == key.name }
97
+ end
98
+
99
+ def get(key)
100
+ send(key.name)
101
+ end
102
+
103
+ def set?(key)
104
+ !get(key).nil?
105
+ end
106
+
107
+ def set(key, value)
108
+ send(:"#{key.name}=", value)
109
+ end
110
+
111
+ private
112
+
113
+ def resolve_value(key)
114
+ key.value_from_env_var do |default|
115
+ value = get(key)
116
+ value == self.class::UNSET_VALUE ? default : value
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,33 @@
1
+ require 'vagrant'
2
+ require_relative 'key_mixin'
3
+
4
+ module VagrantPlugins
5
+ module ProxyConf
6
+ module Config
7
+ # Default configuration for all proxy Config classes
8
+ #
9
+ # @!parse class Proxy < Vagrant::Plugin::V2::Config; end
10
+ class Proxy < Vagrant.plugin('2', :config)
11
+ include KeyMixin
12
+ # @!parse extend KeyMixin::ClassMethods
13
+
14
+ # @!attribute
15
+ # @return [String] the HTTP proxy
16
+ key :http, env_var: 'VAGRANT_HTTP_PROXY'
17
+
18
+ # @!attribute
19
+ # @return [String] the HTTPS proxy
20
+ key :https, env_var: 'VAGRANT_HTTPS_PROXY'
21
+
22
+ # @!attribute
23
+ # @return [String] the FTP proxy
24
+ key :ftp, env_var: 'VAGRANT_FTP_PROXY'
25
+
26
+ # @!attribute
27
+ # @return [String] a comma separated list of hosts or domains which do not use proxies
28
+ key :no_proxy, env_var: 'VAGRANT_NO_PROXY'
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -15,12 +15,35 @@ module VagrantPlugins
15
15
  # is incompatible with the Vagrant version
16
16
  def self.check_vagrant_version!
17
17
  if Gem::Version.new(Vagrant::VERSION) < Gem::Version.new(MIN_VAGRANT_VERSION)
18
- msg = "vagrant-proxyconf plugin requires Vagrant #{MIN_VAGRANT_VERSION} or newer"
18
+ msg = I18n.t('vagrant_proxyconf.errors.vagrant_version', min_version: MIN_VAGRANT_VERSION)
19
19
  $stderr.puts msg
20
20
  raise msg
21
21
  end
22
22
  end
23
23
 
24
+ # Initializes the internationalization strings
25
+ def self.setup_i18n
26
+ I18n.load_path << File.expand_path('../../../locales/en.yml', __FILE__)
27
+ I18n.reload!
28
+ end
29
+
30
+ def self.register_hooks(hook, provision_action)
31
+ require_relative 'action/configure_apt_proxy'
32
+ require_relative 'action/configure_env_proxy'
33
+
34
+ hook.after provision_action, Action::ConfigureAptProxy
35
+ hook.after provision_action, Action::ConfigureEnvProxy
36
+ end
37
+
38
+ def self.aws_plugin_installed?
39
+ VagrantPlugins.const_defined?('AWS')
40
+ end
41
+
42
+ def self.omnibus_plugin_installed?
43
+ VagrantPlugins.const_defined?('Omnibus')
44
+ end
45
+
46
+ setup_i18n
24
47
  check_vagrant_version!
25
48
 
26
49
  name 'vagrant-proxyconf'
@@ -30,24 +53,37 @@ module VagrantPlugins
30
53
  Config::AptProxy
31
54
  end
32
55
 
56
+ config 'env_proxy' do
57
+ require_relative 'config/env_proxy'
58
+ Config::EnvProxy
59
+ end
60
+
61
+ config 'proxy' do
62
+ require_relative 'config/proxy'
63
+ Config::Proxy
64
+ end
65
+
33
66
  guest_capability 'debian', 'apt_proxy_conf' do
34
67
  require_relative 'cap/debian/apt_proxy_conf'
35
68
  Cap::Debian::AptProxyConf
36
69
  end
37
70
 
38
- proxyconf_action_hook = lambda do |hook|
39
- require_relative 'action/configure_apt_proxy'
40
- hook.after Vagrant::Action::Builtin::Provision, Action::ConfigureAptProxy
71
+ guest_capability 'linux', 'env_proxy_conf' do
72
+ require_relative 'cap/linux/env_proxy_conf'
73
+ Cap::Linux::EnvProxyConf
74
+ end
75
+
76
+ action_hook 'proxyconf_configure' do |hook|
77
+ if omnibus_plugin_installed?
78
+ # configure the proxies before vagrant-omnibus
79
+ register_hooks(hook, VagrantPlugins::Omnibus::Action::InstallChef)
80
+ else
81
+ register_hooks(hook, Vagrant::Action::Builtin::Provision)
41
82
 
42
- # vagrant-aws uses a non-standard provision action
43
- if VagrantPlugins.const_defined?('AWS')
44
- hook.after VagrantPlugins::AWS::Action::TimedProvision, Action::ConfigureAptProxy
83
+ # vagrant-aws uses a non-standard provision action
84
+ register_hooks(hook, VagrantPlugins::AWS::Action::TimedProvision) if aws_plugin_installed?
45
85
  end
46
86
  end
47
- action_hook 'proxyconf-machine-up', :machine_action_up, &proxyconf_action_hook
48
- action_hook 'proxyconf-machine-reload', :machine_action_reload, &proxyconf_action_hook
49
- # Hook to vagrant-digitalocean's `rebuild` command
50
- action_hook 'proxyconf-machine-rebuild', :machine_action_rebuild, &proxyconf_action_hook
51
87
  end
52
88
  end
53
89
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module ProxyConf
3
- VERSION = '0.3.0'
3
+ VERSION = '0.4.0.rc1'
4
4
  end
5
5
  end
data/locales/en.yml ADDED
@@ -0,0 +1,21 @@
1
+ en:
2
+ vagrant_proxyconf:
3
+ apt_proxy:
4
+ not_enabled: |-
5
+ apt_proxy not enabled or configured
6
+ not_supported: |-
7
+ Skipping Apt proxy config as the machine does not support it
8
+ configuring: |-
9
+ Configuring proxy for Apt...
10
+
11
+ env_proxy:
12
+ not_enabled: |-
13
+ env_proxy not enabled or configured
14
+ not_supported: |-
15
+ Skipping environment variable based proxy config as the machine does not support it
16
+ configuring: |-
17
+ Configuring proxy environment variables...
18
+
19
+ errors:
20
+ vagrant_version: |-
21
+ vagrant-proxyconf plugin requires Vagrant %{min_version} or newer
@@ -2,4 +2,10 @@ require 'spec_helper'
2
2
  require 'vagrant-proxyconf/action/configure_apt_proxy'
3
3
 
4
4
  describe VagrantPlugins::ProxyConf::Action::ConfigureAptProxy do
5
+
6
+ describe '#config_name' do
7
+ subject { described_class.new(double, double).config_name }
8
+ it { should eq 'apt_proxy' }
9
+ end
10
+
5
11
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-proxyconf/action/configure_env_proxy'
3
+
4
+ describe VagrantPlugins::ProxyConf::Action::ConfigureEnvProxy do
5
+
6
+ describe '#config_name' do
7
+ subject { described_class.new(double, double).config_name }
8
+ it { should eq 'env_proxy' }
9
+ end
10
+
11
+ end
@@ -7,7 +7,7 @@ describe VagrantPlugins::ProxyConf::Config::AptProxy do
7
7
 
8
8
  before :each do
9
9
  # Ensure tests are not affected by environment variables
10
- %w[APT_PROXY_HTTP APT_PROXY_HTTPS APT_PROXY_FTP].each { |k| ENV.delete(k) }
10
+ %w[HTTP HTTPS FTP].map { |proto| ENV.delete("VAGRANT_APT_#{proto}_PROXY") }
11
11
  end
12
12
 
13
13
  context "defaults" do
@@ -28,9 +28,9 @@ describe VagrantPlugins::ProxyConf::Config::AptProxy do
28
28
  end
29
29
 
30
30
  context "with env var" do
31
- include_examples "apt proxy env var", "APT_PROXY_HTTP", "http"
32
- include_examples "apt proxy env var", "APT_PROXY_HTTPS", "https"
33
- include_examples "apt proxy env var", "APT_PROXY_FTP", "ftp"
31
+ include_examples "apt proxy env var", "VAGRANT_APT_HTTP_PROXY", "http"
32
+ include_examples "apt proxy env var", "VAGRANT_APT_HTTPS_PROXY", "https"
33
+ include_examples "apt proxy env var", "VAGRANT_APT_FTP_PROXY", "ftp"
34
34
  end
35
35
 
36
36
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-proxyconf/config/env_proxy'
3
+
4
+ def config_with(options)
5
+ instance.tap do |c|
6
+ options.each_pair { |k, v| c.send("#{k}=".to_sym, v) }
7
+ c.finalize!
8
+ end
9
+ end
10
+
11
+ def conf_lines(env_var, val)
12
+ [env_var.upcase, env_var.downcase].map { |var| "export #{var}=#{val}\n" }
13
+ end
14
+
15
+ RSpec::Matchers.define :match_lines do |expected|
16
+ match do |actual|
17
+ expect(actual.lines.to_a).to match_array(expected)
18
+ end
19
+ end
20
+
21
+ describe VagrantPlugins::ProxyConf::Config::EnvProxy do
22
+ let(:instance) { described_class.new }
23
+
24
+ before :each do
25
+ # Ensure tests are not affected by environment variables
26
+ %w[HTTP_PROXY HTTPS_PROXY FTP_PROXY NO_PROXY].each do |var|
27
+ ENV.delete("VAGRANT_ENV_#{var}")
28
+ end
29
+ end
30
+
31
+ context "defaults" do
32
+ subject { config_with({}) }
33
+ its(:enabled?) { should be_false }
34
+ its(:to_s) { should eq "" }
35
+ end
36
+
37
+ context "with http config" do
38
+ let(:proxy) { 'http://proxy.example.com:8888' }
39
+ subject { config_with({ http: proxy }) }
40
+ its(:enabled?) { should be_true }
41
+ its(:to_s) { should match_lines conf_lines('http_proxy', proxy) }
42
+ end
43
+
44
+ context "with http and no_proxy config" do
45
+ let(:proxy) { 'http://proxy.example.com:8888' }
46
+ let(:no_proxy) { 'localhost,127.0.0.1' }
47
+ subject { config_with({ http: proxy, no_proxy: no_proxy }) }
48
+ its(:enabled?) { should be_true }
49
+ its(:to_s) { should match_lines conf_lines('http_proxy', proxy) + conf_lines('no_proxy', no_proxy) }
50
+ end
51
+
52
+ context "with VAGRANT_ENV_HTTP_PROXY env var" do
53
+ let(:proxy) { 'http://proxy.example.com:8888' }
54
+ before(:each) { ENV['VAGRANT_ENV_HTTP_PROXY'] = proxy }
55
+ subject { config_with({ http: 'http://default:3128' }) }
56
+ its(:enabled?) { should be_true }
57
+ its(:to_s) { should match_lines conf_lines('HTTP_PROXY', proxy) }
58
+ end
59
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-proxyconf/config/key_mixin'
3
+
4
+ describe VagrantPlugins::ProxyConf::Config::KeyMixin do
5
+
6
+ class TestConfig < Vagrant.plugin('2', :config)
7
+ include VagrantPlugins::ProxyConf::Config::KeyMixin
8
+ key :foo
9
+ key :bar
10
+ end
11
+
12
+ class TestDefaultConfig < Vagrant.plugin('2', :config)
13
+ include VagrantPlugins::ProxyConf::Config::KeyMixin
14
+ key :foo
15
+ key :baz
16
+ end
17
+
18
+ let(:config) do
19
+ TestConfig.new.tap do |c|
20
+ c.foo = foo
21
+ c.bar = bar
22
+ end
23
+ end
24
+
25
+ let(:default) do
26
+ TestDefaultConfig.new.tap do |c|
27
+ c.foo = default_foo
28
+ c.baz = default_baz
29
+ end
30
+ end
31
+
32
+ let(:foo) { nil }
33
+ let(:bar) { nil }
34
+ let(:default_foo) { nil }
35
+ let(:default_baz) { nil }
36
+
37
+ describe '#merge_defaults' do
38
+ subject { config.merge_defaults(default) }
39
+
40
+ context 'with no configuration' do
41
+ it { should be_kind_of config.class }
42
+ it { should_not be config }
43
+
44
+ its(:foo) { should be_nil }
45
+ its(:bar) { should be_nil }
46
+ end
47
+
48
+ context 'without default configuration' do
49
+ let(:foo) { 'tricky' }
50
+ let(:bar) { 'tracks' }
51
+
52
+ its(:foo) { should eq foo }
53
+ its(:bar) { should eq bar }
54
+ end
55
+
56
+ context 'with default configuration' do
57
+ let(:foo) { 'tricky' }
58
+ let(:bar) { 'tracks' }
59
+ let(:default_foo) { 'billy' }
60
+ let(:default_baz) { 'bam-bam' }
61
+
62
+ its(:foo) { should eq foo }
63
+ its(:bar) { should eq bar }
64
+ end
65
+
66
+ context 'with a mixture configuration' do
67
+ let(:bar) { 'tracks' }
68
+ let(:default_foo) { 'billy' }
69
+
70
+ its(:foo) { should eq default_foo }
71
+ its(:bar) { should eq bar }
72
+ end
73
+
74
+ context 'with only default configuration' do
75
+ let(:default_foo) { 'billy' }
76
+ let(:default_baz) { 'bam-bam' }
77
+
78
+ its(:foo) { should eq default_foo }
79
+ its(:bar) { should be_nil }
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-proxyconf/config/key'
3
+
4
+ describe VagrantPlugins::ProxyConf::Config::Key do
5
+
6
+ describe '.new' do
7
+ context 'without options' do
8
+ subject { described_class.new(name) }
9
+ let(:name) { :mykey }
10
+ its(:name) { should eq name }
11
+ its(:default) { should be_nil }
12
+ its(:env_var) { should be_nil }
13
+ end
14
+
15
+ context 'with string name' do
16
+ subject { described_class.new(name) }
17
+ let(:name) { 'mykey' }
18
+ its(:name) { should eq name.to_sym }
19
+ end
20
+
21
+ context 'with default value' do
22
+ subject { described_class.new(name, default: default) }
23
+ let(:name) { :foo }
24
+ let(:default) { 'bar' }
25
+ its(:default) { should eq default }
26
+ end
27
+
28
+ context 'with env_var' do
29
+ subject { described_class.new(name, env_var: env_var) }
30
+ let(:name) { :key }
31
+ let(:env_var) { 'baz' }
32
+ its(:env_var) { should eq env_var }
33
+ end
34
+ end
35
+
36
+ describe '#value_from_env_var' do
37
+ before :each do
38
+ %w[foo_bar BAZ].each { |k| ENV.delete(k) }
39
+ end
40
+ let(:instance) { described_class.new(name, default: default, env_var: env_var) }
41
+ let(:name) { 'the_key' }
42
+ let(:default) { nil }
43
+ let(:env_var) { nil }
44
+
45
+ shared_examples 'env_var' do
46
+ it 'returns :default without block' do
47
+ expect(instance.value_from_env_var).to eq default
48
+ end
49
+ it 'yields with the :default value' do
50
+ expect { |b| instance.value_from_env_var(&b) }.to yield_with_args default
51
+ end
52
+ it 'returns the value from the block' do
53
+ ret = 'block_default'
54
+ expect(instance.value_from_env_var { ret }).to eq ret
55
+ end
56
+ end
57
+
58
+ context 'without env_var' do
59
+ context 'with a specified default' do
60
+ let(:default) { 'param_default' }
61
+ include_examples 'env_var'
62
+ end
63
+
64
+ context 'and without default' do
65
+ include_examples 'env_var'
66
+ end
67
+ end
68
+
69
+ context 'with env_var' do
70
+ before :each do
71
+ ENV['foo_bar'] = 'from_env_var'
72
+ ENV['BAZ'] = 'second_env_var'
73
+ end
74
+ let(:env_var) { 'BAZ' }
75
+ let(:default) { 'the_default' }
76
+
77
+ it 'returns value of the environment variable' do
78
+ expect(instance.value_from_env_var).to eq ENV['BAZ']
79
+ end
80
+ it 'does not yield' do
81
+ expect { |b| instance.value_from_env_var(&b) }.not_to yield_control
82
+ end
83
+ end
84
+ end
85
+
86
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-proxyconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
5
- prerelease:
4
+ version: 0.4.0.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Teemu Matilainen
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2013-08-30 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A Vagrant plugin that configures the virtual machine to use proxies
15
15
  email:
@@ -31,16 +31,28 @@ files:
31
31
  - development/README.md
32
32
  - development/Vagrantfile.example
33
33
  - lib/vagrant-proxyconf.rb
34
+ - lib/vagrant-proxyconf/action/base.rb
34
35
  - lib/vagrant-proxyconf/action/configure_apt_proxy.rb
36
+ - lib/vagrant-proxyconf/action/configure_env_proxy.rb
35
37
  - lib/vagrant-proxyconf/cap/debian/apt_proxy_conf.rb
38
+ - lib/vagrant-proxyconf/cap/linux/env_proxy_conf.rb
36
39
  - lib/vagrant-proxyconf/config/apt_proxy.rb
40
+ - lib/vagrant-proxyconf/config/env_proxy.rb
41
+ - lib/vagrant-proxyconf/config/key.rb
42
+ - lib/vagrant-proxyconf/config/key_mixin.rb
43
+ - lib/vagrant-proxyconf/config/proxy.rb
37
44
  - lib/vagrant-proxyconf/plugin.rb
38
45
  - lib/vagrant-proxyconf/version.rb
46
+ - locales/en.yml
39
47
  - spec/spec_helper.rb
40
48
  - spec/unit/support/shared/apt_proxy_config.rb
41
49
  - spec/unit/vagrant-proxyconf/action/configure_apt_proxy_spec.rb
50
+ - spec/unit/vagrant-proxyconf/action/configure_env_proxy_spec.rb
42
51
  - spec/unit/vagrant-proxyconf/cap/debian/apt_proxy_conf_spec.rb
43
52
  - spec/unit/vagrant-proxyconf/config/apt_proxy_spec.rb
53
+ - spec/unit/vagrant-proxyconf/config/env_proxy_spec.rb
54
+ - spec/unit/vagrant-proxyconf/config/key_mixin_spec.rb
55
+ - spec/unit/vagrant-proxyconf/config/key_spec.rb
44
56
  - spec/unit/vagrant-proxyconf/plugin_spec.rb
45
57
  - vagrant-proxyconf.gemspec
46
58
  homepage: http://tmatilai.github.io/vagrant-proxyconf/
@@ -58,16 +70,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
70
  version: '0'
59
71
  segments:
60
72
  - 0
61
- hash: 3198216208626978364
73
+ hash: -457260254384338946
62
74
  required_rubygems_version: !ruby/object:Gem::Requirement
63
75
  none: false
64
76
  requirements:
65
- - - ! '>='
77
+ - - ! '>'
66
78
  - !ruby/object:Gem::Version
67
- version: '0'
68
- segments:
69
- - 0
70
- hash: 3198216208626978364
79
+ version: 1.3.1
71
80
  requirements: []
72
81
  rubyforge_project:
73
82
  rubygems_version: 1.8.23
@@ -78,7 +87,11 @@ test_files:
78
87
  - spec/spec_helper.rb
79
88
  - spec/unit/support/shared/apt_proxy_config.rb
80
89
  - spec/unit/vagrant-proxyconf/action/configure_apt_proxy_spec.rb
90
+ - spec/unit/vagrant-proxyconf/action/configure_env_proxy_spec.rb
81
91
  - spec/unit/vagrant-proxyconf/cap/debian/apt_proxy_conf_spec.rb
82
92
  - spec/unit/vagrant-proxyconf/config/apt_proxy_spec.rb
93
+ - spec/unit/vagrant-proxyconf/config/env_proxy_spec.rb
94
+ - spec/unit/vagrant-proxyconf/config/key_mixin_spec.rb
95
+ - spec/unit/vagrant-proxyconf/config/key_spec.rb
83
96
  - spec/unit/vagrant-proxyconf/plugin_spec.rb
84
97
  has_rdoc: