Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single / global configuration key for setting proxy #17

Merged
merged 5 commits into from
Aug 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 0.4.0 / _Unreleased_

- BREAKING: Environment variables for Apt config renamed to `VAGRANT_APT_HTTP_PROXY` etc. ([GH-15][])
- Configure all supported programs with a single `config.proxy` configuration or `VAGRANT_HTTP_PROXY` etc. environment variables ([GH-14][], [GH-17][])
- Add support for global `*_proxy` environment variables via `config.env_proxy` ([GH-6][])
- Configure the VM also on `vagrant provision` ([GH-12][])
* Hook to all commands that trigger provisioning action
Expand Down Expand Up @@ -38,4 +39,6 @@
[GH-10]: https://github.com/tmatilai/vagrant-proxyconf/issues/10 "Issue 10"
[GH-11]: https://github.com/tmatilai/vagrant-proxyconf/issues/11 "Issue 11"
[GH-12]: https://github.com/tmatilai/vagrant-proxyconf/issues/12 "Issue 12"
[GH-14]: https://github.com/tmatilai/vagrant-proxyconf/issues/14 "Issue 14"
[GH-15]: https://github.com/tmatilai/vagrant-proxyconf/issues/15 "Issue 15"
[GH-17]: https://github.com/tmatilai/vagrant-proxyconf/issues/17 "Issue 17"
45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,53 @@ vagrant plugin install vagrant-proxyconf

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.

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.
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.

Project specific Vagrantfile overrides global settings. Environment variables override both.

### Default/global configuration

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.

#### Example Vagrantfile

```ruby
Vagrant.configure("2") do |config|
config.proxy.http = "http://192.168.0.2:3128/"
config.proxy.https = "http://192.168.0.2:3128/"
config.proxy.no_proxy = "localhost,127.0.0.1,.example.com"
# ... other stuff
end
```

#### Configuration keys

* `config.proxy.http` - The proxy for HTTP URIs
* `config.proxy.https` - The proxy for HTTPS URIs
* `config.proxy.ftp` - The proxy for FTS URIs
* `config.proxy.no_proxy` - A comma separated list of hosts or domains which do not use proxies.

#### Possible values

* If all keys are unset or `nil`, no configuration is written.
* A proxy should be specified in the form of _protocol://[user:pass@]host[:port]_.
* 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.

#### Environment variables

* `VAGRANT_HTTP_PROXY`
* `VAGRANT_HTTPS_PROXY`
* `VAGRANT_FTP_PROXY`
* `VAGRANT_NO_PROXY`

These also override the Vagrantfile configuration. To disable or remove the proxy use an empty value.

For example to spin up a VM, run:

```sh
VAGRANT_HTTP_PROXY="http://proxy.example.com:8080" vagrant up
```

### Global `*_proxy` environment variables

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.
Expand Down
7 changes: 7 additions & 0 deletions lib/vagrant-proxyconf/action/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ def config_name
def config(machine)
config = machine.config.send(config_name.to_sym)
finalize_config(config)
config.merge_defaults(default_config(machine))
end

# @return [Vagrant::Plugin::V2::Config] the default configuration
def default_config(machine)
config = machine.config.proxy
finalize_config(config)
end

def finalize_config(config)
Expand Down
29 changes: 27 additions & 2 deletions lib/vagrant-proxyconf/config/key_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def finalize!

# @return [Boolean] true if any of the configuration keys has a non-nil value
def enabled?
keys.any? { |key| !get(key).nil? }
keys.any? { |key| set?(key) }
end

# Returns the full configuration stanza
Expand All @@ -71,20 +71,45 @@ def config_for(key, value)
"#{key}=#{value}\n"
end

private
# Returns a new instance of this class where all nil keys are
# replaced from the specified default config
#
# @param defaults [KeyMixin] the default configuration
# @return [KeyMixin]
def merge_defaults(defaults)
result = dup
keys.each do |key|
if !set?(key) && defaults.key?(key)
result.set(key, defaults.get(key))
end
end
result
end

protected

def keys
self.class.keys
end

def key?(key)
keys.any? { |k| k.name == key.name }
end

def get(key)
send(key.name)
end

def set?(key)
!get(key).nil?
end

def set(key, value)
send(:"#{key.name}=", value)
end

private

def resolve_value(key)
key.value_from_env_var do |default|
value = get(key)
Expand Down
33 changes: 33 additions & 0 deletions lib/vagrant-proxyconf/config/proxy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'vagrant'
require_relative 'key_mixin'

module VagrantPlugins
module ProxyConf
module Config
# Default configuration for all proxy Config classes
#
# @!parse class Proxy < Vagrant::Plugin::V2::Config; end
class Proxy < Vagrant.plugin('2', :config)
include KeyMixin
# @!parse extend KeyMixin::ClassMethods

# @!attribute
# @return [String] the HTTP proxy
key :http, env_var: 'VAGRANT_HTTP_PROXY'

# @!attribute
# @return [String] the HTTPS proxy
key :https, env_var: 'VAGRANT_HTTPS_PROXY'

# @!attribute
# @return [String] the FTP proxy
key :ftp, env_var: 'VAGRANT_FTP_PROXY'

# @!attribute
# @return [String] a comma separated list of hosts or domains which do not use proxies
key :no_proxy, env_var: 'VAGRANT_NO_PROXY'

end
end
end
end
5 changes: 5 additions & 0 deletions lib/vagrant-proxyconf/plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ def self.setup_i18n
Config::EnvProxy
end

config 'proxy' do
require_relative 'config/proxy'
Config::Proxy
end

guest_capability 'debian', 'apt_proxy_conf' do
require_relative 'cap/debian/apt_proxy_conf'
Cap::Debian::AptProxyConf
Expand Down
77 changes: 76 additions & 1 deletion spec/unit/vagrant-proxyconf/config/key_mixin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,82 @@
require 'vagrant-proxyconf/config/key_mixin'

describe VagrantPlugins::ProxyConf::Config::KeyMixin do
let(:instance) { described_class.new }

class TestConfig < Vagrant.plugin('2', :config)
include VagrantPlugins::ProxyConf::Config::KeyMixin
key :foo
key :bar
end

class TestDefaultConfig < Vagrant.plugin('2', :config)
include VagrantPlugins::ProxyConf::Config::KeyMixin
key :foo
key :baz
end

let(:config) do
TestConfig.new.tap do |c|
c.foo = foo
c.bar = bar
end
end

let(:default) do
TestDefaultConfig.new.tap do |c|
c.foo = default_foo
c.baz = default_baz
end
end

let(:foo) { nil }
let(:bar) { nil }
let(:default_foo) { nil }
let(:default_baz) { nil }

describe '#merge_defaults' do
subject { config.merge_defaults(default) }

context 'with no configuration' do
it { should be_kind_of config.class }
it { should_not be config }

its(:foo) { should be_nil }
its(:bar) { should be_nil }
end

context 'without default configuration' do
let(:foo) { 'tricky' }
let(:bar) { 'tracks' }

its(:foo) { should eq foo }
its(:bar) { should eq bar }
end

context 'with default configuration' do
let(:foo) { 'tricky' }
let(:bar) { 'tracks' }
let(:default_foo) { 'billy' }
let(:default_baz) { 'bam-bam' }

its(:foo) { should eq foo }
its(:bar) { should eq bar }
end

context 'with a mixture configuration' do
let(:bar) { 'tracks' }
let(:default_foo) { 'billy' }

its(:foo) { should eq default_foo }
its(:bar) { should eq bar }
end

context 'with only default configuration' do
let(:default_foo) { 'billy' }
let(:default_baz) { 'bam-bam' }

its(:foo) { should eq default_foo }
its(:bar) { should be_nil }
end
end

end