Skip to content

Commit 7af3f4c

Browse files
committed
Support 'local' routes with redhat provider
1 parent 3a1251c commit 7af3f4c

File tree

6 files changed

+86
-9
lines changed

6 files changed

+86
-9
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ network_route { 'default':
8080
netmask => '0.0.0.0',
8181
network => 'default'
8282
}
83+
network_route { '10.0.0.2':
84+
ensure => 'present',
85+
gateway => 'local',
86+
netmask => 'local',
87+
network => 'local',
88+
interface => 'eth0',
89+
options => 'proto 66 scope host table local',
90+
}
8391
```
8492

8593
For SLES:

lib/puppet/provider/network_route/redhat.rb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,25 @@ def self.parse_file(_filename, contents)
4242
route = line.split(' ', 6)
4343
raise Puppet::Error, 'Malformed redhat route file, cannot instantiate network_route resources' if route.length < 4
4444

45+
route = line.split(' ', 5) if route[0] == 'local'
46+
4547
new_route = {}
4648

47-
new_route[:gateway] = route[2]
48-
new_route[:interface] = route[4]
49-
new_route[:options] = route[5] if route[5]
49+
if route[0] == 'local'
50+
new_route[:gateway] = 'local'
51+
new_route[:interface] = route[3]
52+
new_route[:options] = route[4] if route[4]
53+
else
54+
new_route[:gateway] = route[2]
55+
new_route[:interface] = route[4]
56+
new_route[:options] = route[5] if route[5]
57+
end
5058

51-
if ['default', '0.0.0.0'].include? route[0]
59+
if route[0] == 'local'
60+
new_route[:name] = route[1]
61+
new_route[:network] = 'local'
62+
new_route[:netmask] = 'local'
63+
elsif ['default', '0.0.0.0'].include? route[0]
5264
new_route[:name] = 'default' # FIXME: Must match :name in order for changes to be detected
5365
new_route[:network] = 'default'
5466
new_route[:netmask] = '0.0.0.0'
@@ -77,6 +89,8 @@ def self.format_file(_filename, providers)
7789
end
7890
contents << if provider.network == 'default'
7991
"#{provider.network} via #{provider.gateway} dev #{provider.interface}"
92+
elsif provider.network == 'local'
93+
"#{provider.network} #{provider.name} dev #{provider.interface}"
8094
else
8195
ip = IPAddr.new("#{provider.network}/#{provider.netmask}")
8296
"#{ip}/#{ip.prefix} via #{provider.gateway} dev #{provider.interface}"

lib/puppet/type/network_route.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
isrequired
2323
desc 'The target network address'
2424
validate do |value|
25-
unless value == 'default'
25+
unless %w[default local].include?(value)
2626
a = PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) }
2727
raise("Invalid value for parameter 'network': #{value}") unless a
2828
end
@@ -34,12 +34,14 @@
3434
desc 'The subnet mask to apply to the route'
3535

3636
validate do |value|
37-
raise("Invalid value for parameter 'netmask': #{value}") unless value.length <= 3 || PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) }
37+
raise("Invalid value for parameter 'netmask': #{value}") unless value == 'local' || value.length <= 3 || PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) }
3838
end
3939

4040
munge do |value|
41+
if value == 'local'
42+
value
4143
# '255.255.255.255'.to_i will return 255, so we try to convert it back:
42-
if value.to_i.to_s == value
44+
elsif value.to_i.to_s == value
4345
# what are the chances someone is using /16 for their IPv6 network?
4446
addr = value.to_i <= 32 ? '255.255.255.255' : 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
4547
IPAddr.new(addr).mask(value.strip.to_i).to_s
@@ -58,7 +60,7 @@
5860
desc 'The gateway to use for the route'
5961

6062
validate do |value|
61-
IPAddr.new(value)
63+
IPAddr.new(value) unless value == 'local'
6264
rescue ArgumentError
6365
raise("Invalid value for parameter 'gateway': #{value}")
6466
end
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
10.0.0.0/8 via 10.0.0.1 dev eth0
2+
192.168.0.0/16 via 10.0.0.1 table n0-hc
3+
local 10.0.0.2 dev eth0 proto 66 scope host table local

spec/unit/provider/network_route/redhat_spec.rb

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,23 @@ def fixture_data(file)
6969
end
7070
end
7171

72+
describe 'an advanced file using local route' do
73+
let :data do
74+
described_class.parse_file('', fixture_data('local_routes'))
75+
end
76+
77+
it 'parses out normal ipv4 network routes' do
78+
expect(data.find { |h| h[:name] == '10.0.0.2' }).to eq(
79+
name: '10.0.0.2',
80+
network: 'local',
81+
netmask: 'local',
82+
gateway: 'local',
83+
interface: 'eth0',
84+
options: 'proto 66 scope host table local'
85+
)
86+
end
87+
end
88+
7289
describe 'an invalid file' do
7390
it 'fails' do
7491
expect do
@@ -127,8 +144,20 @@ def fixture_data(file)
127144
)
128145
end
129146

147+
let :local_provider do
148+
instance_double(
149+
'local_provider',
150+
name: '10.0.0.2',
151+
network: 'local',
152+
netmask: '',
153+
gateway: 'local',
154+
interface: 'eth0',
155+
options: 'proto 66 scope host table local'
156+
)
157+
end
158+
130159
let :content do
131-
described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider, nooptions_provider])
160+
described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider, nooptions_provider, local_provider])
132161
end
133162

134163
describe 'writing the route line' do
@@ -166,5 +195,11 @@ def fixture_data(file)
166195
expect(content).not_to match(%r{absent})
167196
end
168197
end
198+
199+
describe 'for local routes' do
200+
it 'has local route defined' do
201+
expect(content.scan(%r{^local .*$}).first).to include('local 10.0.0.2 dev eth0 proto 66 scope host table local')
202+
end
203+
end
169204
end
170205
end

spec/unit/type/network_route_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535

3636
describe 'when validating the attribute value' do
3737
describe 'network' do
38+
it 'allows local' do
39+
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: 'local', netmask: '255.255.255.0', gateway: '23.23.23.42', interface: 'eth0')
40+
expect(r[:network]).to eq('local')
41+
end
42+
3843
it 'validates the network as an IP address' do
3944
expect do
4045
Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: 'not an ip address', netmask: '255.255.255.0', gateway: '23.23.23.42', interface: 'eth0')
@@ -63,9 +68,19 @@
6368
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', netmask: '255.255.128.0', gateway: '23.23.23.42', interface: 'eth0')
6469
expect(r[:netmask]).to eq('255.255.128.0')
6570
end
71+
72+
it 'allows local' do
73+
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', netmask: 'local', gateway: '23.23.23.42', interface: 'eth0')
74+
expect(r[:netmask]).to eq('local')
75+
end
6676
end
6777

6878
describe 'gateway' do
79+
it 'allows local' do
80+
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', netmask: '255.255.255.0', gateway: 'local', interface: 'eth0')
81+
expect(r[:gateway]).to eq('local')
82+
end
83+
6984
it 'validates as an IP address' do
7085
expect do
7186
Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', netmask: '255.255.255.0', gateway: 'not an ip address', interface: 'eth0')

0 commit comments

Comments
 (0)