furnish-ip 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|