furnish-ip 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ html
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in furnish-ip.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,10 @@
1
+ # vim: ft=ruby
2
+ guard 'minitest' do
3
+ # with Minitest::Unit
4
+ watch(%r!^test/(.*)\/?test_(.*)\.rb!)
5
+ watch(%r!^test/(?:mt_cases|helper)\.rb!) { "test" }
6
+ end
7
+
8
+ guard 'rake', :failure_ok => true, :run_on_all => false, :task => 'rdoc_cov' do
9
+ watch(%r!^lib/(.*)([^/]+)\.rb!)
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Erik Hollensbe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Furnish::IP
2
+
3
+ This provides 3 classes:
4
+
5
+ * Furnish::IP, a simple class to maintain a grouped IP registry
6
+ * Furnish::Provisioner::IP, a furnish provisioner intended to be chained to
7
+ resources that allocate their own IP addresses for recording purposes.
8
+ * Furnish::Provisioner::AutoIP, a furnish provisioner that works against a
9
+ subnet, allocating IPs automatically based on what's not in use.
10
+
11
+ Please see the documentation for these classes, and the furnish documentation,
12
+ for further usage.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'furnish-ip'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install furnish-ip
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.test_files = FileList["test/test_*.rb"]
8
+ t.verbose = true
9
+ end
10
+
11
+ RDoc::Task.new do |rdoc|
12
+ rdoc.title = "Generic IP allocator for the Furnish provisioning system"
13
+ rdoc.rdoc_files.include("lib/**/*.rb")
14
+ rdoc.rdoc_files -= ["lib/furnish/ip/version.rb"]
15
+ if ENV["RDOC_COVER"]
16
+ rdoc.options << "-C"
17
+ end
18
+ end
19
+
20
+ desc "run tests with coverage report"
21
+ task "test:coverage" do
22
+ ENV["COVERAGE"] = "1"
23
+ Rake::Task["test"].invoke
24
+ end
25
+
26
+ desc "run rdoc with coverage report"
27
+ task :rdoc_cov do
28
+ # ugh
29
+ ENV["RDOC_COVER"] = "1"
30
+ ruby "-S rake rerdoc"
31
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'furnish/ip/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "furnish-ip"
8
+ gem.version = Furnish::IP::VERSION
9
+ gem.authors = ["Erik Hollensbe"]
10
+ gem.email = ["erik+github@hollensbe.org"]
11
+ gem.description = %q{Generic IP allocator for the Furnish provisioning system}
12
+ gem.summary = %q{Generic IP allocator for the Furnish provisioning system}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'furnish', '~> 0.0.1'
21
+ gem.add_dependency 'palsy', '~> 0.0.2'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'minitest', '~> 4.5.0'
25
+ gem.add_development_dependency 'guard-minitest'
26
+ gem.add_development_dependency 'guard-rake'
27
+ gem.add_development_dependency 'rdoc'
28
+ gem.add_development_dependency 'rb-fsevent'
29
+ gem.add_development_dependency 'simplecov'
30
+ end
@@ -0,0 +1,6 @@
1
+ module Furnish
2
+ class IP
3
+ # Version for furnish-ip
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
data/lib/furnish/ip.rb ADDED
@@ -0,0 +1,120 @@
1
+ require 'ipaddr'
2
+ require 'set'
3
+
4
+ module Furnish # :nodoc:
5
+
6
+ #
7
+ # Furnish::IP maintains a saved registry of IP allocations, and can be
8
+ # instantiated any time after Furnish is.
9
+ #
10
+ class IP
11
+
12
+ ##
13
+ # the subnet being worked over as an IPAddr object.
14
+ attr_reader :subnet
15
+ ##
16
+ # the name of the registry.
17
+ attr_reader :name
18
+ ##
19
+ # A Palsy::Set of the sum of allocated addresses.
20
+ attr_reader :allocated
21
+ ##
22
+ # A Palsy::Map of the individual groups of addresses. Each item yields a
23
+ # set of string IP addresses.
24
+ attr_reader :groups
25
+
26
+ #
27
+ # Instantiate a new IP registry.
28
+ #
29
+ # Subnet is expected to be a String in CIDR notation or IPAddr object. If
30
+ # nil is passed, indicates no automated allocation logic is to be used and
31
+ # calls that do so will raise if referenced, allowing you to record
32
+ # allocations from another source.
33
+ #
34
+ # The name is a string and is "default" by default. Can be used to create
35
+ # semantic relationships or refer to an existing collection with a newly
36
+ # constructed object.
37
+ #
38
+ def initialize(subnet=nil, name="default")
39
+ if subnet and !subnet.kind_of?(IPAddr)
40
+ subnet = IPAddr.new(subnet) unless subnet.kind_of?(IPAddr)
41
+ end
42
+
43
+ @subnet = subnet
44
+ @name = name
45
+ @allocated = Palsy::Set.new('furnish_ip_allocations', name)
46
+ @groups = Palsy::Map.new('furnish_ip_groups', name)
47
+ end
48
+
49
+ #
50
+ # Determine, based on allocations already made, what the next available
51
+ # un-used IP is. Will raise ArgumentError if #new is not provided with an
52
+ # IPAddr object (see the documentation there for details).
53
+ #
54
+ # Will raise RuntimeError if the subnet is exhausted.
55
+ #
56
+ def unused_ip
57
+ unless subnet
58
+ raise ArgumentError, "#{self.class}#unused_ip requires an IPAddr object to work"
59
+ end
60
+
61
+ subnet_range = subnet.to_range
62
+
63
+ net = subnet
64
+
65
+ subnet_range.count.times do
66
+ this_ip = net.to_s
67
+
68
+ return this_ip unless allocated.include?(this_ip)
69
+
70
+ net = net.succ
71
+
72
+ unless subnet_range.include?(net.to_s)
73
+ net = subnet
74
+ end
75
+ end
76
+
77
+ raise "No free IP address for subnet #{subnet.inspect}"
78
+ end
79
+
80
+ #
81
+ # Get a set of IPs for a given group. Returns a Set object regardless of
82
+ # whether the group exists or not (it will just be empty).
83
+ #
84
+ def group_ips(name)
85
+ groups[name] || Set.new
86
+ end
87
+
88
+ #
89
+ # Assign one or more ips to a group. This method is additive, so multiple
90
+ # calls will grow the group, not replace it.
91
+ #
92
+ def assign_group_ips(name, *ips)
93
+ group = group_ips(name)
94
+
95
+ ips.each do |ip|
96
+ allocated.add(ip)
97
+ group.add(ip)
98
+ end
99
+
100
+ groups[name] = group
101
+
102
+ return ips
103
+ end
104
+
105
+ #
106
+ # Remove a group and free its allocated IP addresses.
107
+ #
108
+ def decommission_group(name)
109
+ group = group_ips(name)
110
+
111
+ group.each do |ip|
112
+ allocated.delete(ip)
113
+ end
114
+
115
+ groups.delete(name)
116
+
117
+ return name
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,51 @@
1
+ require 'furnish/ip'
2
+ require 'set'
3
+
4
+ module Furnish # :nodoc:
5
+ module Provisioner # :nodoc:
6
+ #
7
+ # The AutoIP provisioner is used to create IP addresses for other systems
8
+ # that allow them as direct input, such as VirtualBox VMs. The expectation
9
+ # is that this will be chained to another provisioner who would accept it
10
+ # as input during startup.
11
+ #
12
+ class AutoIP
13
+ ##
14
+ # The name of the provisioner group, set at scheduling time.
15
+ attr_accessor :name
16
+
17
+ ##
18
+ # Create the provisioner. Takes a Furnish::IP object that has subnet
19
+ # semantics (see Furnish::IP#new for more information) and a number of
20
+ # addresses to allocate, default 1.
21
+ def initialize(ip, number_of_addresses=1)
22
+ @ip = ip
23
+ @number_of_addresses = number_of_addresses
24
+ end
25
+
26
+ ##
27
+ # Allocate addresses and forward them on to the next provisioner. Uses
28
+ # the provisioner group name as the key for the address set.
29
+ def startup(*args)
30
+ @number_of_addresses.times do
31
+ @ip.assign_group_ips(name, @ip.unused_ip)
32
+ end
33
+
34
+ return @ip.group_ips(name)
35
+ end
36
+
37
+ ##
38
+ # Release the IP addresses back to the allocator.
39
+ def shutdown
40
+ @ip.decommission_group(name)
41
+ return true
42
+ end
43
+
44
+ ##
45
+ # Display the allocated addresses for this group.
46
+ def report
47
+ @ip.group_ips(name).to_a
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,50 @@
1
+ require 'furnish/ip'
2
+ require 'set'
3
+
4
+ module Furnish # :nodoc:
5
+ module Provisioner # :nodoc:
6
+ #
7
+ # Static Provisioner against the Furnish::IP registry.
8
+ #
9
+ class IP
10
+ ##
11
+ # The name of the provisioner group, set at scheduling time.
12
+ attr_accessor :name
13
+
14
+ ##
15
+ #
16
+ # Create the provisioner. Takes a Furnish::IP object, and uses no
17
+ # auto-allocation features.
18
+ #
19
+ def initialize(ip)
20
+ @ip = ip
21
+ end
22
+
23
+ ##
24
+ # Allocate the results passed to the argument list (presumably from a
25
+ # previously-run provisioner) in a Furnish::IP group named after the name
26
+ # of the provisioning group.
27
+ #
28
+ # Returns the set of IP addresses.
29
+ #
30
+ def startup(*args)
31
+ @ip.assign_group_ips(name, *args.flatten)
32
+ return @ip.group_ips(name)
33
+ end
34
+
35
+ ##
36
+ # Releases the allocated addresses.
37
+ #
38
+ def shutdown
39
+ @ip.decommission_group(name)
40
+ return true
41
+ end
42
+
43
+ ##
44
+ # Display the allocated addresses for this group.
45
+ def report
46
+ @ip.group_ips(name).to_a
47
+ end
48
+ end
49
+ end
50
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/setup'
2
+
3
+ if ENV["COVERAGE"]
4
+ require 'simplecov'
5
+ SimpleCov.start do
6
+ add_filter '/test/'
7
+ end
8
+ end
9
+
10
+ require 'minitest/unit'
11
+ require 'tempfile'
12
+ require 'furnish'
13
+ require 'furnish/ip'
14
+ require 'furnish/provisioners/ip'
15
+ require 'furnish/provisioners/auto_ip'
16
+ require 'mt_cases'
17
+
18
+ require 'minitest/autorun'
data/test/mt_cases.rb ADDED
@@ -0,0 +1,50 @@
1
+ # FIXME copied from the furnish repo, should be a first-class thing in the furnish gem others can consume.
2
+ module Furnish
3
+ class TestCase < MiniTest::Unit::TestCase
4
+ def setup
5
+ @tempfiles ||= []
6
+ file = Tempfile.new('furnish_db')
7
+ @tempfiles.push(file)
8
+ logfile = Tempfile.new('furnish_log')
9
+ @tempfiles.push(logfile)
10
+ Furnish.logger = Furnish::Logger.new(logfile, 3)
11
+ Furnish.init(file.path)
12
+ return file
13
+ end
14
+
15
+ def teardown
16
+ Furnish.logger.close
17
+ Furnish.shutdown
18
+ @tempfiles.each do |file|
19
+ file.unlink
20
+ end
21
+ end
22
+ end
23
+
24
+ class SchedulerTestCase < TestCase
25
+ attr_reader :sched
26
+
27
+ def setup
28
+ super
29
+ @sched = Furnish::Scheduler.new
30
+ @monitor = Thread.new { loop { @sched.running?; sleep 1 } }
31
+ @monitor.abort_on_exception = true
32
+ @sched.run
33
+ end
34
+
35
+ def teardown
36
+ @sched.stop
37
+ sleep 0.3 while @sched.running?
38
+ @monitor.kill rescue nil
39
+ super
40
+ end
41
+
42
+ def assert_solved(name)
43
+ assert_includes(sched.vm.solved, name, "#{name} is solved in the scheduler")
44
+ end
45
+
46
+ def refute_solved(name)
47
+ refute_includes(sched.vm.solved, name, "#{name} is solved in the scheduler")
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,54 @@
1
+ require 'helper'
2
+
3
+ class TestAutoIPProvisioner < Furnish::SchedulerTestCase
4
+ def setup
5
+ super
6
+ @ip = Furnish::IP.new("127.0.0.1/24")
7
+ end
8
+
9
+ def make_provisioner(num=1)
10
+ Furnish::Provisioner::AutoIP.new(@ip, num)
11
+ end
12
+
13
+ def test_basic_provision
14
+ provisioner = make_provisioner
15
+ sched.schedule_provision("test1", provisioner, [])
16
+ sched.wait_for("test1")
17
+
18
+ assert_solved("test1")
19
+
20
+ assert_equal(1, @ip.group_ips("test1").count, "one IP was allocated")
21
+ assert_equal(1, @ip.allocated.count, "reflected in the allocation count")
22
+
23
+ first_ip = @ip.group_ips("test1").first
24
+
25
+ assert_equal("test1", provisioner.name, "name reflects provisioner name")
26
+ assert_equal([first_ip], provisioner.report, "report reflects provisioned IPs")
27
+
28
+ sched.schedule_provision("test2", make_provisioner(10), [])
29
+ sched.wait_for("test2")
30
+
31
+ assert_solved("test2")
32
+
33
+ assert_equal(10, @ip.group_ips("test2").count, "ten new ips were allocated to the test2 provisioning group")
34
+ assert_equal(11, @ip.allocated.count, "a total of 11 IPs are allocated now, across the two groups")
35
+
36
+ sched.teardown_group("test1")
37
+
38
+ refute_solved("test1")
39
+ assert_equal(0, @ip.group_ips("test1").count, "deprovisioning deallocates the IP group")
40
+ assert_equal(10, @ip.allocated.count, "ten IPs now, reflecting the loss of the one in this group")
41
+
42
+ sched.teardown_group("test2")
43
+
44
+ refute_solved("test2")
45
+ assert_equal(0, @ip.group_ips("test2").count, "deprovisioning deallocates the IP group")
46
+ assert_equal(0, @ip.allocated.count, "no IPs left in allocation group")
47
+
48
+ sched.schedule_provision("test1", make_provisioner, [])
49
+ sched.wait_for("test1")
50
+
51
+ assert_solved("test1")
52
+ assert_equal(first_ip, @ip.group_ips("test1").first, "provisioner re-uses deprovisioned IP addresses")
53
+ end
54
+ end
@@ -0,0 +1,78 @@
1
+ require 'helper'
2
+
3
+ class TestIPLib < Furnish::TestCase
4
+ def test_constructor
5
+ ip = Furnish::IP.new("127.0.0.1/24")
6
+ assert_equal("default", ip.name, "default name is 'default'")
7
+ assert_equal(IPAddr.new("127.0.0.1/24"), ip.subnet, "string subnet is cast to IPAddr")
8
+
9
+ ip = Furnish::IP.new(IPAddr.new("127.0.0.1/24"), "foo")
10
+ assert_equal("foo", ip.name, "when second argument is supplied, changes name")
11
+ assert_equal(IPAddr.new("127.0.0.1/24"), ip.subnet, "IPAddr is just accepted as an argument")
12
+
13
+ ip = Furnish::IP.new
14
+ assert_nil(ip.subnet, "subnet was not cast without provided subnet")
15
+ end
16
+
17
+ def test_unused_ip
18
+ ip = Furnish::IP.new(IPAddr.new("127.0.0.1/24"))
19
+ assert_equal("127.0.0.0", ip.unused_ip, "picks the next available ip")
20
+ assert_equal("127.0.0.0", ip.unused_ip, "has no side effects -- returns the same IP on the second call")
21
+
22
+ ip.allocated.add("127.0.0.0") # add something to get it to choose the next thing.
23
+
24
+ assert_equal("127.0.0.1", ip.unused_ip, "picks the next unavailable ip")
25
+
26
+ ip = Furnish::IP.new
27
+ assert_raises(ArgumentError, "Furnish::IP#unused_ip requires an IPAddr object to work") { ip.unused_ip }
28
+ end
29
+
30
+ def test_cycle_detection
31
+ ip = Furnish::IP.new(IPAddr.new("127.0.0.1/31"))
32
+
33
+ 2.times { ip.assign_group_ips("test", ip.unused_ip) }
34
+
35
+ assert_raises(RuntimeError, "No free IP address for subnet #{ip.inspect}") { ip.unused_ip }
36
+ end
37
+
38
+ def test_group_management
39
+ ip = Furnish::IP.new(IPAddr.new("127.0.0.1/24"))
40
+ assert_kind_of(Set, ip.group_ips("foo"), "a non-existent group always returns an empty set")
41
+ assert_empty(ip.group_ips("foo"), "a non-existent group always returns an empty set")
42
+
43
+ allocated = Set.new
44
+
45
+ ip_arg = ip.unused_ip
46
+
47
+ allocated.add(ip_arg)
48
+
49
+ assert_equal(
50
+ [ip_arg],
51
+ ip.assign_group_ips("foo", ip_arg),
52
+ "single argument is return as an array"
53
+ )
54
+
55
+ assert_equal(Set[ip_arg], ip.group_ips("foo"), "returned as set from group_ips")
56
+
57
+ unused_ip = ip.unused_ip
58
+ ip_arg = [unused_ip, unused_ip.succ, unused_ip.succ.succ]
59
+
60
+ ip_arg.each { |i| allocated.add(i) }
61
+
62
+ assert_equal(
63
+ ip_arg,
64
+ ip.assign_group_ips("bar", *ip_arg),
65
+ "array is returned when multiple arguments passed"
66
+ )
67
+
68
+ assert_equal(Set[*ip_arg], ip.group_ips("bar"), "returned as set from group_ips")
69
+ assert_equal(allocated, allocated & ip.allocated.to_set, "group IPs are in the allocation table")
70
+
71
+ ip.decommission_group("foo")
72
+ ip.decommission_group("bar")
73
+
74
+ assert_empty(ip.group_ips("foo"), "group foo has been deallocated")
75
+ assert_empty(ip.group_ips("bar"), "group bar has been deallocated")
76
+ assert_empty(ip.allocated.to_set, "nothing in the allocation table since deprovisioning groups")
77
+ end
78
+ end
@@ -0,0 +1,77 @@
1
+ require 'helper'
2
+ require 'ipaddr'
3
+
4
+ class IPReturningProvisioner
5
+ attr_accessor :name
6
+
7
+ def initialize(*ips)
8
+ @ips = ips
9
+ end
10
+
11
+ def startup(*args)
12
+ return @ips
13
+ end
14
+
15
+ def shutdown
16
+ return true
17
+ end
18
+
19
+ def report
20
+ @ips
21
+ end
22
+ end
23
+
24
+ class TestIPProvisioner < Furnish::SchedulerTestCase
25
+ def setup
26
+ super
27
+ @ip = Furnish::IP.new
28
+ end
29
+
30
+ def make_provisioner(*ips)
31
+ [
32
+ IPReturningProvisioner.new(*ips),
33
+ Furnish::Provisioner::IP.new(@ip)
34
+ ]
35
+ end
36
+
37
+ def test_basic_provision
38
+ ipaddr = IPAddr.new("127.0.0.1/24")
39
+ ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
40
+ provisioner = make_provisioner(*ips)
41
+
42
+ sched.schedule_provision("test1", provisioner, [])
43
+ sched.wait_for("test1")
44
+
45
+ count = ips.count
46
+
47
+ assert_solved("test1")
48
+ assert_equal(count, @ip.group_ips("test1").count, "#{count} IPs were allocated")
49
+ assert_equal(count, @ip.allocated.count, "#{count} IPs were allocated")
50
+
51
+ assert_equal("test1", provisioner.last.name, "name reflects group name")
52
+ assert_equal(ips, provisioner.last.report, "report reflects ip list")
53
+
54
+ ips = (0..4).map { ipaddr = ipaddr.succ; ipaddr.to_s }
55
+ provisioner = make_provisioner(*ips)
56
+ count += ips.count
57
+
58
+ sched.schedule_provision("test2", provisioner, [])
59
+ sched.wait_for("test2")
60
+
61
+ assert_solved("test2")
62
+ assert_equal(ips.count, @ip.group_ips("test2").count, "#{ips.count} IPs were allocated")
63
+ assert_equal(count, @ip.allocated.count, "between both groups, #{count} IPs were allocated")
64
+
65
+ count -= ips.count
66
+
67
+ sched.teardown_group("test2")
68
+
69
+ refute_solved("test2")
70
+ assert_empty(@ip.group_ips("test2"), "torn down group is empty")
71
+ assert_equal(count, @ip.allocated.count, "count is correct (#{count}) after deprovisioning one group")
72
+
73
+ sched.teardown_group("test1")
74
+ assert_empty(@ip.group_ips("test1"), "torn down group is empty")
75
+ assert_equal(0, @ip.allocated.count, "count is zero after deprovisioning all groups")
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,210 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: furnish-ip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Erik Hollensbe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: furnish
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.0.1
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.0.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: palsy
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.0.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.0.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 4.5.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 4.5.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard-minitest
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rdoc
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-fsevent
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: simplecov
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ description: Generic IP allocator for the Furnish provisioning system
159
+ email:
160
+ - erik+github@hollensbe.org
161
+ executables: []
162
+ extensions: []
163
+ extra_rdoc_files: []
164
+ files:
165
+ - .gitignore
166
+ - Gemfile
167
+ - Guardfile
168
+ - LICENSE.txt
169
+ - README.md
170
+ - Rakefile
171
+ - furnish-ip.gemspec
172
+ - lib/furnish/ip.rb
173
+ - lib/furnish/ip/version.rb
174
+ - lib/furnish/provisioners/auto_ip.rb
175
+ - lib/furnish/provisioners/ip.rb
176
+ - test/helper.rb
177
+ - test/mt_cases.rb
178
+ - test/test_auto_ip_provisioner.rb
179
+ - test/test_ip_lib.rb
180
+ - test/test_ip_provisioner.rb
181
+ homepage: ''
182
+ licenses: []
183
+ post_install_message:
184
+ rdoc_options: []
185
+ require_paths:
186
+ - lib
187
+ required_ruby_version: !ruby/object:Gem::Requirement
188
+ none: false
189
+ requirements:
190
+ - - ! '>='
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ required_rubygems_version: !ruby/object:Gem::Requirement
194
+ none: false
195
+ requirements:
196
+ - - ! '>='
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ requirements: []
200
+ rubyforge_project:
201
+ rubygems_version: 1.8.25
202
+ signing_key:
203
+ specification_version: 3
204
+ summary: Generic IP allocator for the Furnish provisioning system
205
+ test_files:
206
+ - test/helper.rb
207
+ - test/mt_cases.rb
208
+ - test/test_auto_ip_provisioner.rb
209
+ - test/test_ip_lib.rb
210
+ - test/test_ip_provisioner.rb