-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelpers_network.rb
118 lines (105 loc) · 3.2 KB
/
helpers_network.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module DockerCookbook
module DockerHelpers
module Network
require 'ipaddr'
###################
# property coersion
###################
def coerce_auxiliary_addresses(v)
ray = []
Array(v).each do |e|
case e
when String, Array, nil
ray += Array(e)
when Hash
e.each { |key, val| ray << "#{key}=#{val}" }
end
end
ray.length == 1 ? ray[0] : ray
end
def coerce_gateway(v)
case v
when String
v.split('/')[0]
when Array
ray = Array(v).map { |a| a.split('/')[0] }
ray.length == 1 ? ray[0] : ray
end
end
def coerce_subnet(v)
Array(v).length == 1 ? Array(v)[0] : v
end
def coerce_ip_range(v)
Array(v).length == 1 ? Array(v)[0] : v
end
######
# IPAM
######
def consolidate_ipam(subnets, ranges, gateways, auxaddrs)
subnets = Array(subnets)
ranges = Array(ranges)
gateways = Array(gateways)
auxaddrs = Array(auxaddrs)
subnets = [] if subnets.empty?
ranges = [] if ranges.empty?
gateways = [] if gateways.empty?
auxaddrs = [] if auxaddrs.empty?
if subnets.size < ranges.size || subnets.size < gateways.size
raise 'every ip-range or gateway myust have a corresponding subnet'
end
data = {}
# Check overlapping subnets
subnets.each do |s|
data.each do |k, _|
if subnet_matches(s, k) || subnet_matches(k, s)
raise 'multiple overlapping subnet configuration is not supported'
end
end
data[s] = { 'Subnet' => s, 'AuxiliaryAddresses' => {} }
end
ranges.each do |r|
match = false
subnets.each do |s|
ok = subnet_matches(s, r)
next unless ok
if data[s].fetch('IPRange', '') != ''
raise 'cannot configure multiple ranges on the same subnet'
end
data[s]['IPRange'] = r
match = true
end
raise "no matching subnet for range #{r}" unless match
end
gateways.each do |g|
match = false
subnets.each do |s|
ok = subnet_matches(s, g)
next unless ok
unless data[s].fetch('Gateway', '').empty?
raise "cannot configure multiple gateways (#{g}, #{data[s]['Gateway']}) for the same subnet (#{s})"
end
data[s]['Gateway'] = g
match = true
end
raise "no matching subnet for gateway #{s}" unless match
end
auxaddrs.each do |aa|
key, a = aa.split('=')
match = false
subnets.each do |s|
# require 'pry' ; binding.pry
ok = subnet_matches(s, a)
next unless ok
data[s]['AuxiliaryAddresses'][key] = a
match = true
end
raise "no matching subnet for aux-address #{a}" unless match
end
data.values
end
def subnet_matches(subnet, data)
IPAddr.new(subnet).include?(IPAddr.new(data))
end
end
end
end