furnish-ip 0.1.0 → 0.2.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.
- checksums.yaml +6 -14
- data/CHANGELOG.md +5 -0
- data/README.md +8 -3
- data/furnish-ip.gemspec +1 -1
- data/lib/furnish/ip.rb +6 -142
- data/lib/furnish/ip/version.rb +3 -2
- data/lib/furnish/port.rb +10 -0
- data/lib/furnish/provisioners/auto_ip.rb +3 -3
- data/lib/furnish/provisioners/ip.rb +4 -4
- data/lib/furnish/range_set.rb +169 -0
- data/test/test_auto_ip_provisioner.rb +12 -12
- data/test/test_ip_lib.rb +12 -12
- data/test/test_ip_provisioner.rb +11 -11
- metadata +16 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
YTllZWEwMDU2ZDNhZGY3YWIwNWY5MjEyYjgyNDEyMDI0ZDllZTM2ZGVkNzBj
|
10
|
-
YmQ3MmFjOTJiZWMxYzg0MzNiOTNkYjM0YmNiZWQxNWEzZDhkNDUwMDVjNDRj
|
11
|
-
YThmNDZlYjFmZjc2MmE0YmE2MjdjNGEwZWVjYTg2OTIwMTVmY2U=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZmQyYzA3ZjE2M2I2YzQ0MzM3ODVlZjE1MmE5ZDk1YTUxMmVhMGZiOWVkM2U0
|
14
|
-
MGE3MjFhOTIyMTNlODI5NjA2MTU4NWQ1ZjEzNDc3ODcxOGQ4ZWY2MWY4ZGVm
|
15
|
-
OTc2Y2YyZDgwOWI2MWM1Y2VkNjliMGRhZDNhN2NiYmNhMWNmZDE=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ae2b7f6a9a956d835025a4511039237a3146583
|
4
|
+
data.tar.gz: 81a04a106c02e6c9cdab500831618d6eb5e9ef50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d01f9db27c11ba7b63d9cb98e0ced564ffd8efb4ffd9ee04aa2ba97e4d661d9dac3da068b0a92c63c741a7347a29c4caa87c93a016c905291de8d8feefbb4e2b
|
7
|
+
data.tar.gz: 82d29e0d7311b3e9890e6c127e77d7ad2afda8f9f619df264127a174cf8f46e8664b4a7959cda57cbb66aa5ce602d8b3bc168333010b420a196c68d7481c3c3f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
* 0.2.0 (05/1/2013)
|
2
|
+
* Most of Furnish::IP was moved to Furnish::RangeSet, which is basically the
|
3
|
+
same thing only without the IP limitation.
|
4
|
+
* Furnish::Port was created, which is quite literally Furnish::RangeSet.
|
5
|
+
* This release is pretty experimental and likely shouldn't be used.
|
1
6
|
* 0.1.0 (04/10/2013)
|
2
7
|
* Now supports Furnish 0.1.0, include protocol and property definitions and
|
3
8
|
all Provisioners inherit from Furnish::Provisioner::API. Recovery is still
|
data/README.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# Furnish::IP
|
2
2
|
|
3
|
-
This provides
|
4
|
-
|
5
|
-
* Furnish::
|
3
|
+
This provides 5 classes:
|
4
|
+
|
5
|
+
* Furnish::RangeSet, a registry that takes its values from a range for
|
6
|
+
allocation purposes.
|
7
|
+
* Furnish::IP, a simple class to maintain a grouped IP registry, derived from
|
8
|
+
RangeSet.
|
9
|
+
* Furnish::Port, a simple class to maintain a grouped Port registry, also
|
10
|
+
derived from RangeSet.
|
6
11
|
* Furnish::Provisioner::IP, a furnish provisioner intended to be chained to
|
7
12
|
resources that allocate their own IP addresses for recording purposes.
|
8
13
|
* Furnish::Provisioner::AutoIP, a furnish provisioner that works against a
|
data/furnish-ip.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.add_dependency 'palsy', '~> 0.0.4'
|
22
22
|
|
23
23
|
gem.add_development_dependency 'rake'
|
24
|
-
gem.add_development_dependency 'minitest', '~> 4.
|
24
|
+
gem.add_development_dependency 'minitest', '~> 4.7'
|
25
25
|
gem.add_development_dependency 'guard-minitest'
|
26
26
|
gem.add_development_dependency 'guard-rake', '~> 0.0.8'
|
27
27
|
gem.add_development_dependency 'rdoc', '~> 4'
|
data/lib/furnish/ip.rb
CHANGED
@@ -1,27 +1,16 @@
|
|
1
1
|
require 'ipaddr'
|
2
|
-
require '
|
2
|
+
require 'furnish/range_set'
|
3
3
|
|
4
4
|
module Furnish # :nodoc:
|
5
|
-
|
6
5
|
#
|
7
6
|
# Furnish::IP maintains a saved registry of IP allocations, and can be
|
8
7
|
# instantiated any time after Furnish is.
|
9
8
|
#
|
10
|
-
class IP
|
11
|
-
|
9
|
+
class IP < RangeSet
|
12
10
|
##
|
13
11
|
# the subnet being worked over as an IPAddr object.
|
12
|
+
#
|
14
13
|
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
14
|
|
26
15
|
#
|
27
16
|
# Instantiate a new IP registry.
|
@@ -40,34 +29,8 @@ module Furnish # :nodoc:
|
|
40
29
|
subnet = IPAddr.new(subnet) unless subnet.kind_of?(IPAddr)
|
41
30
|
end
|
42
31
|
|
43
|
-
@subnet
|
44
|
-
|
45
|
-
@allocated = Palsy::Set.new('furnish_ip_allocations', name)
|
46
|
-
@groups = Palsy::Map.new('furnish_ip_groups', name)
|
47
|
-
end
|
48
|
-
|
49
|
-
#
|
50
|
-
# Allocates an IP without putting it in a group. Useful for placeholders.
|
51
|
-
#
|
52
|
-
# Makes no attempt to check if something's allocated already.
|
53
|
-
#
|
54
|
-
|
55
|
-
def allocate(ip)
|
56
|
-
allocated.add(ip.encode("UTF-8"))
|
57
|
-
end
|
58
|
-
|
59
|
-
#
|
60
|
-
# Deallocates IPs from the global allocation pool. Always succeeds.
|
61
|
-
#
|
62
|
-
def deallocate(ip)
|
63
|
-
allocated.delete(ip.encode("UTF-8"))
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
# Predicate to determine whether or not an IP is already allocated.
|
68
|
-
#
|
69
|
-
def allocated?(ip)
|
70
|
-
allocated.include?(ip.encode("UTF-8"))
|
32
|
+
@subnet = subnet
|
33
|
+
super(subnet ? subnet.to_range : (0..0), "ip", name)
|
71
34
|
end
|
72
35
|
|
73
36
|
#
|
@@ -84,106 +47,7 @@ module Furnish # :nodoc:
|
|
84
47
|
raise ArgumentError, "#{self.class}#unused_ip requires an IPAddr object to work"
|
85
48
|
end
|
86
49
|
|
87
|
-
|
88
|
-
|
89
|
-
net = subnet
|
90
|
-
|
91
|
-
subnet_range.count.times do
|
92
|
-
this_ip = net.to_s.encode("UTF-8")
|
93
|
-
|
94
|
-
begin
|
95
|
-
unless allocated.include?(this_ip)
|
96
|
-
return name ? assign_group_ips(name, this_ip, true).first : this_ip
|
97
|
-
end
|
98
|
-
rescue
|
99
|
-
end
|
100
|
-
|
101
|
-
net = net.succ
|
102
|
-
|
103
|
-
unless subnet_range.include?(net.to_s)
|
104
|
-
net = subnet
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
raise "No free IP address for subnet #{subnet.inspect}"
|
109
|
-
end
|
110
|
-
|
111
|
-
#
|
112
|
-
# Get a set of IPs for a given group. Returns a Set object regardless of
|
113
|
-
# whether the group exists or not (it will just be empty).
|
114
|
-
#
|
115
|
-
def group_ips(name)
|
116
|
-
groups[name] || Set.new
|
117
|
-
end
|
118
|
-
|
119
|
-
#
|
120
|
-
# Overwrite a group for name with a given group.
|
121
|
-
#
|
122
|
-
def replace_group(name, group)
|
123
|
-
groups[name] = group
|
124
|
-
end
|
125
|
-
|
126
|
-
#
|
127
|
-
# Assign one or more ips to a group. This method is additive, so multiple
|
128
|
-
# calls will grow the group, not replace it.
|
129
|
-
#
|
130
|
-
def assign_group_ips(name, ips, raise_if_exists=false)
|
131
|
-
group = group_ips(name)
|
132
|
-
|
133
|
-
if ips.kind_of?(Array)
|
134
|
-
ips = Set[*ips]
|
135
|
-
elsif !ips.kind_of?(Set)
|
136
|
-
ips = Set[ips]
|
137
|
-
end
|
138
|
-
|
139
|
-
c_allocated = allocated.count
|
140
|
-
c_group = group.count
|
141
|
-
|
142
|
-
ips.each do |ip|
|
143
|
-
utf8_ip = ip.encode("UTF-8")
|
144
|
-
allocated.add(utf8_ip)
|
145
|
-
group.add(utf8_ip)
|
146
|
-
end
|
147
|
-
|
148
|
-
if raise_if_exists
|
149
|
-
raise unless group.count == c_group + ips.count && allocated.count == c_allocated + ips.count
|
150
|
-
end
|
151
|
-
|
152
|
-
replace_group(name, group)
|
153
|
-
|
154
|
-
return ips
|
155
|
-
end
|
156
|
-
|
157
|
-
#
|
158
|
-
# Remove the IPs from the group provided by name, also deallocates them.
|
159
|
-
#
|
160
|
-
def remove_from_group(name, ips)
|
161
|
-
group = group_ips(name)
|
162
|
-
|
163
|
-
ips.each do |ip|
|
164
|
-
utf8_ip = ip.encode("UTF-8")
|
165
|
-
deallocate(utf8_ip)
|
166
|
-
group.delete(utf8_ip)
|
167
|
-
end
|
168
|
-
|
169
|
-
replace_group(name, group)
|
170
|
-
|
171
|
-
return ips
|
172
|
-
end
|
173
|
-
|
174
|
-
#
|
175
|
-
# Remove a group and free its allocated IP addresses.
|
176
|
-
#
|
177
|
-
def decommission_group(name)
|
178
|
-
group = group_ips(name)
|
179
|
-
|
180
|
-
group.each do |ip|
|
181
|
-
deallocate(ip)
|
182
|
-
end
|
183
|
-
|
184
|
-
groups.delete(name)
|
185
|
-
|
186
|
-
return name
|
50
|
+
unused(name)
|
187
51
|
end
|
188
52
|
end
|
189
53
|
end
|
data/lib/furnish/ip/version.rb
CHANGED
data/lib/furnish/port.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'furnish/range_set'
|
2
|
+
|
3
|
+
module Furnish # :nodoc:
|
4
|
+
#
|
5
|
+
# Furnish::Port is similar to Furnish::IP and maintains a registry of port
|
6
|
+
# allocations for a given host. It does not have any different API from
|
7
|
+
# RangeSet, it merely exists as a nicety.
|
8
|
+
#
|
9
|
+
Port = RangeSet
|
10
|
+
end
|
@@ -67,7 +67,7 @@ module Furnish # :nodoc:
|
|
67
67
|
@controlled_ips.add(this_ip)
|
68
68
|
end
|
69
69
|
|
70
|
-
return({ :ips => ip.
|
70
|
+
return({ :ips => ip.group_items(furnish_group_name) })
|
71
71
|
end
|
72
72
|
|
73
73
|
##
|
@@ -80,7 +80,7 @@ module Furnish # :nodoc:
|
|
80
80
|
ip.remove_from_group(furnish_group_name, @controlled_ips)
|
81
81
|
end
|
82
82
|
|
83
|
-
if ip.
|
83
|
+
if ip.group_items(furnish_group_name).empty?
|
84
84
|
ip.decommission_group(furnish_group_name)
|
85
85
|
end
|
86
86
|
|
@@ -90,7 +90,7 @@ module Furnish # :nodoc:
|
|
90
90
|
##
|
91
91
|
# Display the allocated addresses for this group.
|
92
92
|
def report
|
93
|
-
ip.
|
93
|
+
ip.group_items(furnish_group_name).to_a rescue []
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -46,8 +46,8 @@ module Furnish # :nodoc:
|
|
46
46
|
#
|
47
47
|
def startup(args={})
|
48
48
|
@controlled_ips = args[:ips]
|
49
|
-
ip.
|
50
|
-
return({ :ips => ip.
|
49
|
+
ip.assign_group_items(furnish_group_name, @controlled_ips)
|
50
|
+
return({ :ips => ip.group_items(furnish_group_name) })
|
51
51
|
end
|
52
52
|
|
53
53
|
##
|
@@ -58,7 +58,7 @@ module Furnish # :nodoc:
|
|
58
58
|
ip.remove_from_group(furnish_group_name, @controlled_ips)
|
59
59
|
end
|
60
60
|
|
61
|
-
if ip.
|
61
|
+
if ip.group_items(furnish_group_name).empty?
|
62
62
|
ip.decommission_group(furnish_group_name)
|
63
63
|
end
|
64
64
|
|
@@ -68,7 +68,7 @@ module Furnish # :nodoc:
|
|
68
68
|
##
|
69
69
|
# Display the allocated addresses for this group.
|
70
70
|
def report
|
71
|
-
ip.
|
71
|
+
ip.group_items(furnish_group_name).to_a rescue []
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Furnish
|
4
|
+
class RangeSet
|
5
|
+
##
|
6
|
+
# the name of the registry.
|
7
|
+
attr_reader :name
|
8
|
+
|
9
|
+
##
|
10
|
+
# A Palsy::Set of the sum of allocated items.
|
11
|
+
attr_reader :allocated
|
12
|
+
|
13
|
+
##
|
14
|
+
# A Palsy::Map of the individual groups of items. Each item yields a
|
15
|
+
# set of string item addresses.
|
16
|
+
attr_reader :groups
|
17
|
+
|
18
|
+
##
|
19
|
+
# The range we're allocating from.
|
20
|
+
attr_reader :range
|
21
|
+
|
22
|
+
##
|
23
|
+
# The type of thing we're allocating. No spaces.
|
24
|
+
attr_reader :allocation_type
|
25
|
+
|
26
|
+
#
|
27
|
+
# Allocate something from a range. Takes a Range object, a type of
|
28
|
+
# allocation (which is coerced into a table name, so be nice!) and
|
29
|
+
# namespace for the allocations.
|
30
|
+
#
|
31
|
+
# See Furnish::item for an example.
|
32
|
+
#
|
33
|
+
def initialize(range, allocation_type, name="default")
|
34
|
+
@range = range
|
35
|
+
@allocation_type = allocation_type
|
36
|
+
@name = name
|
37
|
+
|
38
|
+
@allocated = Palsy::Set.new("furnish_#{allocation_type}_allocations", name)
|
39
|
+
@groups = Palsy::Map.new("furnish_#{allocation_type}_groups", name)
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Get the next unused item. Will raise if the range is exahusted
|
44
|
+
#
|
45
|
+
def unused(name=nil)
|
46
|
+
net = range.first
|
47
|
+
|
48
|
+
range.count.times do
|
49
|
+
this_item = net.to_s.encode("UTF-8")
|
50
|
+
|
51
|
+
begin
|
52
|
+
unless allocated.include?(this_item)
|
53
|
+
return name ? assign_group_items(name, this_item, true).first : this_item
|
54
|
+
end
|
55
|
+
rescue
|
56
|
+
end
|
57
|
+
|
58
|
+
net = net.succ
|
59
|
+
|
60
|
+
unless range.include?(net.to_s)
|
61
|
+
net = range.first
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
raise "No free #{allocation_type} for subnet #{range.inspect}"
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Allocates an item without putting it in a group. Useful for placeholders.
|
70
|
+
#
|
71
|
+
# Makes no attempt to check if something's allocated already.
|
72
|
+
#
|
73
|
+
def allocate(item)
|
74
|
+
allocated.add(item.encode("UTF-8"))
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Deallocates items from the global allocation pool. Always succeeds.
|
79
|
+
#
|
80
|
+
def deallocate(item)
|
81
|
+
allocated.delete(item.encode("UTF-8"))
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Predicate to determine whether or not an item is already allocated.
|
86
|
+
#
|
87
|
+
def allocated?(item)
|
88
|
+
allocated.include?(item.encode("UTF-8"))
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Get a set of items for a given group. Returns a Set object regardless of
|
93
|
+
# whether the group exists or not (it will just be empty).
|
94
|
+
#
|
95
|
+
def group_items(name)
|
96
|
+
groups[name] || Set.new
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# Overwrite a group for name with a given group.
|
101
|
+
#
|
102
|
+
def replace_group(name, group)
|
103
|
+
groups[name] = group
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# Assign one or more items to a group. This method is additive, so multitemle
|
108
|
+
# calls will grow the group, not replace it.
|
109
|
+
#
|
110
|
+
def assign_group_items(name, items, raise_if_exists=false)
|
111
|
+
group = group_items(name)
|
112
|
+
|
113
|
+
if items.kind_of?(Array)
|
114
|
+
items = Set[*items]
|
115
|
+
elsif !items.kind_of?(Set)
|
116
|
+
items = Set[items]
|
117
|
+
end
|
118
|
+
|
119
|
+
c_allocated = allocated.count
|
120
|
+
c_group = group.count
|
121
|
+
|
122
|
+
items.each do |item|
|
123
|
+
utf8_item = item.encode("UTF-8")
|
124
|
+
allocated.add(utf8_item)
|
125
|
+
group.add(utf8_item)
|
126
|
+
end
|
127
|
+
|
128
|
+
if raise_if_exists
|
129
|
+
raise unless group.count == c_group + items.count && allocated.count == c_allocated + items.count
|
130
|
+
end
|
131
|
+
|
132
|
+
replace_group(name, group)
|
133
|
+
|
134
|
+
return items
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Remove the items from the group provided by name, also deallocates them.
|
139
|
+
#
|
140
|
+
def remove_from_group(name, items)
|
141
|
+
group = group_items(name)
|
142
|
+
|
143
|
+
items.each do |item|
|
144
|
+
utf8_item = item.encode("UTF-8")
|
145
|
+
deallocate(utf8_item)
|
146
|
+
group.delete(utf8_item)
|
147
|
+
end
|
148
|
+
|
149
|
+
replace_group(name, group)
|
150
|
+
|
151
|
+
return items
|
152
|
+
end
|
153
|
+
|
154
|
+
#
|
155
|
+
# Remove a group and free its allocated item addresses.
|
156
|
+
#
|
157
|
+
def decommission_group(name)
|
158
|
+
group = group_items(name)
|
159
|
+
|
160
|
+
group.each do |item|
|
161
|
+
deallocate(item)
|
162
|
+
end
|
163
|
+
|
164
|
+
groups.delete(name)
|
165
|
+
|
166
|
+
return name
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -21,11 +21,11 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
21
21
|
def test_properties
|
22
22
|
assert_equal(
|
23
23
|
{
|
24
|
-
|
24
|
+
"ip" => {
|
25
25
|
:description => "A Furnish::IP registry object",
|
26
26
|
:type => Furnish::IP
|
27
27
|
},
|
28
|
-
|
28
|
+
"number_of_addresses" => {
|
29
29
|
:description => "An integer indicating the number of addresses to generate",
|
30
30
|
:type => Integer
|
31
31
|
}
|
@@ -61,10 +61,10 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
61
61
|
|
62
62
|
assert_solved("test1")
|
63
63
|
|
64
|
-
assert_equal(1, @ip.
|
64
|
+
assert_equal(1, @ip.group_items("test1").count, "one IP was allocated")
|
65
65
|
assert_equal(1, @ip.allocated.count, "reflected in the allocation count")
|
66
66
|
|
67
|
-
first_ip = @ip.
|
67
|
+
first_ip = @ip.group_items("test1").first
|
68
68
|
|
69
69
|
assert_equal("test1", provisioner.furnish_group_name, "name reflects provisioner name")
|
70
70
|
assert_equal([first_ip], provisioner.report, "report reflects provisioned IPs")
|
@@ -74,26 +74,26 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
74
74
|
|
75
75
|
assert_solved("test2")
|
76
76
|
|
77
|
-
assert_equal(10, @ip.
|
77
|
+
assert_equal(10, @ip.group_items("test2").count, "ten new ips were allocated to the test2 provisioning group")
|
78
78
|
assert_equal(11, @ip.allocated.count, "a total of 11 IPs are allocated now, across the two groups")
|
79
79
|
|
80
80
|
sched.teardown_group("test1")
|
81
81
|
|
82
82
|
refute_solved("test1")
|
83
|
-
assert_equal(0, @ip.
|
83
|
+
assert_equal(0, @ip.group_items("test1").count, "deprovisioning deallocates the IP group")
|
84
84
|
assert_equal(10, @ip.allocated.count, "ten IPs now, reflecting the loss of the one in this group")
|
85
85
|
|
86
86
|
sched.teardown_group("test2")
|
87
87
|
|
88
88
|
refute_solved("test2")
|
89
|
-
assert_equal(0, @ip.
|
89
|
+
assert_equal(0, @ip.group_items("test2").count, "deprovisioning deallocates the IP group")
|
90
90
|
assert_equal(0, @ip.allocated.count, "no IPs left in allocation group")
|
91
91
|
|
92
92
|
sched.schedule_provision("test1", make_provisioner, [])
|
93
93
|
sched.wait_for("test1")
|
94
94
|
|
95
95
|
assert_solved("test1")
|
96
|
-
assert_equal(first_ip, @ip.
|
96
|
+
assert_equal(first_ip, @ip.group_items("test1").first, "provisioner re-uses deprovisioned IP addresses")
|
97
97
|
end
|
98
98
|
|
99
99
|
def test_multi_provision
|
@@ -105,8 +105,8 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
105
105
|
sched.wait_for("first", "second")
|
106
106
|
assert_solved("first")
|
107
107
|
assert_solved("second")
|
108
|
-
assert_equal(5, @ip.
|
109
|
-
assert_equal(5, @ip.
|
108
|
+
assert_equal(5, @ip.group_items("first").count)
|
109
|
+
assert_equal(5, @ip.group_items("second").count)
|
110
110
|
assert_equal(10, @ip.allocated.count)
|
111
111
|
|
112
112
|
sched.deprovision_group("first")
|
@@ -119,10 +119,10 @@ class TestAutoIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
119
119
|
|
120
120
|
sched.s("both", [first, second])
|
121
121
|
sched.wait_for("both")
|
122
|
-
assert_equal(10, @ip.
|
122
|
+
assert_equal(10, @ip.group_items("both").count)
|
123
123
|
assert_equal(10, @ip.allocated.count)
|
124
124
|
sched.teardown
|
125
|
-
assert_equal(0, @ip.
|
125
|
+
assert_equal(0, @ip.group_items("both").count)
|
126
126
|
assert_equal(0, @ip.allocated.count)
|
127
127
|
end
|
128
128
|
end
|
data/test/test_ip_lib.rb
CHANGED
@@ -38,8 +38,8 @@ class TestIPLib < Furnish::TestCase
|
|
38
38
|
ip.allocate("127.0.0.42".encode("ASCII-8BIT"))
|
39
39
|
assert(ip.allocated?("127.0.0.42".encode("UTF-8")), "127.0.0.42 was allocated encoding-agnostic")
|
40
40
|
|
41
|
-
ip.
|
42
|
-
assert_equal("UTF-8", ip.
|
41
|
+
ip.assign_group_items("foo", "127.0.0.23".encode("ASCII-8BIT"))
|
42
|
+
assert_equal("UTF-8", ip.group_items("foo").first.encoding.to_s, "encoding always comes back UTF-8")
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_allocated
|
@@ -47,7 +47,7 @@ class TestIPLib < Furnish::TestCase
|
|
47
47
|
ip.allocate("127.0.0.0")
|
48
48
|
assert(ip.allocated?("127.0.0.0"), "127.0.0.0 is allocated")
|
49
49
|
|
50
|
-
ip.
|
50
|
+
ip.assign_group_items("foo", "127.0.0.1")
|
51
51
|
|
52
52
|
assert(ip.allocated?("127.0.0.1"), "127.0.0.1 is allocated by way of a group")
|
53
53
|
end
|
@@ -55,15 +55,15 @@ class TestIPLib < Furnish::TestCase
|
|
55
55
|
def test_cycle_detection
|
56
56
|
ip = Furnish::IP.new(IPAddr.new("127.0.0.1/31"))
|
57
57
|
|
58
|
-
2.times { ip.
|
58
|
+
2.times { ip.assign_group_items("test", ip.unused_ip) }
|
59
59
|
|
60
60
|
assert_raises(RuntimeError, "No free IP address for subnet #{ip.inspect}") { ip.unused_ip }
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_group_management
|
64
64
|
ip = Furnish::IP.new(IPAddr.new("127.0.0.1/24"))
|
65
|
-
assert_kind_of(Set, ip.
|
66
|
-
assert_empty(ip.
|
65
|
+
assert_kind_of(Set, ip.group_items("foo"), "a non-existent group always returns an empty set")
|
66
|
+
assert_empty(ip.group_items("foo"), "a non-existent group always returns an empty set")
|
67
67
|
|
68
68
|
allocated = Set.new
|
69
69
|
|
@@ -73,11 +73,11 @@ class TestIPLib < Furnish::TestCase
|
|
73
73
|
|
74
74
|
assert_equal(
|
75
75
|
Set[ip_arg],
|
76
|
-
ip.
|
76
|
+
ip.assign_group_items("foo", ip_arg),
|
77
77
|
"single argument is returned as a set"
|
78
78
|
)
|
79
79
|
|
80
|
-
assert_equal(Set[ip_arg], ip.
|
80
|
+
assert_equal(Set[ip_arg], ip.group_items("foo"), "returned as set from group_items")
|
81
81
|
|
82
82
|
unused_ip = ip.unused_ip
|
83
83
|
ip_arg = Set[unused_ip, unused_ip.succ, unused_ip.succ.succ]
|
@@ -86,18 +86,18 @@ class TestIPLib < Furnish::TestCase
|
|
86
86
|
|
87
87
|
assert_equal(
|
88
88
|
ip_arg,
|
89
|
-
ip.
|
89
|
+
ip.assign_group_items("bar", ip_arg.to_a),
|
90
90
|
"set is returned when array passed"
|
91
91
|
)
|
92
92
|
|
93
|
-
assert_equal(Set[*ip_arg], ip.
|
93
|
+
assert_equal(Set[*ip_arg], ip.group_items("bar"), "returned as set from group_items")
|
94
94
|
assert_equal(allocated, allocated & ip.allocated.to_set, "group IPs are in the allocation table")
|
95
95
|
|
96
96
|
ip.decommission_group("foo")
|
97
97
|
ip.decommission_group("bar")
|
98
98
|
|
99
|
-
assert_empty(ip.
|
100
|
-
assert_empty(ip.
|
99
|
+
assert_empty(ip.group_items("foo"), "group foo has been deallocated")
|
100
|
+
assert_empty(ip.group_items("bar"), "group bar has been deallocated")
|
101
101
|
assert_empty(ip.allocated.to_set, "nothing in the allocation table since deprovisioning groups")
|
102
102
|
end
|
103
103
|
end
|
data/test/test_ip_provisioner.rb
CHANGED
@@ -55,7 +55,7 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
55
55
|
def test_properties
|
56
56
|
assert_equal(
|
57
57
|
{
|
58
|
-
|
58
|
+
"ip" => {
|
59
59
|
:description => "A Furnish::IP registry object",
|
60
60
|
:type => Furnish::IP
|
61
61
|
}
|
@@ -103,7 +103,7 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
103
103
|
count = ips.count
|
104
104
|
|
105
105
|
assert_solved("test1")
|
106
|
-
assert_equal(count, @ip.
|
106
|
+
assert_equal(count, @ip.group_items("test1").count, "#{count} IPs were allocated")
|
107
107
|
assert_equal(count, @ip.allocated.count, "#{count} IPs were allocated")
|
108
108
|
|
109
109
|
assert_equal("test1", provisioner.last.furnish_group_name, "name reflects group name")
|
@@ -117,7 +117,7 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
117
117
|
sched.wait_for("test2")
|
118
118
|
|
119
119
|
assert_solved("test2")
|
120
|
-
assert_equal(ips.count, @ip.
|
120
|
+
assert_equal(ips.count, @ip.group_items("test2").count, "#{ips.count} IPs were allocated")
|
121
121
|
assert_equal(count, @ip.allocated.count, "between both groups, #{count} IPs were allocated")
|
122
122
|
|
123
123
|
count -= ips.count
|
@@ -125,11 +125,11 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
125
125
|
sched.teardown_group("test2")
|
126
126
|
|
127
127
|
refute_solved("test2")
|
128
|
-
assert_empty(@ip.
|
128
|
+
assert_empty(@ip.group_items("test2"), "torn down group is empty")
|
129
129
|
assert_equal(count, @ip.allocated.count, "count is correct (#{count}) after deprovisioning one group")
|
130
130
|
|
131
131
|
sched.teardown_group("test1")
|
132
|
-
assert_empty(@ip.
|
132
|
+
assert_empty(@ip.group_items("test1"), "torn down group is empty")
|
133
133
|
assert_equal(0, @ip.allocated.count, "count is zero after deprovisioning all groups")
|
134
134
|
end
|
135
135
|
|
@@ -143,19 +143,19 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
143
143
|
sched.s("first", first)
|
144
144
|
sched.wait_for("first")
|
145
145
|
assert_solved("first")
|
146
|
-
assert_equal(first_ips.count, @ip.
|
146
|
+
assert_equal(first_ips.count, @ip.group_items("first").count, "#{first_ips.count} IPs were allocated")
|
147
147
|
assert_equal(first_ips.count, @ip.allocated.count, "#{first_ips.count} IPs were allocated")
|
148
148
|
sched.deprovision_group("first")
|
149
|
-
assert_equal(0, @ip.
|
149
|
+
assert_equal(0, @ip.group_items("first").count, "count is zero after deprovision")
|
150
150
|
assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
|
151
151
|
|
152
152
|
sched.s("second", second)
|
153
153
|
sched.wait_for("second")
|
154
154
|
assert_solved("second")
|
155
|
-
assert_equal(second_ips.count, @ip.
|
155
|
+
assert_equal(second_ips.count, @ip.group_items("second").count, "#{second_ips.count} IPs were allocated")
|
156
156
|
assert_equal(second_ips.count, @ip.allocated.count, "#{second_ips.count} IPs were allocated")
|
157
157
|
sched.deprovision_group("second")
|
158
|
-
assert_equal(0, @ip.
|
158
|
+
assert_equal(0, @ip.group_items("second").count, "count is zero after deprovision")
|
159
159
|
assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
|
160
160
|
|
161
161
|
sched.s("test1", first + second)
|
@@ -163,10 +163,10 @@ class TestIPProvisioner < Furnish::RunningSchedulerTestCase
|
|
163
163
|
|
164
164
|
assert_solved("test1")
|
165
165
|
total = first_ips.count + second_ips.count
|
166
|
-
assert_equal(total, @ip.
|
166
|
+
assert_equal(total, @ip.group_items("test1").count, "#{total} IPs were allocated")
|
167
167
|
assert_equal(total, @ip.allocated.count, "#{total} IPs were allocated")
|
168
168
|
sched.deprovision_group("test1")
|
169
|
-
assert_equal(0, @ip.
|
169
|
+
assert_equal(0, @ip.group_items("test1").count, "count is zero after deprovision")
|
170
170
|
assert_equal(0, @ip.allocated.count, "count is zero after deprovision")
|
171
171
|
end
|
172
172
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: furnish-ip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erik Hollensbe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: furnish
|
@@ -42,14 +42,14 @@ dependencies:
|
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
@@ -58,26 +58,26 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 4.
|
61
|
+
version: '4.7'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 4.
|
68
|
+
version: '4.7'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: guard-minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
@@ -112,28 +112,28 @@ dependencies:
|
|
112
112
|
name: rb-fsevent
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - '>='
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: simplecov
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - '>='
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - '>='
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
description: Generic IP allocator for the Furnish provisioning system
|
@@ -153,8 +153,10 @@ files:
|
|
153
153
|
- furnish-ip.gemspec
|
154
154
|
- lib/furnish/ip.rb
|
155
155
|
- lib/furnish/ip/version.rb
|
156
|
+
- lib/furnish/port.rb
|
156
157
|
- lib/furnish/provisioners/auto_ip.rb
|
157
158
|
- lib/furnish/provisioners/ip.rb
|
159
|
+
- lib/furnish/range_set.rb
|
158
160
|
- test/helper.rb
|
159
161
|
- test/test_auto_ip_provisioner.rb
|
160
162
|
- test/test_ip_lib.rb
|
@@ -168,12 +170,12 @@ require_paths:
|
|
168
170
|
- lib
|
169
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
172
|
requirements:
|
171
|
-
- -
|
173
|
+
- - '>='
|
172
174
|
- !ruby/object:Gem::Version
|
173
175
|
version: '0'
|
174
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
177
|
requirements:
|
176
|
-
- -
|
178
|
+
- - '>='
|
177
179
|
- !ruby/object:Gem::Version
|
178
180
|
version: '0'
|
179
181
|
requirements: []
|