Add ip address duplication check
* Add ip address duplication check for l3_ifconfig puppet resource before ip address set. Sometimes when there is ip address duplication it leads to wierd problems and long-time investigation of root cause. * Add sending Gratuitous ARP to update all neighbours. Closes-bug: #1457416 Change-Id: I047458dff0fbbb6fbd2a8143c641f834ecc9a100
This commit is contained in:
parent
b82855db50
commit
f1e949592e
@ -2,7 +2,8 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :iproute => 'ip',
|
||||
:ifup => 'ifup',
|
||||
:ifdown => 'ifdown'
|
||||
:ifdown => 'ifdown',
|
||||
:arping => 'arping'
|
||||
|
||||
|
||||
def self.prefetch(resources)
|
||||
@ -98,12 +99,30 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
else
|
||||
# add IP addresses
|
||||
adding_addresses.each do |ipaddr|
|
||||
# Check whether IP address is already used
|
||||
begin
|
||||
arping('-D', '-c 32', '-w 5', '-I', @resource[:interface], ipaddr.split('/')[0])
|
||||
rescue Exception => e
|
||||
_errmsg = nil
|
||||
e.message.split(/\n/).each do |line|
|
||||
line =~ /reply\s+from\s+(\d+\.\d+\.\d+\.\d+)/i
|
||||
if $1
|
||||
_errmsg = line
|
||||
break
|
||||
end
|
||||
end
|
||||
raise if _errmsg.nil?
|
||||
warn("There is IP duplication for IP address #{ipaddr} on interface #{@resource[:interface]}!!!\n#{_errmsg}")
|
||||
end
|
||||
# Set IP address
|
||||
begin
|
||||
iproute('addr', 'add', ipaddr, 'dev', @resource[:interface])
|
||||
rescue
|
||||
rv = iproute('-o', 'addr', 'show', 'dev', @resource[:interface], 'to', "#{ipaddr.split('/')[0]}/32")
|
||||
raise if ! rv.include? "inet #{ipaddr}"
|
||||
end
|
||||
# Send Gratuitous ARP to update all neighbours
|
||||
arping('-U', '-c 32', '-w 5', '-I', @resource[:interface], ipaddr.split('/')[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -112,15 +131,15 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
if !@property_flush[:gateway].nil? or !@property_flush[:gateway_metric].nil?
|
||||
# clean all default gateways for *THIS* interface (with any metrics)
|
||||
cmdline = ['route', 'del', 'default', 'dev', @resource[:interface]]
|
||||
rc = 0
|
||||
while rc == 0
|
||||
|
||||
while true
|
||||
# we should remove route repeatedly for prevent situation
|
||||
# when has multiple default routes through the same router,
|
||||
# but with different metrics
|
||||
begin
|
||||
iproute(cmdline)
|
||||
rescue
|
||||
rc = 1
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -58,10 +58,10 @@ class l23network (
|
||||
Anchor <| title == 'l23network::l2::centos_upndown_scripts' |> -> Anchor['l23network::init']
|
||||
}
|
||||
|
||||
#install extra tools
|
||||
ensure_packages($::l23network::params::extra_tools)
|
||||
|
||||
Anchor['l23network::l2::init'] -> Anchor['l23network::init']
|
||||
anchor { 'l23network::init': }
|
||||
|
||||
}
|
||||
#
|
||||
###
|
||||
|
@ -16,6 +16,7 @@ class l23network::params {
|
||||
$ovs_datapath_package_name = 'openvswitch-datapath-dkms'
|
||||
$ovs_common_package_name = 'openvswitch-switch'
|
||||
$ovs_kern_module_name = 'openvswitch'
|
||||
$extra_tools = 'iputils-arping'
|
||||
}
|
||||
/(?i)redhat/: {
|
||||
$interfaces_dir = '/etc/sysconfig/network-scripts'
|
||||
@ -32,6 +33,7 @@ class l23network::params {
|
||||
}
|
||||
$ovs_common_package_name = 'openvswitch'
|
||||
$ovs_kern_module_name = 'openvswitch'
|
||||
$extra_tools = 'iputils'
|
||||
}
|
||||
/(?i)darwin/: {
|
||||
$interfaces_dir = '/tmp/1'
|
||||
|
@ -13,7 +13,13 @@ if Puppet.version < '4.0.0'
|
||||
end
|
||||
end
|
||||
|
||||
Puppet::Util::Log.level = :debug
|
||||
Puppet::Util::Log.newdestination(:console)
|
||||
|
||||
RSpec.configure do |c|
|
||||
c.module_path = File.join(fixture_path, 'modules')
|
||||
c.manifest_dir = File.join(fixture_path, 'manifests')
|
||||
c.mock_with(:mocha)
|
||||
end
|
||||
|
||||
###
|
@ -0,0 +1,53 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Type.type(:l3_ifconfig).provider(:lnx) do
|
||||
|
||||
let(:resource) {
|
||||
Puppet::Type.type(:l3_ifconfig).new(
|
||||
:name => 'eth1',
|
||||
:interface => 'eth1',
|
||||
:ensure => :present,
|
||||
:ipaddr => ["10.99.1.4/24"],
|
||||
:gateway => :absent,
|
||||
:provider => :lnx
|
||||
)
|
||||
}
|
||||
|
||||
let(:provider) { resource.provider }
|
||||
let(:instance) { provider.class.instances }
|
||||
|
||||
describe "l3_ifconfig " do
|
||||
before(:each) do
|
||||
provider.class.stubs(:arping).with('-U', '-c 32', '-w 5', '-I', 'eth1', '10.99.1.4').returns(true)
|
||||
provider.class.stubs(:iproute)
|
||||
provider.class.stubs(:iproute).with(['route', 'del', 'default', 'dev', 'eth1']).raises(Puppet::ExecutionFailure)
|
||||
end
|
||||
|
||||
it "Assign IP address to the NIC" do
|
||||
provider.class.stubs(:arping).with('-D', '-c 32', '-w 5', '-I', 'eth1', '10.99.1.4').returns(true)
|
||||
provider.expects(:warn).with { |arg| arg =~ /IP\s+duplication/ }.never
|
||||
provider.create
|
||||
provider.flush
|
||||
end
|
||||
|
||||
it "Assign duplication IP address to the NIC" do
|
||||
provider.class.stubs(:arping).with('-D', '-c 32', '-w 5', '-I', 'eth1', '10.99.1.4').raises(Exception, """
|
||||
ARPING 10.99.1.4 from 0.0.0.0 eth1
|
||||
Unicast reply from 10.99.1.4 [00:1C:42:99:06:98] 1.292ms
|
||||
Sent 1 probes (1 broadcast(s))
|
||||
Received 1 response(s)
|
||||
""")
|
||||
provider.expects(:warn).with { |arg| arg =~ /IP\s+duplication/ }
|
||||
provider.create
|
||||
provider.flush
|
||||
end
|
||||
|
||||
it "Arping execution error while assigning IP address to the NIC" do
|
||||
provider.class.stubs(:arping).with('-D', '-c 32', '-w 5', '-I', 'eth1', '10.99.1.4').raises(Puppet::ExecutionFailure, '')
|
||||
provider.create
|
||||
expect{provider.flush}.to raise_error(Puppet::ExecutionFailure)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user