Skip to content

Commit

Permalink
Support 'local' routes with redhat provider
Browse files Browse the repository at this point in the history
  • Loading branch information
treydock committed Nov 30, 2023
1 parent 3a1251c commit a80db8c
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 9 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ network_route { 'default':
netmask => '0.0.0.0',
network => 'default'
}
network_route { '10.0.0.2':
ensure => 'present',
network => 'local',
interface => 'eth0',
options => 'proto 66 scope host table local',
}
```

For SLES:
Expand Down
25 changes: 20 additions & 5 deletions lib/puppet/provider/network_route/redhat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,23 @@ def self.parse_file(_filename, contents)
route = line.split(' ', 6)
raise Puppet::Error, 'Malformed redhat route file, cannot instantiate network_route resources' if route.length < 4

route = line.split(' ', 5) if route[0] == 'local'

new_route = {}

new_route[:gateway] = route[2]
new_route[:interface] = route[4]
new_route[:options] = route[5] if route[5]
if route[0] == 'local'
new_route[:interface] = route[3]
new_route[:options] = route[4] if route[4]
else
new_route[:gateway] = route[2]
new_route[:interface] = route[4]
new_route[:options] = route[5] if route[5]
end

if ['default', '0.0.0.0'].include? route[0]
if route[0] == 'local'
new_route[:name] = route[1]
new_route[:network] = 'local'
elsif ['default', '0.0.0.0'].include? route[0]
new_route[:name] = 'default' # FIXME: Must match :name in order for changes to be detected
new_route[:network] = 'default'
new_route[:netmask] = '0.0.0.0'
Expand All @@ -72,11 +82,16 @@ def self.format_file(_filename, providers)
contents << header
# Build routes
providers.sort_by(&:name).each do |provider|
%w[network netmask gateway interface].each do |prop|
%w[network interface].each do |prop|
raise Puppet::Error, "#{provider.name} is missing the required parameter '#{prop}'." if provider.send(prop).nil?
end
%w[netmask gateway].each do |prop|
raise Puppet::Error, "#{provider.name} is missing the required parameter '#{prop}'." if provider.send(prop).nil? && provider.send('network').to_s != 'local'
end
contents << if provider.network == 'default'
"#{provider.network} via #{provider.gateway} dev #{provider.interface}"
elsif provider.network == 'local'
"#{provider.network} #{provider.name} dev #{provider.interface}"
else
ip = IPAddr.new("#{provider.network}/#{provider.netmask}")
"#{ip}/#{ip.prefix} via #{provider.gateway} dev #{provider.interface}"
Expand Down
9 changes: 6 additions & 3 deletions lib/puppet/type/network_route.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
isrequired
desc 'The target network address'
validate do |value|
unless value == 'default'
unless %w[default local].include?(value)
a = PuppetX::Voxpupuli::Utils.try { IPAddr.new(value) }
raise("Invalid value for parameter 'network': #{value}") unless a
end
end
end

newproperty(:netmask) do
isrequired
desc 'The subnet mask to apply to the route'

validate do |value|
Expand All @@ -54,7 +53,6 @@
end

newproperty(:gateway) do
isrequired
desc 'The gateway to use for the route'

validate do |value|
Expand All @@ -79,4 +77,9 @@
raise ArgumentError, "#{self.class} requires a string for the options property" unless value.is_a?(String)
end
end

validate do
raise "Network_route[#{self[:name]}] must have netmask defined" if self[:network] != 'local' && self[:netmask].nil?
raise "Network_route[#{self[:name]}] must have gateway defined" if self[:network] != 'local' && self[:gateway].nil?
end
end
3 changes: 3 additions & 0 deletions spec/fixtures/provider/network_route/redhat/local_routes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
10.0.0.0/8 via 10.0.0.1 dev eth0
192.168.0.0/16 via 10.0.0.1 table n0-hc
local 10.0.0.2 dev eth0 proto 66 scope host table local
35 changes: 34 additions & 1 deletion spec/unit/provider/network_route/redhat_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ def fixture_data(file)
end
end

describe 'an advanced file using local route' do
let :data do
described_class.parse_file('', fixture_data('local_routes'))
end

it 'parses out normal ipv4 network routes' do
expect(data.find { |h| h[:name] == '10.0.0.2' }).to eq(
name: '10.0.0.2',
network: 'local',
interface: 'eth0',
options: 'proto 66 scope host table local'
)
end
end

describe 'an invalid file' do
it 'fails' do
expect do
Expand Down Expand Up @@ -127,8 +142,20 @@ def fixture_data(file)
)
end

let :local_provider do
instance_double(
'local_provider',
name: '10.0.0.2',
network: 'local',
netmask: nil,
gateway: nil,
interface: 'eth0',
options: 'proto 66 scope host table local'
)
end

let :content do
described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider, nooptions_provider])
described_class.format_file('', [route1_provider, route2_provider, defaultroute_provider, nooptions_provider, local_provider])
end

describe 'writing the route line' do
Expand Down Expand Up @@ -166,5 +193,11 @@ def fixture_data(file)
expect(content).not_to match(%r{absent})
end
end

describe 'for local routes' do
it 'has local route defined' do
expect(content.scan(%r{^local .*$}).first).to include('local 10.0.0.2 dev eth0 proto 66 scope host table local')
end
end
end
end
27 changes: 27 additions & 0 deletions spec/unit/type/network_route_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@

describe 'when validating the attribute value' do
describe 'network' do
it 'allows local' do
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')
expect(r[:network]).to eq('local')
end

it 'validates the network as an IP address' do
expect do
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')
Expand Down Expand Up @@ -63,6 +68,17 @@
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')
expect(r[:netmask]).to eq('255.255.128.0')
end

it 'requires netmask when not local' do
expect do
Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', gateway: '10.0.0.1', interface: 'eth0')
end.to raise_error(%r{must have netmask defined})
end

it 'does not require netmask when local' do
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: 'local', gateway: '10.0.0.1', interface: 'eth0')
expect(r[:netmask]).to be_nil
end
end

describe 'gateway' do
Expand All @@ -71,6 +87,17 @@
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')
end.to raise_error(%r{Invalid value for parameter 'gateway'})
end

it 'requires gateway when not local' do
expect do
Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: '192.168.1.0', netmask: '255.255.255.0', interface: 'eth0')
end.to raise_error(%r{must have gateway defined})
end

it 'does not require gateway when local' do
r = Puppet::Type.type(:network_route).new(name: '192.168.1.0/24', network: 'local', netmask: '255.255.255.0', interface: 'eth0')
expect(r[:gateway]).to be_nil
end
end
end
end

0 comments on commit a80db8c

Please sign in to comment.