vagrant-auto_network 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1,12 @@
1
+ vagrant-auto_network
2
+ ====================
3
+
4
+ 0.2.0
5
+ -----
6
+
7
+ 2013-08-07
8
+
9
+ This is a backwards compatible feature release. It reimplements the
10
+ auto_network functionality as part of the :private_network network config
11
+ method. It also implements persistent leases so that machines in different
12
+ Vagrant environments all have unique addresses.
data/README.markdown CHANGED
@@ -26,14 +26,13 @@ Usage
26
26
  node.vm.box = "centos-5-i386"
27
27
 
28
28
  node.vm.extend AutoNetwork::Mixin
29
- node.vm.auto_network!
29
+ node.vm.network :private_network, :auto_network => true
30
30
  end
31
31
 
32
32
  config.vm.define 'second' do |node|
33
33
  node.vm.box = "centos-5-i386"
34
34
 
35
- node.vm.extend AutoNetwork::Mixin
36
- node.vm.auto_network!
35
+ node.vm.network :private_network, :auto_network => true
37
36
  end
38
37
  end
39
38
 
@@ -54,8 +53,8 @@ To change this, add the following _before_ the Vagrant configuration block:
54
53
  Contact
55
54
  -------
56
55
 
57
- * Source code: https://github.com/adrienthebo/vagrant-auto\_network
58
- * Issue tracker: https://github.com/adrienthebo/vagrant-auto\_network/issues
56
+ * [Source code](https://github.com/adrienthebo/vagrant-auto_network)
57
+ * [Issue tracker](https://github.com/adrienthebo/vagrant-auto_network/issues)
59
58
 
60
59
  If you have questions or concerns about this module, contact finch on Freenode,
61
60
  or email adrien@puppetlabs.com.
data/lib/auto_network.rb CHANGED
@@ -1,13 +1,12 @@
1
- require 'auto_network/mixin'
2
-
3
1
  module AutoNetwork
4
- class << self
5
- def default_pool
6
- @default_pool ||= '10.20.1.0/24'
7
- end
8
2
 
9
- def default_pool=(pool)
10
- @default_pool = pool
11
- end
12
- end
3
+ require 'auto_network/default_pool'
4
+ extend DefaultPool
5
+
6
+ require 'auto_network/action'
7
+ require 'auto_network/mixin'
8
+ require 'auto_network/plugin'
9
+ require 'auto_network/version'
13
10
  end
11
+
12
+ I18n.load_path << File.expand_path('../templates/locales/en.yml', File.dirname(__FILE__))
@@ -0,0 +1,8 @@
1
+ module AutoNetwork
2
+ module Action
3
+ require 'auto_network/action/load_pool'
4
+ require 'auto_network/action/filter_networks'
5
+ require 'auto_network/action/release'
6
+ require 'auto_network/action/request'
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ require 'auto_network/action_helpers'
2
+ require 'log4r'
3
+
4
+ class AutoNetwork::Action::FilterNetworks
5
+
6
+ include AutoNetwork::ActionHelpers
7
+
8
+ def initialize(app, env)
9
+ @app, @env = app, env
10
+
11
+ @logger = Log4r::Logger.new('vagrant::auto_network::filter_networks')
12
+ end
13
+
14
+ # Convert auto_network interfaces to static private_network interfaces.
15
+ #
16
+ # @param env [Hash]
17
+ #
18
+ # @option env [AutoNetwork::Pool] auto_network_pool The global auto network pool
19
+ # @option env [Vagrant::Environment] env The Vagrant environment containing
20
+ # the active machines that need to be filtered.
21
+ #
22
+ # @return [void]
23
+ def call(env)
24
+ @env = env
25
+
26
+ @pool = @env[:auto_network_pool]
27
+ global_env = @env[:env]
28
+
29
+ machines_for_env(global_env).each do |machine|
30
+ assign_address(machine) if machine_has_address?(machine)
31
+ end
32
+
33
+ @app.call(@env)
34
+ end
35
+
36
+ private
37
+
38
+ def machines_for_env(global_env)
39
+ global_env.active_machines.map { |vm_id| global_env.machine(*vm_id) }
40
+ end
41
+
42
+ def assign_address(machine)
43
+ machine_auto_networks(machine).each do |net|
44
+ addr = @pool.address_for(machine)
45
+ @logger.info "Reassigning #{addr.inspect} to existing machine #{machine.id}"
46
+ filter_private_network(net, addr)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,50 @@
1
+ require 'auto_network'
2
+ require 'yaml'
3
+
4
+ class AutoNetwork::Action::LoadPool
5
+
6
+ def initialize(app, env)
7
+ @app, @env = app, env
8
+
9
+ @config_path = @env[:home_path].join('auto_network')
10
+ @statefile = @config_path.join('pool.yaml')
11
+ end
12
+
13
+ # Handle the loading and unloading of the auto_network pool
14
+ #
15
+ # @param env [Hash]
16
+ #
17
+ # @option env [AutoNetwork::Pool] auto_network_pool The global auto network pool
18
+ # @option env [Vagrant::Environment] env The Vagrant environment containing
19
+ # the active machines that need to be filtered.
20
+ #
21
+ # @return [void]
22
+ def call(env)
23
+ @env = env
24
+
25
+ deserialize!
26
+ @app.call(@env)
27
+ serialize!
28
+ end
29
+
30
+ private
31
+
32
+ def deserialize!
33
+ pool = nil
34
+ if @statefile.exist?
35
+ pool = YAML.load(@statefile.read)
36
+ else
37
+ range = AutoNetwork.default_pool
38
+ @env[:ui].info "No auto_network pool available, generating a pool with the range #{range}"
39
+ pool = AutoNetwork::Pool.new(range)
40
+ end
41
+ @env[:auto_network_pool] = pool
42
+ end
43
+
44
+ def serialize!
45
+ @config_path.mkpath unless @config_path.exist?
46
+
47
+ pool_data = YAML.dump(@env[:auto_network_pool])
48
+ @statefile.open('w') { |fh| fh.write(pool_data) }
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ require 'auto_network/action_helpers'
2
+
3
+ class AutoNetwork::Action::Release
4
+
5
+ include AutoNetwork::ActionHelpers
6
+
7
+ def initialize(app, env)
8
+ @app, @env = app, env
9
+ end
10
+
11
+ # Release auto_network IP address on VM destruction
12
+ #
13
+ # @param env [Hash]
14
+ #
15
+ # @option env [AutoNetwork::Pool] auto_network_pool The global auto network pool
16
+ # @option env [Vagrant::Machine] machine The Vagrant machine being destroyed
17
+ #
18
+ # @return [void]
19
+ def call(env)
20
+ @env = env
21
+
22
+ @machine = @env[:machine]
23
+ @pool = @env[:auto_network_pool]
24
+
25
+ release_network_addresses if machine_has_address?(@machine)
26
+
27
+ @app.call(@env)
28
+ end
29
+
30
+ private
31
+
32
+ def release_network_addresses
33
+ addr = @pool.address_for(@machine)
34
+ @env[:ui].info "Releasing #{addr.inspect} from #{@machine.id}", :prefix => true
35
+ @pool.release(@machine)
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ require 'auto_network/action_helpers'
2
+
3
+ class AutoNetwork::Action::Request
4
+
5
+ include AutoNetwork::ActionHelpers
6
+
7
+ def initialize(app, env)
8
+ @app, @env = app, env
9
+ end
10
+
11
+ # Request an auto_network IP address on VM creation
12
+ #
13
+ # @param env [Hash]
14
+ #
15
+ # @option env [AutoNetwork::Pool] auto_network_pool The global auto network pool
16
+ # @option env [Vagrant::Machine] machine The Vagrant machine being created
17
+ #
18
+ # @return [void]
19
+ def call(env)
20
+ @env = env
21
+
22
+ @pool = @env[:auto_network_pool]
23
+ @machine = @env[:machine]
24
+
25
+ request_address unless machine_has_address?(@machine)
26
+
27
+ @app.call(@env)
28
+ end
29
+
30
+ private
31
+
32
+ def request_address
33
+ machine_auto_networks(@machine).each do |net|
34
+ addr = @pool.request(@machine)
35
+ @env[:ui].info "Assigning #{addr.inspect} to '#{@machine.id}'", :prefix => true
36
+ filter_private_network(net, addr)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module AutoNetwork
2
+ module ActionHelpers
3
+
4
+ # Determine if the given machine exists and has an auto_network address
5
+ #
6
+ # @param [Vagrant::Machine]
7
+ #
8
+ # @return [true, false]
9
+ def machine_has_address?(machine)
10
+ !!(machine and @pool.address_for(machine))
11
+ end
12
+
13
+ # Fetch all private networks that are tagged for auto networking
14
+ #
15
+ # @param iface [Array<Symbol, Hash>]
16
+ #
17
+ # @return [Array<Symbol, Hash>] All auto_networks
18
+ def machine_auto_networks(machine)
19
+ machine.config.vm.networks.select do |(net_type, options)|
20
+ net_type == :private_network and options[:auto_network]
21
+ end
22
+ end
23
+
24
+ # Convert an auto network to a private network with a static IP address.
25
+ #
26
+ # This does an in-place modification of the private_network options hash
27
+ # to strip out the auto_network configuration and make this behave like a
28
+ # normal private network interface with a static IP address.
29
+ #
30
+ # @param iface [Array<Symbol, Hash>]
31
+ # @param addr [String] The static IP address to assign to the private network
32
+ #
33
+ # @return [void]
34
+ def filter_private_network(iface, addr)
35
+ opts = iface[1]
36
+ opts.delete(:auto_network)
37
+ opts[:ip] = addr
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ module AutoNetwork::DefaultPool
2
+ def default_pool
3
+ @default_pool ||= '10.20.1.0/24'
4
+ end
5
+
6
+ def default_pool=(pool)
7
+ @default_pool = pool
8
+ end
9
+ end
@@ -1,15 +1,12 @@
1
1
  require 'auto_network/pool'
2
2
 
3
3
  module AutoNetwork
4
-
5
- # Extension to vagrant VM configuration to automatically configure an
6
- # internal network.
7
- module Mixin
8
-
9
- def auto_network!
10
- pool = AutoNetwork::Pool.instance
11
- addr = pool.next
12
- network :private_network, :ip => addr
4
+ # Extension to vagrant VM configuration to automatically configure an
5
+ # internal network.
6
+ module Mixin
7
+ def auto_network!
8
+ puts "AutoNetwork::Mixin is deprecated, use config.vm.network :private_network, :auto_network => true"
9
+ network :private_network, :auto_network => true
10
+ end
13
11
  end
14
12
  end
15
- end
@@ -0,0 +1,32 @@
1
+ require 'vagrant'
2
+ require 'auto_network/action'
3
+
4
+ module AutoNetwork
5
+ class Plugin < Vagrant.plugin('2')
6
+ name 'auto_network'
7
+
8
+ description <<-DESC
9
+ This plugin adds support for automatically configuring Vagrant hostonly
10
+ networks.
11
+ DESC
12
+
13
+ action_hook('Auto network: initialize address pool') do |hook|
14
+ hook.prepend AutoNetwork::Action::LoadPool
15
+ end
16
+
17
+ action_hook('Auto network: filter private networks', :environment_load) do |hook|
18
+ action = AutoNetwork::Action::LoadPool
19
+ hook.after(action, AutoNetwork::Action::FilterNetworks)
20
+ end
21
+
22
+ action_hook('Auto network: request address', :machine_action_up) do |hook|
23
+ action = VagrantPlugins::ProviderVirtualBox::Action::Network
24
+ hook.before(action, AutoNetwork::Action::Request)
25
+ end
26
+
27
+ action_hook('Auto network: release address', :machine_action_destroy) do |hook|
28
+ action = VagrantPlugins::ProviderVirtualBox::Action::Destroy
29
+ hook.before(action, AutoNetwork::Action::Release)
30
+ end
31
+ end
32
+ end
@@ -1,39 +1,73 @@
1
- require 'auto_network'
2
-
3
- require 'ipaddress'
1
+ require 'ipaddr'
4
2
 
5
3
  module AutoNetwork
6
- class Pool
4
+ class Pool
7
5
 
8
- class PoolExhaustedError < StandardError; end
6
+ class PoolExhaustedError < Vagrant::Errors::VagrantError
7
+ error_key(:pool_exhausted, 'vagrant_auto_network')
8
+ end
9
9
 
10
- # Provide a single instance of this class
11
- #
12
- # @return [AutoNetwork::Pool]
13
- def self.instance
14
- @myself ||= new
15
- end
10
+ # @param network_addr [String] The network address range to use as the
11
+ # address pool.
12
+ def initialize(network_range)
13
+ @network_range = network_range
14
+ generate_pool
15
+ end
16
16
 
17
- # @param addr [String] The network address range to use as the address pool.
18
- # Defaults to `AutoNetwork.default_pool`
19
- def initialize(addr = AutoNetwork.default_pool)
20
- @addr = addr
21
- @network = IPAddress.parse(addr)
17
+ # Retrieve an IP address for the given machine. If a machine already has
18
+ # an IP address requested, then return that.
19
+ #
20
+ # @param machine [Vagrant::Machine]
21
+ def request(machine)
22
+ if (address = address_for(machine))
23
+ return address
24
+ elsif (address = next_available_lease)
25
+ @pool[address] = machine.id
26
+ return address
27
+ else
28
+ raise PoolExhaustedError,
29
+ :name => machine.name,
30
+ :network => @network_range
31
+ end
32
+ end
22
33
 
23
- @range = @network.hosts
24
- # Drop the first IP address as it should be reserved for the host system
25
- @range.shift
26
- end
34
+ # Release an IP address associated with a machine
35
+ #
36
+ # @param machine [Vagrant::Machine]
37
+ def release(machine)
38
+ if (address = address_for(machine))
39
+ @pool[address] = nil
40
+ end
41
+ end
27
42
 
28
- # @return [String] The string representation of the next available address
29
- # @raise [PoolExhaustedError] There are no remaining addresses in the pool.
30
- def next
31
- if @range.empty?
32
- raise PoolExhaustedError, "No addresses remaining in network address pool #{addr.inspect}"
43
+ def address_for(machine)
44
+ return nil if machine.id.nil?
45
+ next_addr, _ = @pool.find { |(addr, id)| machine.id == id }
46
+
47
+ next_addr
33
48
  end
34
49
 
35
- addr = @range.shift
36
- addr.address
50
+ private
51
+
52
+ def next_available_lease
53
+ next_addr, _ = @pool.find { |(addr, id)| id.nil? }
54
+
55
+ next_addr
56
+ end
57
+
58
+ def generate_pool
59
+ network = IPAddr.new(@network_range)
60
+ addresses = network.to_range.to_a
61
+
62
+ addresses.delete_at(-1) # Strip out the broadcast address
63
+ addresses.delete_at(1) # And the first address (should be used by the host)
64
+ addresses.delete_at(0) # And the network address
65
+
66
+ @pool = {}
67
+
68
+ addresses.map(&:to_s).each do |addr|
69
+ @pool[addr] = nil
70
+ end
71
+ end
37
72
  end
38
73
  end
39
- end
@@ -1,3 +1,3 @@
1
1
  module AutoNetwork
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -0,0 +1,9 @@
1
+ ---
2
+ en:
3
+ vagrant_auto_network:
4
+ pool_exhausted: |-
5
+ The machine '%{name}' tried to get an automatic network address, but all
6
+ ip addresses in the network range '%{network}' have been used. This is
7
+ probably due to VMs being deleted outside of Vagrant. Check the
8
+ auto_network pool configuration file and remove the machine IDs from
9
+ addresses that are no longer in use, or add addresses to the pool.
@@ -13,8 +13,8 @@ Gem::Specification.new do |gem|
13
13
 
14
14
  gem.summary = "Automatically create an internal network for all vagrant boxes"
15
15
 
16
- gem.add_dependency 'ipaddress'
17
-
18
16
  gem.files = %x{git ls-files -z}.split("\0")
19
17
  gem.require_path = 'lib'
18
+
19
+ gem.license = 'Apache 2.0'
20
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-auto_network
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,40 +9,35 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-07 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: ipaddress
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
12
+ date: 2013-08-08 00:00:00.000000000 Z
13
+ dependencies: []
30
14
  description:
31
15
  email: adrien@somethingsinistral.net
32
16
  executables: []
33
17
  extensions: []
34
18
  extra_rdoc_files: []
35
19
  files:
20
+ - CHANGELOG
36
21
  - Gemfile
37
22
  - README.markdown
38
23
  - lib/auto_network.rb
24
+ - lib/auto_network/action.rb
25
+ - lib/auto_network/action/filter_networks.rb
26
+ - lib/auto_network/action/load_pool.rb
27
+ - lib/auto_network/action/release.rb
28
+ - lib/auto_network/action/request.rb
29
+ - lib/auto_network/action_helpers.rb
30
+ - lib/auto_network/default_pool.rb
39
31
  - lib/auto_network/mixin.rb
32
+ - lib/auto_network/plugin.rb
40
33
  - lib/auto_network/pool.rb
41
34
  - lib/auto_network/version.rb
42
35
  - lib/vagrant-auto_network.rb
36
+ - templates/locales/en.yml
43
37
  - vagrant-auto_network.gemspec
44
38
  homepage: https://github.com/adrienthebo/vagrant-auto_network
45
- licenses: []
39
+ licenses:
40
+ - Apache 2.0
46
41
  post_install_message:
47
42
  rdoc_options: []
48
43
  require_paths: