Add new bond propertiew configuration:
New properties are: * downdelay * updelay * ad_select Also implemented: * improved tests * replace some iproute() to corresponded class methods * modifyed arping arguments * move some interface-related methods to InterfaceToolset base class implementation progress: + l23_stored_config_for LNX-ubuntu + l23_stored_config_for OVS-ubuntu - l23_stored_config_for LNX-centos - l23_stored_config_for OVS-centos + runtime configuration for LNX + runtime configuration for OVS Change-Id: I3c144f410c29c114c7976a43f5fd00967ae601a4
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
require 'puppetx/l23_utils'
|
||||
require 'yaml'
|
||||
|
||||
class Puppet::Provider::InterfaceToolset < Puppet::Provider
|
||||
|
||||
def self.iproute(*cmd)
|
||||
actual_cmd = ['ip'] + Array(*cmd)
|
||||
rv = []
|
||||
IO.popen(actual_cmd.join(' ') + ' 2>&1') do |ff|
|
||||
rv = ff.readlines().map{|l| l.chomp()}
|
||||
ff.close
|
||||
if 0 != $?.exitstatus
|
||||
raise Puppet::ExecutionFailure, "Command '#{actual_cmd.join(' ')}' has been failed with exit_code=#{$?.exitstatus}:\n#{rv.join("\n")}"
|
||||
end
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
def self.ovs_vsctl(*cmd)
|
||||
actual_cmd = ['ovs-vsctl'] + Array(*cmd)
|
||||
rv = []
|
||||
IO.popen(actual_cmd.join(' ') + ' 2>&1') do |ff|
|
||||
rv = ff.readlines().map{|l| l.chomp()}
|
||||
ff.close
|
||||
if 0 != $?.exitstatus
|
||||
rv = nil
|
||||
end
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.iface_exist?(iface)
|
||||
File.exist? "/sys/class/net/#{iface}"
|
||||
end
|
||||
|
||||
def self.set_mtu(iface, mtu=1500)
|
||||
if File.symlink?("/sys/class/net/#{iface}")
|
||||
debug("Set MTU to '#{mtu}' for interface '#{iface}'")
|
||||
set_sys_class("/sys/class/net/#{iface}/mtu", mtu)
|
||||
end
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.set_sys_class(property, value)
|
||||
debug("SET sys.property: #{property} << #{value}")
|
||||
begin
|
||||
property_file = File.open(property, 'a')
|
||||
property_file.write("#{value.to_s}")
|
||||
property_file.close
|
||||
rv = true
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't set property '#{property}' to '#{value}': #{e.message}")
|
||||
rv = false
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
def self.get_sys_class(property, array=false)
|
||||
as_array = (array ? ' as array' : '')
|
||||
debug("GET sys.property: #{property}#{as_array}.")
|
||||
begin
|
||||
rv = File.open(property).read.split(/\s+/)
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't get property '#{property}': #{e.message}")
|
||||
rv = ['']
|
||||
end
|
||||
(array ? rv : rv[0])
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
def self.get_iface_state(iface)
|
||||
# returns:
|
||||
# true -- interface in UP state
|
||||
# false -- interface in UP state, but no-carrier
|
||||
# nil -- interface in DOWN state
|
||||
begin
|
||||
1 == File.open("/sys/class/net/#{iface}/carrier").read.chomp.to_i
|
||||
rescue
|
||||
# if interface is down, this file can't be read
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.interface_up(iface, force=false)
|
||||
cmd = ['link', 'set', 'up', 'dev', iface]
|
||||
cmd.insert(0, '--force') if force
|
||||
begin
|
||||
iproute(cmd)
|
||||
rv = true
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't put interface '#{iface}' to UP state: #{e.message}")
|
||||
rv = false
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
def self.interface_down(iface, force=false)
|
||||
cmd = ['link', 'set', 'down', 'dev', iface]
|
||||
cmd.insert(0, '--force') if force
|
||||
begin
|
||||
iproute(cmd)
|
||||
rv = true
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't put interface '#{iface}' to DOWN state: #{e.message}")
|
||||
rv = false
|
||||
end
|
||||
return rv
|
||||
end
|
||||
# ---------------------------------------------------------------------------
|
||||
def self.ipaddr_exist?(if_name)
|
||||
rv = false
|
||||
iproute(['-o', 'addr', 'show', 'dev', if_name]).map{|l| l.split(/\s+/)}.each do |line|
|
||||
if line[2].match(/^inet\d?$/)
|
||||
rv=true
|
||||
break
|
||||
end
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
def self.addr_flush(iface, force=false)
|
||||
cmd = ['addr', 'flush', 'dev', iface]
|
||||
cmd.insert(0, '--force') if force
|
||||
begin
|
||||
iproute(cmd)
|
||||
rv = true
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't flush addr for interface '#{iface}': #{e.message}")
|
||||
rv = false
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
def self.route_flush(iface, force=false)
|
||||
cmd = ['route', 'flush', 'dev', iface]
|
||||
cmd.insert(0, '--force') if force
|
||||
begin
|
||||
iproute(cmd)
|
||||
rv = true
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't flush routes for interface '#{iface}': #{e.message}")
|
||||
rv = false
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def self.get_if_addr_mappings
|
||||
if_list = {}
|
||||
ip_a = iproute(['-f', 'inet', 'addr', 'show'])
|
||||
if_name = nil
|
||||
ip_a.each do |line|
|
||||
line.rstrip!
|
||||
case line
|
||||
when /^\s*\d+\:\s+([\w\-\.]+)[\:\@]/i
|
||||
if_name = $1
|
||||
if_list[if_name] = { :ipaddr => [] }
|
||||
when /^\s+inet\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})/
|
||||
next if if_name.nil?
|
||||
if_list[if_name][:ipaddr] << $1
|
||||
else
|
||||
next
|
||||
end
|
||||
end
|
||||
return if_list
|
||||
end
|
||||
|
||||
def self.get_if_defroutes_mappings
|
||||
rou_list = {}
|
||||
ip_a = iproute(['-f', 'inet', 'route', 'show'])
|
||||
ip_a.each do |line|
|
||||
line.rstrip!
|
||||
next if !line.match(/^\s*default\s+via\s+([\d\.]+)\s+dev\s+([\w\-\.]+)(\s+metric\s+(\d+))?/)
|
||||
metric = $4.nil? ? :absent : $4.to_i
|
||||
rou_list[$2] = { :gateway => $1, :gateway_metric => metric } if rou_list[$2].nil? # do not replace to gateway with highest metric
|
||||
end
|
||||
return rou_list
|
||||
end
|
||||
|
||||
def self.get_routes
|
||||
# return array of hashes -- all defined routes.
|
||||
rv = []
|
||||
# cat /proc/net/route returns information about routing table in format:
|
||||
# Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||
# eth0 00000000 0101010A 0003 0 0 0 00000000 0 0 0
|
||||
# eth0 0001010A 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||
File.open('/proc/net/route').readlines.reject{|l| l.match(/^[Ii]face.+/) or l.match(/^(\r\n|\n|\s*)$|^$/)}.map{|l| l.split(/\s+/)}.each do |line|
|
||||
#https://github.com/kwilczynski/facter-facts/blob/master/default_gateway.rb
|
||||
iface = line[0]
|
||||
metric = line[6]
|
||||
# whether gateway is default
|
||||
if line[1] == '00000000'
|
||||
dest = 'default'
|
||||
dest_addr = nil
|
||||
mask = nil
|
||||
route_type = 'default'
|
||||
else
|
||||
dest_addr = [line[1]].pack('H*').unpack('C4').reverse.join('.')
|
||||
mask = [line[7]].pack('H*').unpack('B*')[0].count('1')
|
||||
dest = "#{dest_addr}/#{mask}"
|
||||
end
|
||||
# whether route is local
|
||||
if line[2] == '00000000'
|
||||
gateway = nil
|
||||
route_type = 'local'
|
||||
else
|
||||
gateway = [line[2]].pack('H*').unpack('C4').reverse.join('.')
|
||||
route_type = nil
|
||||
end
|
||||
rv << {
|
||||
:destination => dest,
|
||||
:gateway => gateway,
|
||||
:metric => metric.to_i,
|
||||
:type => route_type,
|
||||
:interface => iface,
|
||||
}
|
||||
end
|
||||
# this sort need for prioritize routes by metrics
|
||||
return rv.sort_by{|r| r[:metric]||0}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
||||
@@ -1,5 +1,3 @@
|
||||
require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_base')
|
||||
|
||||
Puppet::Type.type(:k_mod).provide(:lnx) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :mod_load => 'modprobe',
|
||||
|
||||
@@ -22,6 +22,9 @@ Puppet::Type.type(:l23_stored_config).provide(:ovs_ubuntu, :parent => Puppet::Pr
|
||||
:bond_lacp_rate => 'ovs_options',
|
||||
:bond_lacp => 'ovs_options',
|
||||
:bond_xmit_hash_policy => '', # unused
|
||||
:bond_ad_select => '',
|
||||
:bond_updelay => 'ovs_options',
|
||||
:bond_downdelay => 'ovs_options',
|
||||
})
|
||||
return rv
|
||||
end
|
||||
@@ -34,6 +37,14 @@ Puppet::Type.type(:l23_stored_config).provide(:ovs_ubuntu, :parent => Puppet::Pr
|
||||
:field => 'bond_mode',
|
||||
:store_to => 'ovs_options'
|
||||
},
|
||||
:bond_updelay => {
|
||||
:field => 'bond_updelay',
|
||||
:store_to => 'ovs_options'
|
||||
},
|
||||
:bond_downdelay => {
|
||||
:field => 'bond_downdelay',
|
||||
:store_to => 'ovs_options'
|
||||
},
|
||||
:bond_lacp => {
|
||||
:field => 'lacp',
|
||||
:store_to => 'ovs_options'
|
||||
@@ -46,7 +57,6 @@ Puppet::Type.type(:l23_stored_config).provide(:ovs_ubuntu, :parent => Puppet::Pr
|
||||
:field => 'other_config:bond-miimon-interval',
|
||||
:store_to => 'ovs_options'
|
||||
},
|
||||
|
||||
}
|
||||
end
|
||||
def oneline_properties
|
||||
|
||||
@@ -31,6 +31,9 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
||||
:bond_miimon => 'bond-miimon',
|
||||
:bond_lacp => '', # unused for lnx
|
||||
:bond_lacp_rate => 'bond-lacp-rate',
|
||||
:bond_updelay => 'bond-updelay',
|
||||
:bond_downdelay => 'bond-downdelay',
|
||||
:bond_ad_select => 'bond-ad-select',
|
||||
:bond_xmit_hash_policy => 'bond-xmit-hash-policy'
|
||||
}
|
||||
end
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
require 'puppetx/l23_utils'
|
||||
require 'puppetx/l23_ethtool_name_commands_mapping'
|
||||
require 'yaml'
|
||||
require File.join(File.dirname(__FILE__), 'interface_toolset')
|
||||
|
||||
class Puppet::Provider::L2_base < Puppet::Provider
|
||||
|
||||
def self.ovs_vsctl(*cmd)
|
||||
actual_cmd = ['ovs-vsctl'] + Array(*cmd)
|
||||
begin
|
||||
ff = IO.popen(actual_cmd.join(' '))
|
||||
rv = ff.readlines().map{|l| l.chomp()}
|
||||
rescue
|
||||
rv = nil
|
||||
end
|
||||
return rv
|
||||
end
|
||||
class Puppet::Provider::L2_base < Puppet::Provider::InterfaceToolset
|
||||
|
||||
def self.prefetch(resources)
|
||||
interfaces = instances
|
||||
@@ -26,10 +14,6 @@ class Puppet::Provider::L2_base < Puppet::Provider
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.iface_exist?(iface)
|
||||
File.exist? "/sys/class/net/#{iface}"
|
||||
end
|
||||
|
||||
def self.get_lnx_vlan_interfaces
|
||||
# returns hash, that contains ports (interfaces) configuration.
|
||||
# i.e {
|
||||
@@ -583,31 +567,6 @@ class Puppet::Provider::L2_base < Puppet::Provider
|
||||
self.ovs_bond_allowed_properties.keys.sort
|
||||
end
|
||||
|
||||
|
||||
def self.get_iface_state(iface)
|
||||
# returns:
|
||||
# true -- interface in UP state
|
||||
# false -- interface in UP state, but no-carrier
|
||||
# nil -- interface in DOWN state
|
||||
begin
|
||||
1 == File.open("/sys/class/net/#{iface}/carrier").read.chomp.to_i
|
||||
rescue
|
||||
# if interface is down, this file can't be read
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def self.ipaddr_exist?(if_name)
|
||||
rv = false
|
||||
iproute('-o', 'addr', 'show', 'dev', if_name).split(/\n+/).map{|l| l.split(/\s+/)}.each do |line|
|
||||
if line[2].match(/^inet\d?$/)
|
||||
rv=true
|
||||
break
|
||||
end
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.get_ethtool_name_commands_mapping
|
||||
@@ -628,35 +587,6 @@ class Puppet::Provider::L2_base < Puppet::Provider
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.set_sys_class(property, value)
|
||||
begin
|
||||
property_file = File.open(property, 'a')
|
||||
property_file.write("#{value.to_s}")
|
||||
property_file.close
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't set property '#{property}' to '#{value}': #{e.message}")
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_sys_class(property, array=false)
|
||||
begin
|
||||
rv = File.open(property).read.split(/\s+/)
|
||||
rescue Exception => e
|
||||
debug("Non-fatal-Error: Can't get property '#{property}': #{e.message}")
|
||||
rv = ['']
|
||||
end
|
||||
(array ? rv : rv[0])
|
||||
end
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def self.set_mtu(iface, mtu=1500)
|
||||
if File.symlink?("/sys/class/net/#{iface}")
|
||||
debug("Set MTU to '#{mtu}' for interface '#{iface}'")
|
||||
File.open("/sys/class/net/#{iface}/mtu", "a") { |f| f.write(mtu) }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
||||
@@ -6,8 +6,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_ba
|
||||
|
||||
Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :iproute => 'ip',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
commands :ethtool_cmd => 'ethtool',
|
||||
:brctl => 'brctl'
|
||||
|
||||
|
||||
@@ -56,16 +55,12 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
debug("CREATE resource: #{@resource}")
|
||||
@old_property_hash = {}
|
||||
@property_flush = {}.merge! @resource
|
||||
open('/sys/class/net/bonding_masters', 'a') do |f|
|
||||
f << "+#{@resource[:name]}"
|
||||
end
|
||||
self.class.set_sys_class('/sys/class/net/bonding_masters', "+#{@resource[:name]}")
|
||||
end
|
||||
|
||||
def destroy
|
||||
debug("DESTROY resource: #{@resource}")
|
||||
open('/sys/class/net/bonding_masters', 'a') do |f|
|
||||
f << "-#{@resource[:name]}"
|
||||
end
|
||||
self.class.set_sys_class('/sys/class/net/bonding_masters', "-#{@resource[:name]}")
|
||||
end
|
||||
|
||||
def flush
|
||||
@@ -75,7 +70,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
#
|
||||
# FLUSH changed properties
|
||||
if @property_flush.has_key? :slaves
|
||||
runtime_slave_ports = File.open("/sys/class/net/#{@resource[:bond]}/bonding/slaves", "r").read.split(/\s+/)
|
||||
runtime_slave_ports = self.class.get_sys_class("/sys/class/net/#{@resource[:bond]}/bonding/slaves", true)
|
||||
if @property_flush[:slaves].nil? or @property_flush[:slaves] == :absent
|
||||
debug("Remove all slave ports from bond '#{@resource[:bond]}'")
|
||||
rm_slave_list = runtime_slave_ports
|
||||
@@ -84,7 +79,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
if !rm_slave_list.empty?
|
||||
debug("Remove '#{rm_slave_list.join(',')}' ports from bond '#{@resource[:bond]}'")
|
||||
rm_slave_list.each do |slave|
|
||||
iproute('link', 'set', 'down', 'dev', slave) # need by kernel requirements by design. undocumented :(
|
||||
self.class.interface_down(slave) # need by kernel requirements by design. undocumented :(
|
||||
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "-#{slave}")
|
||||
end
|
||||
end
|
||||
@@ -94,9 +89,9 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
debug("Add '#{add_slave_list.join(',')}' ports to bond '#{@resource[:bond]}'")
|
||||
add_slave_list.each do |slave|
|
||||
debug("Add interface '#{slave}' to bond '#{@resource[:bond]}'")
|
||||
iproute('link', 'set', 'down', 'dev', slave) # need by kernel requirements by design. undocumented :(
|
||||
self.class.interface_down(slave) # need by kernel requirements by design. undocumented :(
|
||||
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "+#{slave}")
|
||||
iproute('link', 'set', 'up', 'dev', slave)
|
||||
self.class.interface_up(slave)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -115,7 +110,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
# says, that bond interface should be downed, but it's not enouth.
|
||||
self.class.set_sys_class("#{bond_prop_dir}/bonding/slaves", "-#{eth}")
|
||||
end
|
||||
iproute('link', 'set', 'down', 'dev', @resource[:bond])
|
||||
self.class.interface_down(@resource[:bond])
|
||||
# setup primary bond_properties
|
||||
primary_bond_properties = [:mode, :xmit_hash_policy]
|
||||
debug("Set primary bond properties [#{primary_bond_properties.join(',')}] for bond '#{@resource[:bond]}'")
|
||||
@@ -155,7 +150,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
end
|
||||
end
|
||||
# re-assemble bond after configuration
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:bond]) if runtime_bond_state
|
||||
self.class.interface_up(@resource[:bond]) if runtime_bond_state
|
||||
debug("Re-assemble bond '#{@resource[:bond]}'")
|
||||
runtime_slave_ports.each do |eth|
|
||||
debug("Add interface '#{eth}' to bond '#{@resource[:bond]}'")
|
||||
@@ -172,7 +167,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
#
|
||||
# remove interface from old bridge
|
||||
runtime_bond_state = !self.class.get_iface_state(@resource[:bond]).nil?
|
||||
iproute('--force', 'link', 'set', 'down', 'dev', @resource[:bond])
|
||||
self.class.interface_down(@resource[:bond], true)
|
||||
if ! port_bridges_hash[@resource[:bond]].nil?
|
||||
br_name = port_bridges_hash[@resource[:bond]][:bridge]
|
||||
if br_name != @resource[:bond]
|
||||
@@ -200,11 +195,11 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
#pass
|
||||
end
|
||||
end
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:bond]) if runtime_bond_state
|
||||
self.class.interface_up(@resource[:bond]) if runtime_bond_state
|
||||
debug("Change bridge")
|
||||
end
|
||||
if @property_flush[:onboot]
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:bond])
|
||||
self.class.interface_up(@resource[:bond])
|
||||
end
|
||||
if !['', 'absent'].include? @property_flush[:mtu].to_s
|
||||
self.class.set_mtu(@resource[:bond], @property_flush[:mtu])
|
||||
|
||||
@@ -2,8 +2,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
||||
|
||||
Puppet::Type.type(:l2_bond).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||
commands :vsctl => 'ovs-vsctl',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
:iproute => 'ip'
|
||||
:ethtool_cmd => 'ethtool'
|
||||
|
||||
|
||||
# def self.add_unremovable_flag(port_props)
|
||||
@@ -26,7 +25,7 @@ Puppet::Type.type(:l2_bond).provide(:ovs, :parent => Puppet::Provider::Ovs_base)
|
||||
@property_flush = {}.merge! @resource
|
||||
|
||||
@resource[:slaves].each do |slave|
|
||||
iproute('addr', 'flush', 'dev', slave)
|
||||
self.class.addr_flush(slave)
|
||||
end
|
||||
|
||||
begin
|
||||
|
||||
@@ -9,8 +9,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_ba
|
||||
Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :brctl => 'brctl',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
:iproute => 'ip'
|
||||
:ethtool_cmd => 'ethtool'
|
||||
|
||||
def self.instances
|
||||
rv = []
|
||||
@@ -44,11 +43,11 @@ Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_bas
|
||||
raise if ! self.class.iface_exist? @resource[:bridge]
|
||||
notice("'#{@resource[:bridge]}' already created by ghost event.")
|
||||
end
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:bridge])
|
||||
self.class.interface_up(@resource[:bridge])
|
||||
end
|
||||
|
||||
def destroy
|
||||
iproute('link', 'set', 'down', 'dev', @resource[:bridge])
|
||||
self.class.interface_down(@resource[:bridge])
|
||||
brctl('delbr', @resource[:bridge])
|
||||
end
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
||||
Puppet::Type.type(:l2_bridge).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||
commands :vsctl => 'ovs-vsctl',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
:brctl => 'brctl',
|
||||
:iproute => 'ip'
|
||||
:brctl => 'brctl'
|
||||
|
||||
def self.skip_port_for?(port_props)
|
||||
port_props[:br_type] != 'ovs'
|
||||
@@ -27,12 +26,12 @@ Puppet::Type.type(:l2_bridge).provide(:ovs, :parent => Puppet::Provider::Ovs_bas
|
||||
@property_flush = {}.merge! @resource
|
||||
#
|
||||
vsctl('add-br', @resource[:bridge])
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:bridge])
|
||||
self.class.interface_up(@resource[:bridge])
|
||||
notice("bridge '#{@resource[:bridge]}' created.")
|
||||
end
|
||||
|
||||
def destroy
|
||||
iproute('link', 'set', 'down', 'dev', @resource[:bridge])
|
||||
self.class.interface_down(@resource[:bridge])
|
||||
vsctl("del-br", @resource[:bridge])
|
||||
end
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
||||
Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||
commands :vsctl => 'ovs-vsctl',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
:brctl => 'brctl',
|
||||
:iproute => 'ip'
|
||||
:brctl => 'brctl'
|
||||
|
||||
|
||||
def self.instances
|
||||
@@ -107,7 +106,7 @@ Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base
|
||||
end
|
||||
end
|
||||
end
|
||||
iproute('link', 'set', 'up', 'dev', jack)
|
||||
self.class.interface_up(jack)
|
||||
else
|
||||
# creating OVS-to-OVS patchcord
|
||||
jacks = []
|
||||
|
||||
@@ -2,8 +2,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_ba
|
||||
|
||||
Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :iproute => 'ip',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
commands :ethtool_cmd => 'ethtool',
|
||||
:brctl => 'brctl',
|
||||
:pkill => 'pkill'
|
||||
|
||||
@@ -47,7 +46,7 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
@property_flush = {}.merge! @resource
|
||||
# todo: divide simple creating interface and vlan
|
||||
begin
|
||||
iproute('link', 'add', 'link', @resource[:vlan_dev], 'name', @resource[:interface], 'type', 'vlan', 'id', @resource[:vlan_id])
|
||||
self.class.iproute(['link', 'add', 'link', @resource[:vlan_dev], 'name', @resource[:interface], 'type', 'vlan', 'id', @resource[:vlan_id]])
|
||||
rescue
|
||||
# Some time interface may be created by OS init scripts. It's a normal for Ubuntu.
|
||||
raise if ! self.class.iface_exist? @resource[:interface]
|
||||
@@ -59,7 +58,7 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
debug("DESTROY resource: #{@resource}")
|
||||
# todo: Destroing of L2 resource -- is a putting interface to the DOWN state.
|
||||
# Or remove, if ove a vlan interface
|
||||
#iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
|
||||
#iproute(['--force', 'addr', 'flush', 'dev', @resource[:interface]])
|
||||
end
|
||||
|
||||
def flush
|
||||
@@ -77,10 +76,10 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
bond = @old_property_hash[:bond_master]
|
||||
if self.class.ipaddr_exist? @resource[:interface]
|
||||
# remove all IP addresses from member of bond. This should be done on device in UP state
|
||||
iproute('addr', 'flush', 'dev', @resource[:interface])
|
||||
self.class.addr_flush(@resource[:interface])
|
||||
end
|
||||
# putting interface to the down-state, because add/remove upped interface impossible. undocumented kern.behavior.
|
||||
iproute('--force', 'link', 'set', 'down', 'dev', @resource[:interface])
|
||||
self.class.interface_down(@resource[:interface], true)
|
||||
if bond and bond != :absent and File.exist?("/sys/class/net/#{@resource[:interface]}/master/bonding/slaves")
|
||||
# remove interface from bond, if one included to it
|
||||
debug("Remove interface '#{@resource[:interface]}' from bond '#{bond}'.")
|
||||
@@ -99,9 +98,9 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
@property_flush[:port_type] = nil
|
||||
end
|
||||
# Up parent interface if this is vlan port
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:vlan_dev]) if @resource[:vlan_dev]
|
||||
self.class.interface_up(@resource[:vlan_dev]) if @resource[:vlan_dev]
|
||||
# Up port
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:interface])
|
||||
self.class.interface_up(@resource[:interface])
|
||||
end
|
||||
if @property_flush.has_key? :bridge
|
||||
# get actual bridge-list. We should do it here,
|
||||
@@ -112,9 +111,9 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
debug("Actual-port-bridge-mapping: '#{port_bridges_hash}'") # it should removed from LNX
|
||||
#
|
||||
#Flush ipaddr and routes for interface, thah adding to the bridge
|
||||
iproute('route', 'flush', 'dev', @resource[:interface])
|
||||
iproute('addr', 'flush', 'dev', @resource[:interface])
|
||||
iproute('--force', 'link', 'set', 'down', 'dev', @resource[:interface])
|
||||
self.class.route_flush(@resource[:interface])
|
||||
self.class.addr_flush(@resource[:interface])
|
||||
self.class.interface_down(@resource[:interface], true)
|
||||
# remove interface from old bridge
|
||||
if ! port_bridges_hash[@resource[:interface]].nil?
|
||||
br_name = port_bridges_hash[@resource[:interface]][:bridge]
|
||||
@@ -149,7 +148,7 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
#pass
|
||||
end
|
||||
end
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:interface])
|
||||
self.class.interface_up(@resource[:interface])
|
||||
debug("Change bridge")
|
||||
end
|
||||
if @property_flush.has_key? :ethtool and @property_flush[:ethtool].is_a? Hash
|
||||
@@ -176,9 +175,9 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
||||
# Should be after bond, because interface may auto-upped while added to the bond
|
||||
debug("Setup UP state for interface '#{@resource[:interface]}'.")
|
||||
# Up parent interface if this is vlan port
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:vlan_dev]) if @resource[:vlan_dev]
|
||||
self.class.interface_up(@resource[:vlan_dev]) if @resource[:vlan_dev]
|
||||
# Up port
|
||||
iproute('link', 'set', 'up', 'dev', @resource[:interface])
|
||||
self.class.interface_up(@resource[:interface])
|
||||
end
|
||||
if !['', 'absent'].include? @property_flush[:mtu].to_s
|
||||
self.class.set_mtu(@resource[:interface], @property_flush[:mtu])
|
||||
|
||||
@@ -2,9 +2,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
||||
|
||||
Puppet::Type.type(:l2_port).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||
commands :vsctl => 'ovs-vsctl',
|
||||
:ethtool_cmd => 'ethtool',
|
||||
:iproute => 'ip'
|
||||
|
||||
:ethtool_cmd => 'ethtool'
|
||||
|
||||
def self.add_unremovable_flag(port_props)
|
||||
# calculate 'unremovable' flag. Should be re-defined in chield providers
|
||||
|
||||
16
deployment/puppet/l23network/lib/puppet/provider/l3_base.rb
Normal file
16
deployment/puppet/l23network/lib/puppet/provider/l3_base.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
require File.join(File.dirname(__FILE__), 'interface_toolset')
|
||||
|
||||
class Puppet::Provider::L3_base < Puppet::Provider::InterfaceToolset
|
||||
|
||||
def self.prefetch(resources)
|
||||
interfaces = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = interfaces.find{ |ii| ii.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# vim: set ts=2 sw=2 et :
|
||||
@@ -1,20 +1,11 @@
|
||||
Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/l3_base')
|
||||
|
||||
Puppet::Type.type(:l3_ifconfig).provide(:lnx, :parent => Puppet::Provider::L3_base) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :iproute => 'ip',
|
||||
:ifup => 'ifup',
|
||||
commands :ifup => 'ifup',
|
||||
:ifdown => 'ifdown',
|
||||
:arping => 'arping'
|
||||
|
||||
|
||||
def self.prefetch(resources)
|
||||
interfaces = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = interfaces.find{ |ii| ii.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.instances
|
||||
insts = []
|
||||
rou_list = self.get_if_defroutes_mappings()
|
||||
@@ -56,7 +47,7 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
debug("DESTROY resource: #{@resource}")
|
||||
# todo: Destroing of L3 resource -- is a removing any IP addresses.
|
||||
# DO NOT!!! put intedafce to Down state.
|
||||
iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
|
||||
self.class.addr_flush(@resource[:interface], true)
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
@@ -75,7 +66,7 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
if ! @property_flush[:ipaddr].nil?
|
||||
if @property_flush[:ipaddr].include?(:absent)
|
||||
# flush all ip addresses from interface
|
||||
iproute('--force', 'addr', 'flush', 'dev', @resource[:interface])
|
||||
self.class.addr_flush(@resource[:interface], true)
|
||||
#todo(sv): check for existing dhclient for this interface and kill it
|
||||
elsif (@property_flush[:ipaddr] & [:dhcp, 'dhcp', 'DHCP']).any?
|
||||
# start dhclient on interface the same way as at boot time
|
||||
@@ -86,14 +77,14 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
# add-remove static IP addresses
|
||||
if !@old_property_hash.nil? and !@old_property_hash[:ipaddr].nil?
|
||||
(@old_property_hash[:ipaddr] - @property_flush[:ipaddr]).each do |ipaddr|
|
||||
iproute('--force', 'addr', 'del', ipaddr, 'dev', @resource[:interface])
|
||||
self.class.iproute(['--force', 'addr', 'del', ipaddr, 'dev', @resource[:interface]])
|
||||
end
|
||||
adding_addresses = @property_flush[:ipaddr] - @old_property_hash[:ipaddr]
|
||||
else
|
||||
adding_addresses = @property_flush[:ipaddr]
|
||||
end
|
||||
if adding_addresses.include? :none
|
||||
iproute('--force', 'link', 'set', 'dev', @resource[:interface], 'up')
|
||||
self.class.interface_up(@resource[:interface], true)
|
||||
elsif adding_addresses.include? :dhcp
|
||||
debug("!!! DHCP runtime configuration not implemented now !!!")
|
||||
else
|
||||
@@ -101,7 +92,7 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
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])
|
||||
arping(['-D', '-f', '-c 32', '-w 2', '-I', @resource[:interface], ipaddr.split('/')[0]])
|
||||
rescue Exception => e
|
||||
_errmsg = nil
|
||||
e.message.split(/\n/).each do |line|
|
||||
@@ -116,13 +107,13 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
end
|
||||
# Set IP address
|
||||
begin
|
||||
iproute('addr', 'add', ipaddr, 'dev', @resource[:interface])
|
||||
self.class.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}"
|
||||
rv = self.class.iproute(['-o', 'addr', 'show', 'dev', @resource[:interface], 'to', "#{ipaddr.split('/')[0]}/32"])
|
||||
raise if ! rv.join("\n").include? "inet #{ipaddr}"
|
||||
end
|
||||
# Send Gratuitous ARP to update all neighbours
|
||||
arping('-U', '-c 32', '-w 5', '-I', @resource[:interface], ipaddr.split('/')[0])
|
||||
arping(['-A', '-c 32', '-w 2', '-I', @resource[:interface], ipaddr.split('/')[0]])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -137,7 +128,7 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
# when has multiple default routes through the same router,
|
||||
# but with different metrics
|
||||
begin
|
||||
iproute(cmdline)
|
||||
self.class.iproute(cmdline)
|
||||
rescue
|
||||
break
|
||||
end
|
||||
@@ -155,11 +146,11 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
cmdline << ['metric', @property_flush[:gateway_metric]]
|
||||
end
|
||||
begin
|
||||
rv = iproute(cmdline)
|
||||
self.class.iproute(cmdline)
|
||||
rescue
|
||||
warn("!!! Iproute can not setup new gateway.\n!!! May be default gateway with same metric already exists:")
|
||||
rv = iproute('-f', 'inet', 'route', 'show')
|
||||
warn("#{rv}\n\n")
|
||||
rv = self.class.iproute(['-f', 'inet', 'route', 'show'])
|
||||
warn("#{rv.join("\n")}\n\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -233,37 +224,6 @@ Puppet::Type.type(:l3_ifconfig).provide(:lnx) do
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
def self.get_if_addr_mappings
|
||||
if_list = {}
|
||||
ip_a = iproute('-f', 'inet', 'addr', 'show').split(/\n+/)
|
||||
if_name = nil
|
||||
ip_a.each do |line|
|
||||
line.rstrip!
|
||||
case line
|
||||
when /^\s*\d+\:\s+([\w\-\.]+)[\:\@]/i
|
||||
if_name = $1
|
||||
if_list[if_name] = { :ipaddr => [] }
|
||||
when /^\s+inet\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2})/
|
||||
next if if_name.nil?
|
||||
if_list[if_name][:ipaddr] << $1
|
||||
else
|
||||
next
|
||||
end
|
||||
end
|
||||
return if_list
|
||||
end
|
||||
|
||||
def self.get_if_defroutes_mappings
|
||||
rou_list = {}
|
||||
ip_a = iproute('-f', 'inet', 'route', 'show').split(/\n+/)
|
||||
ip_a.each do |line|
|
||||
line.rstrip!
|
||||
next if !line.match(/^\s*default\s+via\s+([\d\.]+)\s+dev\s+([\w\-\.]+)(\s+metric\s+(\d+))?/)
|
||||
metric = $4.nil? ? :absent : $4.to_i
|
||||
rou_list[$2] = { :gateway => $1, :gateway_metric => metric } if rou_list[$2].nil? # do not replace to gateway with highest metric
|
||||
end
|
||||
return rou_list
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -1,62 +1,10 @@
|
||||
require 'ipaddr'
|
||||
require 'yaml'
|
||||
require 'puppetx/l23_utils'
|
||||
# require 'yaml'
|
||||
# require 'puppetx/l23_utils'
|
||||
require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/l3_base')
|
||||
|
||||
Puppet::Type.type(:l3_route).provide(:lnx) do
|
||||
Puppet::Type.type(:l3_route).provide(:lnx, :parent => Puppet::Provider::L3_base) do
|
||||
defaultfor :osfamily => :linux
|
||||
commands :iproute => 'ip'
|
||||
|
||||
|
||||
def self.prefetch(resources)
|
||||
interfaces = instances
|
||||
resources.keys.each do |name|
|
||||
if provider = interfaces.find{ |ii| ii.name == name }
|
||||
resources[name].provider = provider
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_routes
|
||||
# return array of hashes -- all defined routes.
|
||||
rv = []
|
||||
# cat /proc/net/route returns information about routing table in format:
|
||||
# Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||
# eth0 00000000 0101010A 0003 0 0 0 00000000 0 0 0
|
||||
# eth0 0001010A 00000000 0001 0 0 0 00FFFFFF 0 0 0
|
||||
File.open('/proc/net/route').readlines.reject{|l| l.match(/^[Ii]face.+/) or l.match(/^(\r\n|\n|\s*)$|^$/)}.map{|l| l.split(/\s+/)}.each do |line|
|
||||
#https://github.com/kwilczynski/facter-facts/blob/master/default_gateway.rb
|
||||
iface = line[0]
|
||||
metric = line[6]
|
||||
# whether gateway is default
|
||||
if line[1] == '00000000'
|
||||
dest = 'default'
|
||||
dest_addr = nil
|
||||
mask = nil
|
||||
route_type = 'default'
|
||||
else
|
||||
dest_addr = [line[1]].pack('H*').unpack('C4').reverse.join('.')
|
||||
mask = [line[7]].pack('H*').unpack('B*')[0].count('1')
|
||||
dest = "#{dest_addr}/#{mask}"
|
||||
end
|
||||
# whether route is local
|
||||
if line[2] == '00000000'
|
||||
gateway = nil
|
||||
route_type = 'local'
|
||||
else
|
||||
gateway = [line[2]].pack('H*').unpack('C4').reverse.join('.')
|
||||
route_type = nil
|
||||
end
|
||||
rv << {
|
||||
:destination => dest,
|
||||
:gateway => gateway,
|
||||
:metric => metric.to_i,
|
||||
:type => route_type,
|
||||
:interface => iface,
|
||||
}
|
||||
end
|
||||
# this sort need for prioritize routes by metrics
|
||||
return rv.sort_by{|r| r[:metric]||0}
|
||||
end
|
||||
|
||||
def self.instances
|
||||
rv = []
|
||||
@@ -86,7 +34,7 @@ Puppet::Type.type(:l3_route).provide(:lnx) do
|
||||
cmd = ['route', 'add', @resource[:destination], 'via', @resource[:gateway]]
|
||||
cmd << ['metric', @resource[:metric]] if @resource[:metric] != :absent && @resource[:metric].to_i > 0
|
||||
begin
|
||||
iproute(cmd)
|
||||
self.class.iproute(cmd)
|
||||
rescue Exception => e
|
||||
if e.to_s =~ /File\s+exists/
|
||||
notice("Route for '#{@resource[:destination]}' via #{@resource[:gateway]} already exists. Use existing...")
|
||||
@@ -104,7 +52,7 @@ Puppet::Type.type(:l3_route).provide(:lnx) do
|
||||
debug("DESTROY resource: #{@resource}")
|
||||
cmd = ['--force', 'route', 'del', @property_hash[:destination], 'via', @property_hash[:gateway]]
|
||||
cmd << ['metric', @property_hash[:metric]] if @property_hash[:metric] != :absent && @property_hash[:metric].to_i > 0
|
||||
iproute(cmd)
|
||||
self.class.iproute(cmd)
|
||||
@property_hash.clear
|
||||
end
|
||||
|
||||
@@ -127,7 +75,7 @@ Puppet::Type.type(:l3_route).provide(:lnx) do
|
||||
cmd = ['route', 'change', @resource[:destination], 'via', @property_flush[:gateway]]
|
||||
cmd << ['metric', @resource[:metric]] if @resource[:metric] != :absent && @resource[:metric].to_i > 0
|
||||
begin
|
||||
iproute(cmd)
|
||||
self.class.iproute(cmd)
|
||||
rescue Exception => e
|
||||
if e.to_s =~ /File\s+exists/
|
||||
notice("Route for '#{@resource[:destination]}' via #{@property_flush[:gateway]} already exists. Use existing...")
|
||||
|
||||
@@ -221,6 +221,23 @@ Puppet::Type.newtype(:l23_stored_config) do
|
||||
newproperty(:bond_lacp_rate)
|
||||
newproperty(:bond_xmit_hash_policy)
|
||||
|
||||
newproperty(:bond_updelay) do
|
||||
newvalues(/^\d+$/)
|
||||
end
|
||||
|
||||
newproperty(:bond_downdelay) do
|
||||
newvalues(/^\d+$/)
|
||||
end
|
||||
|
||||
newproperty(:bond_ad_select) do
|
||||
validate do |val|
|
||||
allowed_values = ['0','1','2','stable','bandwidth','count']
|
||||
if ! allowed_values.include? val.to_s
|
||||
raise ArgumentError, "'#{val}' is not a valid bond_ad_select. Only #{allowed_values.join(', ')} allowed.)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# # `:options` provides an arbitrary passthrough for provider properties, so
|
||||
# # that provider specific behavior doesn't clutter up the main type but still
|
||||
# # allows for more powerful actions to be taken.
|
||||
|
||||
@@ -72,6 +72,12 @@ define l23network::l2::bond (
|
||||
'active'
|
||||
]
|
||||
|
||||
$ad_select_states = [
|
||||
'stable',
|
||||
'bandwidth',
|
||||
'count'
|
||||
]
|
||||
|
||||
# calculate string representation for bond_mode
|
||||
if ! $bond_properties[mode] {
|
||||
# default value by design https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
@@ -82,48 +88,73 @@ define l23network::l2::bond (
|
||||
$bond_mode = $bond_properties[mode]
|
||||
}
|
||||
|
||||
# calculate string representation for lacp_rate
|
||||
if $bond_mode == '802.3ad' {
|
||||
if is_integer($bond_properties[lacp_rate]) and $bond_properties[lacp_rate] < size($lacp_rates) {
|
||||
$lacp_rate = $lacp_rates[$bond_properties[lacp_rate]]
|
||||
} else {
|
||||
# default value by design https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
$lacp_rate = pick($bond_properties[lacp_rate], $lacp_rates[0])
|
||||
}
|
||||
}
|
||||
|
||||
# calculate default miimon
|
||||
if is_integer($bond_properties[miimon]) and $bond_properties[miimon] >= 0 {
|
||||
$miimon = $bond_properties[miimon]
|
||||
} else {
|
||||
# recommended default value https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
$miimon = 100
|
||||
# init default bond properties hash
|
||||
$default_bond_properties = {
|
||||
mode => $bond_mode,
|
||||
}
|
||||
|
||||
# calculate string representation for xmit_hash_policy
|
||||
if ( $bond_mode == '802.3ad' or $bond_mode == 'balance-xor' or $bond_mode == 'balance-tlb') {
|
||||
if ! $bond_properties[xmit_hash_policy] {
|
||||
# default value by design https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
$xmit_hash_policy = $xmit_hash_policies[0]
|
||||
$default_bond_properties[xmit_hash_policy] = $xmit_hash_policies[0]
|
||||
} else {
|
||||
$xmit_hash_policy = $bond_properties[xmit_hash_policy]
|
||||
$default_bond_properties[xmit_hash_policy] = $bond_properties[xmit_hash_policy]
|
||||
}
|
||||
}
|
||||
|
||||
if ! $bond_properties[lacp] {
|
||||
# default value
|
||||
$lacp = $lacp_states[0]
|
||||
} else {
|
||||
$lacp = $bond_properties[lacp]
|
||||
# non-lacp
|
||||
$default_bond_properties[xmit_hash_policy] = undef
|
||||
}
|
||||
|
||||
# default bond properties
|
||||
$default_bond_properties = {
|
||||
mode => $bond_mode,
|
||||
miimon => $miimon,
|
||||
lacp_rate => $lacp_rate,
|
||||
lacp => $lacp,
|
||||
xmit_hash_policy => $xmit_hash_policy
|
||||
# calculate string representation for lacp_rate
|
||||
if $bond_mode == '802.3ad' or ($provider == 'ovs' and ( $bond_properties[lacp] == 'active' or $bond_properties[lacp] == 'passive')) {
|
||||
if is_integer($bond_properties[lacp_rate]) and $bond_properties[lacp_rate] < size($lacp_rates) {
|
||||
$default_bond_properties[lacp_rate] = $lacp_rates[$bond_properties[lacp_rate]]
|
||||
} else {
|
||||
# default value by design https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
$default_bond_properties[lacp_rate] = pick($bond_properties[lacp_rate], $lacp_rates[0])
|
||||
}
|
||||
if $provider == 'ovs' {
|
||||
$default_bond_properties[lacp] = $bond_properties[lacp]
|
||||
} else {
|
||||
$default_bond_properties[lacp] = undef
|
||||
}
|
||||
} else {
|
||||
$default_bond_properties[lacp_rate] = undef
|
||||
$default_bond_properties[lacp] = undef
|
||||
}
|
||||
|
||||
# calculate default miimon
|
||||
if is_integer($bond_properties[miimon]) and $bond_properties[miimon] >= 0 {
|
||||
$default_bond_properties[miimon] = $bond_properties[miimon]
|
||||
} else {
|
||||
# recommended default value https://www.kernel.org/doc/Documentation/networking/bonding.txt
|
||||
$default_bond_properties[miimon] = 100
|
||||
}
|
||||
|
||||
# calculate default updelay
|
||||
if is_integer($bond_properties[updelay]) and $bond_properties[updelay] >= 0 {
|
||||
$default_bond_properties[updelay] = $bond_properties[updelay]
|
||||
} else {
|
||||
$default_bond_properties[updelay] = 200
|
||||
}
|
||||
|
||||
# calculate default downdelay
|
||||
if is_integer($bond_properties[downdelay]) and $bond_properties[downdelay] >= 0 {
|
||||
$default_bond_properties[downdelay] = $bond_properties[downdelay]
|
||||
} else {
|
||||
$default_bond_properties[downdelay] = 200
|
||||
}
|
||||
|
||||
# calculate default ad_select
|
||||
if $bond_properties[ad_select] {
|
||||
if is_integer($bond_properties[ad_select]) {
|
||||
$default_bond_properties[ad_select] = $ad_select_states[$bond_properties[ad_select]]
|
||||
} else {
|
||||
$default_bond_properties[ad_select] = $bond_properties[ad_select]
|
||||
}
|
||||
} else {
|
||||
$default_bond_properties[ad_select] = $ad_select_states[1]
|
||||
}
|
||||
|
||||
$real_bond_properties = merge($bond_properties, $default_bond_properties)
|
||||
@@ -196,6 +227,9 @@ define l23network::l2::bond (
|
||||
bond_lacp => $real_bond_properties[lacp],
|
||||
bond_lacp_rate => $real_bond_properties[lacp_rate],
|
||||
bond_xmit_hash_policy => $real_bond_properties[xmit_hash_policy],
|
||||
bond_downdelay => $real_bond_properties[downdelay],
|
||||
bond_updelay => $real_bond_properties[updelay],
|
||||
bond_ad_select => $real_bond_properties[ad_select],
|
||||
delay_while_up => $delay_while_up,
|
||||
vendor_specific => $vendor_specific,
|
||||
provider => $config_provider
|
||||
|
||||
@@ -107,13 +107,17 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
end
|
||||
|
||||
|
||||
context 'Just create a lnx-bond with specific MTU' do
|
||||
context 'Create a lnx-bond with specific parameters' do
|
||||
let(:params) do
|
||||
{
|
||||
:name => 'bond0',
|
||||
:interfaces => ['eth3', 'eth4'],
|
||||
:mtu => 9000,
|
||||
:bond_properties => {},
|
||||
:bond_properties => {
|
||||
'updelay' => '111',
|
||||
'downdelay' => '222',
|
||||
'ad_select' => '2',
|
||||
},
|
||||
:provider => 'lnx'
|
||||
}
|
||||
end
|
||||
@@ -124,7 +128,10 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
|
||||
it do
|
||||
should contain_l23_stored_config('bond0').with({
|
||||
'mtu' => 9000,
|
||||
'mtu' => 9000,
|
||||
'bond_updelay' => '111',
|
||||
'bond_downdelay' => '222',
|
||||
'bond_ad_select' => 'count',
|
||||
})
|
||||
end
|
||||
|
||||
@@ -211,10 +218,10 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
'ensure' => 'present',
|
||||
'if_type' => 'bond',
|
||||
'bond_mode' => 'active-backup',
|
||||
'bond_lacp_rate' => nil,
|
||||
'bond_xmit_hash_policy' => nil,
|
||||
'bond_miimon' => '100',
|
||||
})
|
||||
should contain_l23_stored_config('bond0').without_bond_lacp_rate()
|
||||
should contain_l23_stored_config('bond0').without_bond_xmit_hash_policy()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -225,6 +232,7 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
:interfaces => ['eth3', 'eth4'],
|
||||
:bond_properties => {
|
||||
'mode' => 'balance-tlb',
|
||||
'lacp' => 'active',
|
||||
'lacp_rate' => 'fast',
|
||||
'xmit_hash_policy' => 'layer2+3',
|
||||
'miimon' => '300',
|
||||
@@ -242,10 +250,11 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
'ensure' => 'present',
|
||||
'if_type' => 'bond',
|
||||
'bond_mode' => 'balance-tlb',
|
||||
'bond_lacp_rate' => nil,
|
||||
'bond_xmit_hash_policy' => 'layer2+3',
|
||||
'bond_miimon' => '300',
|
||||
})
|
||||
should contain_l23_stored_config('bond0').without_bond_lacp() # because 'lacp' -- only OVS property
|
||||
should contain_l23_stored_config('bond0').without_bond_lacp_rate() # because 'balance-tlb' is non-lacp mode
|
||||
end
|
||||
end
|
||||
|
||||
@@ -272,14 +281,15 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
end
|
||||
end
|
||||
|
||||
context 'Create a ovs-bond with mode = balance-tlb, lacp_rate = fast xmit_hash_policy = layer2+3' do
|
||||
context 'Create a ovs-bond with mode = balance-tcp, lacp_rate = fast xmit_hash_policy = layer2+3' do
|
||||
let(:params) do
|
||||
{
|
||||
:name => 'bond-ovs',
|
||||
:interfaces => ['eth2', 'eth3'],
|
||||
:bridge => 'br-bond-ovs',
|
||||
:bond_properties => {
|
||||
'mode' => 'balance-tlb',
|
||||
'mode' => 'balance-tcp',
|
||||
'lacp' => 'active',
|
||||
'lacp_rate' => 'fast',
|
||||
'xmit_hash_policy' => 'layer2+3',
|
||||
'miimon' => '300',
|
||||
@@ -320,22 +330,29 @@ describe 'l23network::l2::bond', :type => :define do
|
||||
'bridge' => 'br-bond-ovs',
|
||||
'if_type' => 'bond',
|
||||
'bond_lacp' => 'off',
|
||||
'bond_mode' => 'balance-tlb',
|
||||
'bond_lacp_rate' => nil,
|
||||
'bond_xmit_hash_policy' => 'layer2+3',
|
||||
'bond_mode' => 'balance-tcp',
|
||||
'bond_lacp' => 'active',
|
||||
'bond_lacp_rate' => 'fast',
|
||||
'bond_miimon' => '300',
|
||||
'bond_updelay' => '200',
|
||||
'bond_downdelay' => '200',
|
||||
'bond_ad_select' => 'bandwidth',
|
||||
})
|
||||
should contain_l23_stored_config('bond-ovs').without_bond_xmit_hash_policy()
|
||||
end
|
||||
|
||||
it do
|
||||
should contain_l2_bond('bond-ovs').with({
|
||||
'bond_properties' => {
|
||||
:mode => 'balance-tlb',
|
||||
:lacp => 'off',
|
||||
:lacp_rate => :undef,
|
||||
:xmit_hash_policy => 'layer2+3',
|
||||
:miimon => '300',
|
||||
},
|
||||
:mode => 'balance-tcp',
|
||||
:lacp => 'active',
|
||||
:lacp_rate => 'fast',
|
||||
:miimon => '300',
|
||||
:xmit_hash_policy => :undef,
|
||||
:updelay =>"200",
|
||||
:downdelay =>"200",
|
||||
:ad_select =>"bandwidth",
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -5,4 +5,7 @@ iface bond0 inet manual
|
||||
bond-miimon 50
|
||||
bond-lacp-rate fast
|
||||
bond-slaves eth2 eth3
|
||||
bond-xmit-hash-policy encap3+4
|
||||
bond-xmit-hash-policy encap3+4
|
||||
bond-updelay 111
|
||||
bond-downdelay 222
|
||||
bond-ad-select 2
|
||||
|
||||
@@ -4,4 +4,4 @@ iface bond_lacp inet manual
|
||||
ovs_bonds eth2 eth3
|
||||
ovs_type OVSBond
|
||||
ovs_bridge br0
|
||||
ovs_options bond_mode=balance-tcp lacp=active other_config:lacp-time=fast other_config:bond-miimon-interval=50
|
||||
ovs_options bond_mode=balance-tcp bond_updelay=111 bond_downdelay=222 lacp=active other_config:lacp-time=fast other_config:bond-miimon-interval=50
|
||||
@@ -18,6 +18,9 @@ describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
|
||||
:bond_miimon => '50',
|
||||
:bond_lacp_rate => 'fast',
|
||||
:bond_lacp => 'passive', # used only for OVS bonds. Should do nothing for lnx.
|
||||
:bond_updelay => '111',
|
||||
:bond_downdelay => '222',
|
||||
:bond_ad_select => '2',
|
||||
:provider => "lnx_ubuntu",
|
||||
},
|
||||
}
|
||||
@@ -74,7 +77,7 @@ describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
|
||||
# end
|
||||
# end
|
||||
|
||||
context "OVS bond with two interfaces" do
|
||||
context "LNX bond with two interfaces" do
|
||||
|
||||
context 'format file' do
|
||||
subject { providers[:bond0] }
|
||||
@@ -86,8 +89,11 @@ describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
|
||||
it { expect(cfg_file).to match(/bond-lacp-rate\s+fast/) }
|
||||
it { expect(cfg_file).to match(/bond-mode\s+802\.3ad/) }
|
||||
it { expect(cfg_file).to match(/bond-miimon\s+50/) }
|
||||
it { expect(cfg_file).to match(/bond-updelay\s+111/) }
|
||||
it { expect(cfg_file).to match(/bond-downdelay\s+222/) }
|
||||
it { expect(cfg_file).to match(/bond-ad-select\s+2/) }
|
||||
it { expect(cfg_file).to match(/bond-xmit-hash-policy\s+encap3\+4/) }
|
||||
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(8) } # no more lines in the interface file
|
||||
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(11) } # no more lines in the interface file
|
||||
end
|
||||
|
||||
context "parse data from fixture" do
|
||||
@@ -101,6 +107,9 @@ describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
|
||||
it { expect(res[:bond_miimon]).to eq '50' }
|
||||
it { expect(res[:bond_lacp_rate]).to eq 'fast' }
|
||||
it { expect(res[:bond_lacp]).to eq nil }
|
||||
it { expect(res[:bond_updelay]).to eq '111' }
|
||||
it { expect(res[:bond_downdelay]).to eq '222' }
|
||||
it { expect(res[:bond_ad_select]).to eq '2' }
|
||||
it { expect(res[:bond_slaves]).to eq ['eth2', 'eth3'] }
|
||||
it { expect(res[:bond_xmit_hash_policy]).to eq 'encap3+4' }
|
||||
end
|
||||
|
||||
@@ -18,6 +18,9 @@ describe Puppet::Type.type(:l23_stored_config).provider(:ovs_ubuntu) do
|
||||
:bond_miimon => '50',
|
||||
:bond_lacp_rate => 'fast',
|
||||
:bond_lacp => 'active',
|
||||
:bond_updelay => '111',
|
||||
:bond_downdelay => '222',
|
||||
:bond_ad_select => '2', # unused for OVS
|
||||
:provider => "ovs_ubuntu",
|
||||
},
|
||||
}
|
||||
@@ -89,6 +92,8 @@ describe Puppet::Type.type(:l23_stored_config).provider(:ovs_ubuntu) do
|
||||
it { expect(cfg_file).to match(/ovs_options.+bond_mode=balance-tcp/) }
|
||||
it { expect(cfg_file).to match(/ovs_options.+other_config:lacp-time=fast/) }
|
||||
it { expect(cfg_file).to match(/ovs_options.+other_config:bond-miimon-interval=50/) }
|
||||
it { expect(cfg_file).to match(/ovs_options.+bond_updelay=111/) }
|
||||
it { expect(cfg_file).to match(/ovs_options.+bond_downdelay=222/) }
|
||||
it { expect(cfg_file).to match(/ovs_options.+lacp=active/) }
|
||||
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(7) } # no more lines in the interface file
|
||||
|
||||
@@ -106,6 +111,8 @@ describe Puppet::Type.type(:l23_stored_config).provider(:ovs_ubuntu) do
|
||||
it { expect(res[:bond_miimon]).to eq '50' }
|
||||
it { expect(res[:bond_lacp_rate]).to eq 'fast' }
|
||||
it { expect(res[:bond_lacp]).to eq 'active' }
|
||||
it { expect(res[:bond_updelay]).to eq '111' }
|
||||
it { expect(res[:bond_downdelay]).to eq '222' }
|
||||
it { expect(res[:bond_slaves]).to eq ['eth2', 'eth3'] }
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Puppet::Type.type(:l2_bond).provider(:lnx) do
|
||||
|
||||
let(:resource) {
|
||||
Puppet::Type.type(:l2_bond).new(
|
||||
:provider => :lnx,
|
||||
:name => 'bond1',
|
||||
:slaves => ['eth1', 'eth2'],
|
||||
:bond_properties => {
|
||||
'mode' => '802.3ad',
|
||||
'lacp_rate' => 'fast',
|
||||
'xmit_hash_policy' => 'layer2+3',
|
||||
'updelay' => '111',
|
||||
'downdelay' => '222',
|
||||
'ad_select' => '2',
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
let(:provider) { resource.provider }
|
||||
let(:instance) { provider.class.instances }
|
||||
|
||||
describe "lnx bond" do
|
||||
before(:each) do
|
||||
if ENV['SPEC_PUPPET_DEBUG']
|
||||
Puppet::Util::Log.level = :debug
|
||||
Puppet::Util::Log.newdestination(:console)
|
||||
end
|
||||
provider.class.stubs(:iproute).with('addr', 'flush', 'dev', 'eth1').returns(true)
|
||||
provider.class.stubs(:iproute).with('addr', 'flush', 'dev', 'eth2').returns(true)
|
||||
end
|
||||
|
||||
it "Just create bond, which unify two NICs" do
|
||||
provider.create
|
||||
#provider.flush
|
||||
end
|
||||
|
||||
it "Create bond and setup required properties" do
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bonding_masters', '+bond1').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with("/sys/class/net/bond1/bonding/slaves", true).returns([])
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/slaves', '+eth1').returns(true)
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/slaves', '+eth2').returns(true)
|
||||
provider.class.stubs(:set_interface_down).with('bond1').returns(true)
|
||||
provider.class.stubs(:set_interface_down).with('bond1', true).returns(true)
|
||||
provider.class.stubs(:set_interface_down).with('eth1').returns(true)
|
||||
provider.class.stubs(:set_interface_down).with('eth2').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/mode').returns('802.3ad')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/mode', '802.3ad').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/xmit_hash_policy').returns('layer2')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/xmit_hash_policy', 'layer2+3').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/lacp_rate').returns('slow')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/lacp_rate', 'fast').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/ad_select').returns('stable')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/ad_select', '2').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/updelay').returns('0')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/updelay', '111').returns(true)
|
||||
provider.class.stubs(:get_sys_class).with('/sys/class/net/bond1/bonding/downdelay').returns('0')
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bond1/bonding/downdelay', '222').returns(true)
|
||||
provider.class.stubs(:set_interface_up).with('bond1').returns(true)
|
||||
provider.class.stubs(:set_interface_up).with('eth1').returns(true)
|
||||
provider.class.stubs(:set_interface_up).with('eth2').returns(true)
|
||||
provider.create
|
||||
#leave here as template for future
|
||||
#provider.expects(:warn).with { |arg| arg =~ /lnx\s+don't\s+allow\s+change\s+bond\s+slaves/ }
|
||||
provider.flush
|
||||
end
|
||||
|
||||
it "Delete existing bond" do
|
||||
provider.class.stubs(:set_sys_class).with('/sys/class/net/bonding_masters', '-bond1').returns(true)
|
||||
provider.destroy
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -9,9 +9,10 @@ describe Puppet::Type.type(:l2_bond).provider(:ovs) do
|
||||
:bridge => 'br1',
|
||||
:slaves => ['eth1', 'eth2'],
|
||||
:bond_properties => {
|
||||
'mode' => 'balance-slb',
|
||||
'lacp_rate' => 'fast',
|
||||
#'xmit_hash_policy' => 'layer2',
|
||||
'mode' => 'balance-slb',
|
||||
'lacp_rate' => 'fast',
|
||||
'updelay' => 111,
|
||||
'downdelay' => 222,
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -35,6 +36,8 @@ describe Puppet::Type.type(:l2_bond).provider(:ovs) do
|
||||
it "Create bond and setup required properties" do
|
||||
provider.class.expects(:vsctl).with('--', 'set', 'Port', 'bond1', 'bond_mode=balance-slb').returns(true)
|
||||
provider.class.expects(:vsctl).with('--', 'set', 'Port', 'bond1', 'other_config:lacp_time=fast').returns(true)
|
||||
provider.class.expects(:vsctl).with('--', 'set', 'Port', 'bond1', 'bond_updelay=111').returns(true)
|
||||
provider.class.expects(:vsctl).with('--', 'set', 'Port', 'bond1', 'bond_downdelay=222').returns(true)
|
||||
provider.create
|
||||
provider.expects(:warn).with { |arg| arg =~ /OVS\s+don't\s+allow\s+change\s+bond\s+slaves/ }
|
||||
provider.flush
|
||||
|
||||
@@ -18,20 +18,20 @@ describe Puppet::Type.type(:l3_ifconfig).provider(:lnx) do
|
||||
|
||||
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(:arping).with(['-A', '-c 32', '-w 2', '-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.class.stubs(:arping).with(['-D', '-f', '-c 32', '-w 2', '-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, """
|
||||
provider.class.stubs(:arping).with(['-D', '-f', '-c 32', '-w 2', '-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))
|
||||
@@ -43,7 +43,7 @@ Received 1 response(s)
|
||||
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.class.stubs(:arping).with(['-D', '-f', '-c 32', '-w 2', '-I', 'eth1', '10.99.1.4']).raises(Puppet::ExecutionFailure, '')
|
||||
provider.create
|
||||
expect{provider.flush}.to raise_error(Puppet::ExecutionFailure)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user