Merge "Lnx2Lnx patchcord implementation for ubuntu"
This commit is contained in:
commit
b9f8c28f0e
@ -5,6 +5,7 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
|
|||||||
|
|
||||||
def self.iproute(*cmd)
|
def self.iproute(*cmd)
|
||||||
actual_cmd = ['ip'] + Array(*cmd)
|
actual_cmd = ['ip'] + Array(*cmd)
|
||||||
|
debug("iproute: run the command #{actual_cmd.join(' ')}")
|
||||||
rv = []
|
rv = []
|
||||||
IO.popen(actual_cmd.join(' ') + ' 2>&1') do |ff|
|
IO.popen(actual_cmd.join(' ') + ' 2>&1') do |ff|
|
||||||
rv = ff.readlines().map{|l| l.chomp()}
|
rv = ff.readlines().map{|l| l.chomp()}
|
||||||
@ -29,6 +30,33 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
|
|||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.brctl(*cmd)
|
||||||
|
actual_cmd = ['brctl'] + 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.ethtool(*cmd)
|
||||||
|
actual_cmd = ['ethtool'] + Array(*cmd)
|
||||||
|
rv = []
|
||||||
|
debug(actual_cmd.join(' ') + ' 2>&1')
|
||||||
|
IO.popen(actual_cmd.join(' ') + ' 2>&1') do |ff|
|
||||||
|
rv = ff.readlines().map{|l| l.chomp()}
|
||||||
|
ff.close
|
||||||
|
if 0 != $?.exitstatus and 94 != $?.exitstatus # 94 is a 'no stats available'. it's a not error.
|
||||||
|
rv = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
def self.iface_exist?(iface)
|
def self.iface_exist?(iface)
|
||||||
@ -71,6 +99,21 @@ class Puppet::Provider::InterfaceToolset < Puppet::Provider
|
|||||||
end
|
end
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
def self.get_iface_peer_index(iface)
|
||||||
|
# returns:
|
||||||
|
# N -- ifindex of peer interface
|
||||||
|
# nil -- interface in not an veth pair jack
|
||||||
|
cmd = ['-S', iface]
|
||||||
|
begin
|
||||||
|
rv = ethtool(cmd)
|
||||||
|
rescue Exception => e
|
||||||
|
debug("Non-fatal-Error: Can't run ethtool for interface '#{iface}': #{e.message}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
rv = rv.select{|l| l =~ /\s*peer_ifindex\:\s+\d+/}[0]
|
||||||
|
(rv.nil? ? nil : rv.split(':')[-1].strip.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
def self.get_iface_state(iface)
|
def self.get_iface_state(iface)
|
||||||
# returns:
|
# returns:
|
||||||
# true -- interface in UP state
|
# true -- interface in UP state
|
||||||
|
@ -78,6 +78,11 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
|||||||
:detect_re => /(post-)?up\s+sleep\s+(\d+)/,
|
:detect_re => /(post-)?up\s+sleep\s+(\d+)/,
|
||||||
:detect_shift => 2,
|
:detect_shift => 2,
|
||||||
},
|
},
|
||||||
|
:jacks => {
|
||||||
|
# pre-up ip link add p_33470efd-0 type veth peer name p_33470efd-1
|
||||||
|
:detect_re => /pre-up\s+ip\s+link\s+add\s+([\w\-]+)\s+type\s+veth\s+peer\s+name\s+([\w\-]+)/,
|
||||||
|
:detect_shift => 1,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
def collected_properties
|
def collected_properties
|
||||||
@ -200,15 +205,18 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
|||||||
# # todo(sv): Make more powerful methodology for recognizind Bridges.
|
# # todo(sv): Make more powerful methodology for recognizind Bridges.
|
||||||
# hash['if_type'] = :bridge
|
# hash['if_type'] = :bridge
|
||||||
# end
|
# end
|
||||||
when /bridge-ports/
|
when /bridge[-_]ports/
|
||||||
hash['if_type'] = :bridge
|
hash['if_type'] = :bridge
|
||||||
hash[key] = val
|
hash[key] = val
|
||||||
when /bond-(slaves|mode)/
|
when /bond[-_](slaves|mode)/
|
||||||
hash['if_type'] = :bond
|
hash['if_type'] = :bond
|
||||||
hash[key] = val
|
hash[key] = val
|
||||||
else
|
else
|
||||||
hash[key] = val
|
hash[key] = val
|
||||||
end
|
end
|
||||||
|
if val =~ /\s+type\s+veth\s+/
|
||||||
|
hash['if_type'] = :patch
|
||||||
|
end
|
||||||
else
|
else
|
||||||
raise Puppet::Error, %{#{filename} is malformed; "#{line}" did not match "#{pair_regex.to_s}"}
|
raise Puppet::Error, %{#{filename} is malformed; "#{line}" did not match "#{pair_regex.to_s}"}
|
||||||
end
|
end
|
||||||
@ -382,6 +390,10 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
|||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.mangle__jacks(data)
|
||||||
|
[data[0][0], data[0][1]]
|
||||||
|
end
|
||||||
|
|
||||||
###
|
###
|
||||||
# Hash to file
|
# Hash to file
|
||||||
|
|
||||||
@ -420,7 +432,7 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
|||||||
#add to content unmangled collected-properties
|
#add to content unmangled collected-properties
|
||||||
collected_properties.keys.each do |type_name|
|
collected_properties.keys.each do |type_name|
|
||||||
data = provider.send(type_name)
|
data = provider.send(type_name)
|
||||||
if ((!data.nil? or !data.empty?) and data.to_s != 'absent')
|
if ! ['', 'absent'].include? data.to_s
|
||||||
mangle_method_name="unmangle__#{type_name}"
|
mangle_method_name="unmangle__#{type_name}"
|
||||||
if self.respond_to?(mangle_method_name)
|
if self.respond_to?(mangle_method_name)
|
||||||
rv = self.send(mangle_method_name, provider, data)
|
rv = self.send(mangle_method_name, provider, data)
|
||||||
@ -556,5 +568,12 @@ class Puppet::Provider::L23_stored_config_ubuntu < Puppet::Provider::L23_stored_
|
|||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.unmangle__jacks(provider, data)
|
||||||
|
rv = []
|
||||||
|
rv << "pre-up ip link add #{data[0]} type veth peer name #{data[1]}"
|
||||||
|
rv << "post-up ip link set up dev #{data[1]}"
|
||||||
|
rv << "post-down ip link del #{data[0]}"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
# vim: set ts=2 sw=2 et :
|
# vim: set ts=2 sw=2 et :
|
||||||
|
@ -60,11 +60,17 @@ class Puppet::Provider::L2_base < Puppet::Provider::InterfaceToolset
|
|||||||
:port_type => [],
|
:port_type => [],
|
||||||
:onboot => self.get_iface_state(if_name),
|
:onboot => self.get_iface_state(if_name),
|
||||||
:ethtool => nil,
|
:ethtool => nil,
|
||||||
|
:peer_ifindex => nil,
|
||||||
|
:ifindex => File.open("#{if_dir}/ifindex").read.chomp.to_i,
|
||||||
:mtu => File.open("#{if_dir}/mtu").read.chomp.to_i,
|
:mtu => File.open("#{if_dir}/mtu").read.chomp.to_i,
|
||||||
:provider => (if_name == 'ovs-system') ? 'ovs' : 'lnx' ,
|
:provider => (if_name == 'ovs-system') ? 'ovs' : 'lnx' ,
|
||||||
}
|
}
|
||||||
# determine port_type for this iface
|
# determine port_type for this iface
|
||||||
if File.directory? "#{if_dir}/bonding"
|
peer_ifindex = self.get_iface_peer_index(if_name)
|
||||||
|
if !peer_ifindex.nil?
|
||||||
|
port[if_name][:port_type] << 'jack' << 'unremovable'
|
||||||
|
port[if_name][:peer_ifindex] = peer_ifindex
|
||||||
|
elsif File.directory? "#{if_dir}/bonding"
|
||||||
# This interface is a baster of bond, get bonding properties
|
# This interface is a baster of bond, get bonding properties
|
||||||
port[if_name][:slaves] = File.open("#{if_dir}/bonding/slaves").read.chomp.strip.split(/\s+/).sort
|
port[if_name][:slaves] = File.open("#{if_dir}/bonding/slaves").read.chomp.strip.split(/\s+/).sort
|
||||||
port[if_name][:port_type] << 'bond' << 'unremovable'
|
port[if_name][:port_type] << 'bond' << 'unremovable'
|
||||||
@ -365,7 +371,7 @@ class Puppet::Provider::L2_base < Puppet::Provider::InterfaceToolset
|
|||||||
re_c = /([\w\-]+)\s+\d+/
|
re_c = /([\w\-]+)\s+\d+/
|
||||||
begin
|
begin
|
||||||
# todo(sv): using port_list instead fork subprocess
|
# todo(sv): using port_list instead fork subprocess
|
||||||
brctl('show').split(/\n+/).select{|l| l.match(re_c)}.collect{|a| $1 if a.match(re_c)}.each do |br_name|
|
self.brctl(['show']).select{|l| l.match(re_c)}.collect{|a| $1 if a.match(re_c)}.each do |br_name|
|
||||||
br_name.strip!
|
br_name.strip!
|
||||||
bridges[br_name] = {
|
bridges[br_name] = {
|
||||||
:stp => (File.open("/sys/class/net/#{br_name}/bridge/stp_state").read.strip.to_i == 1),
|
:stp => (File.open("/sys/class/net/#{br_name}/bridge/stp_state").read.strip.to_i == 1),
|
||||||
@ -421,7 +427,7 @@ class Puppet::Provider::L2_base < Puppet::Provider::InterfaceToolset
|
|||||||
# (lnx and ovs (with type internal)) included to the lnx bridge
|
# (lnx and ovs (with type internal)) included to the lnx bridge
|
||||||
#
|
#
|
||||||
begin
|
begin
|
||||||
brctl_show = brctl('show').split(/\n+/).select{|l| l.match(/^[\w\-]+\s+\d+/) or l.match(/^\s+[\w\.\-]+/)}
|
brctl_show = self.brctl(['show']).split(/\n+/).select{|l| l.match(/^[\w\-]+\s+\d+/) or l.match(/^\s+[\w\.\-]+/)}
|
||||||
rescue
|
rescue
|
||||||
debug("No LNX bridges found, because error while 'brctl show' execution")
|
debug("No LNX bridges found, because error while 'brctl show' execution")
|
||||||
return {}
|
return {}
|
||||||
|
@ -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
|
Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||||
defaultfor :osfamily => :linux
|
defaultfor :osfamily => :linux
|
||||||
commands :ethtool_cmd => 'ethtool',
|
commands :ethtool_cmd => 'ethtool'
|
||||||
:brctl => 'brctl'
|
|
||||||
|
|
||||||
|
|
||||||
def self.prefetch(resources)
|
def self.prefetch(resources)
|
||||||
@ -192,7 +191,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
|||||||
ovs_vsctl(['del-port', br_name, @resource[:bond]])
|
ovs_vsctl(['del-port', br_name, @resource[:bond]])
|
||||||
# todo catch exception
|
# todo catch exception
|
||||||
when :lnx
|
when :lnx
|
||||||
brctl('delif', br_name, @resource[:bond])
|
self.class.brctl(['delif', br_name, @resource[:bond]])
|
||||||
# todo catch exception
|
# todo catch exception
|
||||||
else
|
else
|
||||||
#pass
|
#pass
|
||||||
@ -205,7 +204,7 @@ Puppet::Type.type(:l2_bond).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
|||||||
when :ovs
|
when :ovs
|
||||||
ovs_vsctl(['add-port', @property_flush[:bridge], @resource[:bond]])
|
ovs_vsctl(['add-port', @property_flush[:bridge], @resource[:bond]])
|
||||||
when :lnx
|
when :lnx
|
||||||
brctl('addif', @property_flush[:bridge], @resource[:bond])
|
self.class.brctl(['addif', @property_flush[:bridge], @resource[:bond]])
|
||||||
else
|
else
|
||||||
#pass
|
#pass
|
||||||
end
|
end
|
||||||
|
@ -8,8 +8,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_ba
|
|||||||
|
|
||||||
Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||||
defaultfor :osfamily => :linux
|
defaultfor :osfamily => :linux
|
||||||
commands :brctl => 'brctl',
|
commands :ethtool_cmd => 'ethtool'
|
||||||
:ethtool_cmd => 'ethtool'
|
|
||||||
|
|
||||||
def self.instances
|
def self.instances
|
||||||
rv = []
|
rv = []
|
||||||
@ -37,7 +36,7 @@ Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_bas
|
|||||||
@old_property_hash = {}
|
@old_property_hash = {}
|
||||||
@property_flush = {}.merge! @resource
|
@property_flush = {}.merge! @resource
|
||||||
begin
|
begin
|
||||||
brctl('addbr', @resource[:bridge])
|
self.class.brctl(['addbr', @resource[:bridge]])
|
||||||
rescue
|
rescue
|
||||||
# Some time interface may be created by OS init scripts. It's a normal for Ubuntu.
|
# Some time interface may be created by OS init scripts. It's a normal for Ubuntu.
|
||||||
raise if ! self.class.iface_exist? @resource[:bridge]
|
raise if ! self.class.iface_exist? @resource[:bridge]
|
||||||
@ -48,7 +47,7 @@ Puppet::Type.type(:l2_bridge).provide(:lnx, :parent => Puppet::Provider::Lnx_bas
|
|||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
self.class.interface_down(@resource[:bridge])
|
self.class.interface_down(@resource[:bridge])
|
||||||
brctl('delbr', @resource[:bridge])
|
self.class.brctl(['delbr', @resource[:bridge]])
|
||||||
end
|
end
|
||||||
|
|
||||||
def flush
|
def flush
|
||||||
|
@ -2,8 +2,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
|||||||
|
|
||||||
Puppet::Type.type(:l2_bridge).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
Puppet::Type.type(:l2_bridge).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||||
commands :vsctl => 'ovs-vsctl',
|
commands :vsctl => 'ovs-vsctl',
|
||||||
:ethtool_cmd => 'ethtool',
|
:ethtool_cmd => 'ethtool'
|
||||||
:brctl => 'brctl'
|
|
||||||
|
|
||||||
def self.skip_port_for?(port_props)
|
def self.skip_port_for?(port_props)
|
||||||
port_props[:br_type] != 'ovs'
|
port_props[:br_type] != 'ovs'
|
||||||
|
141
deployment/puppet/l23network/lib/puppet/provider/l2_patch/lnx.rb
Normal file
141
deployment/puppet/l23network/lib/puppet/provider/l2_patch/lnx.rb
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_base')
|
||||||
|
|
||||||
|
Puppet::Type.type(:l2_patch).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||||
|
defaultfor :osfamily => :linux
|
||||||
|
|
||||||
|
|
||||||
|
def self.instances
|
||||||
|
ports = get_lnx_ports()
|
||||||
|
jacks = []
|
||||||
|
ports.each_pair do |if_name, if_props|
|
||||||
|
next unless if_props[:port_type].include? 'jack'
|
||||||
|
jacks << {
|
||||||
|
:name => if_name,
|
||||||
|
:bridge => if_props[:bridge],
|
||||||
|
:ifindex => if_props[:ifindex],
|
||||||
|
:peer_ifindex => if_props[:peer_ifindex],
|
||||||
|
:mtu => if_props[:mtu],
|
||||||
|
:provider => 'lnx'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# search pairs of jacks and make patchcord resources
|
||||||
|
patches = []
|
||||||
|
skip = []
|
||||||
|
mtu = nil
|
||||||
|
jacks.each do |jack|
|
||||||
|
next if skip.include? jack[:name]
|
||||||
|
# process patch between two bridges
|
||||||
|
found_peer = jacks.select{|j| j[:ifindex]==jack[:peer_ifindex]}
|
||||||
|
next if found_peer.empty?
|
||||||
|
peer = found_peer[0]
|
||||||
|
_bridges = [jack[:bridge], peer[:bridge]].sort
|
||||||
|
_tails = ([jack[:bridge], peer[:bridge]] == _bridges ? [jack[:name], peer[:name]] : [peer[:name], jack[:name]])
|
||||||
|
if _bridges.include? nil
|
||||||
|
_name = "patch__raw__#{_tails[0]}--#{_tails[1]}"
|
||||||
|
else
|
||||||
|
_name = L23network.get_patch_name([jack[:bridge],peer[:bridge]])
|
||||||
|
end
|
||||||
|
props = {
|
||||||
|
:ensure => :present,
|
||||||
|
:name => _name,
|
||||||
|
:bridges => _bridges,
|
||||||
|
:jacks => _tails,
|
||||||
|
:mtu => mtu.to_s,
|
||||||
|
:vlan_ids => ['0','0'], # because veth pairs can't be tagged
|
||||||
|
:provider => 'ovs'
|
||||||
|
}
|
||||||
|
debug("PREFETCH properties for '#{props[:name]}': #{props}")
|
||||||
|
patches << new(props)
|
||||||
|
skip << peer[:name]
|
||||||
|
end
|
||||||
|
return patches
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
debug("CREATE resource: #{@resource}")
|
||||||
|
@old_property_hash = {}
|
||||||
|
@property_flush = {}.merge! @resource
|
||||||
|
patch_name = L23network.get_patch_name(@resource[:jacks])
|
||||||
|
begin
|
||||||
|
self.class.iproute(['link', 'add', 'dev', @resource[:jacks][0], 'type', 'veth', 'peer', 'name', @resource[:jacks][1]])
|
||||||
|
rescue
|
||||||
|
# Some time interface may be created by OS init scripts.
|
||||||
|
raise unless self.class.iface_exist?(@resource[:jacks][0]) & self.class.iface_exist?(@resource[:jacks][1])
|
||||||
|
notice("'#{patch_name}' is already created by ghost event.")
|
||||||
|
end
|
||||||
|
# plug-in jacks to bridges
|
||||||
|
_bridges = self.class.get_bridge_list()
|
||||||
|
self.class.get_bridges_order_for_patch(@resource[:bridges]).each_with_index do |br_name, i|
|
||||||
|
_br = _bridges.fetch(br_name, {})
|
||||||
|
#todo: sv: re-design for call method from bridge provider
|
||||||
|
if _br[:br_type].to_s == 'lnx'
|
||||||
|
self.class.iproute(['link', 'set', 'dev', @resource[:jacks][i], 'master', br_name ])
|
||||||
|
elsif _br[:br_type].to_s == 'ovs'
|
||||||
|
fail("lnx2ovs patchcord '#{patch_name}' is not implemented yet, use ovs2lnx for this purpose!")
|
||||||
|
#self.class.ovs_vsctl(['--may-exist', 'add-port', br_name, @resource[:jacks][i]])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# UP jacks
|
||||||
|
@resource[:jacks].each do |jack_name|
|
||||||
|
self.class.interface_up(jack_name, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
debug("DESTROY resource: #{@resource}")
|
||||||
|
self.class.iproute(['link', 'del', 'dev', @resource[:jacks][0]])
|
||||||
|
end
|
||||||
|
|
||||||
|
def flush
|
||||||
|
if !@property_flush.empty?
|
||||||
|
debug("FLUSH properties: #{@property_flush}")
|
||||||
|
if !['', 'absent'].include? @property_flush[:mtu].to_s
|
||||||
|
# 'absent' is a synonym 'do-not-touch' for MTU
|
||||||
|
@property_hash[:jacks].uniq.each do |iface|
|
||||||
|
self.class.set_mtu(iface, @property_flush[:mtu])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#todo: /sv: make ability of change bridges for RAW patchcords
|
||||||
|
@property_hash = resource.to_hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------
|
||||||
|
def bridges
|
||||||
|
self.class.get_bridges_order_for_patch(@property_hash[:bridges])
|
||||||
|
end
|
||||||
|
def bridges=(val)
|
||||||
|
@property_flush[:bridges] = self.class.get_bridges_order_for_patch(val)
|
||||||
|
end
|
||||||
|
|
||||||
|
def vlan_ids
|
||||||
|
['0', '0']
|
||||||
|
end
|
||||||
|
def vlan_ids=(val)
|
||||||
|
warn("There are no ability for setup VLAN IDs for LNX-patchcords")
|
||||||
|
end
|
||||||
|
|
||||||
|
def mtu
|
||||||
|
'absent'
|
||||||
|
end
|
||||||
|
def mtu=(val)
|
||||||
|
@property_flush[:mtu] = val
|
||||||
|
end
|
||||||
|
|
||||||
|
def jacks
|
||||||
|
@property_hash[:jacks]
|
||||||
|
end
|
||||||
|
def jacks=(val)
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def cross
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
def cross=(val)
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
# vim: set ts=2 sw=2 et :
|
@ -3,8 +3,7 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/ovs_ba
|
|||||||
|
|
||||||
Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base) do
|
||||||
commands :vsctl => 'ovs-vsctl',
|
commands :vsctl => 'ovs-vsctl',
|
||||||
:ethtool_cmd => 'ethtool',
|
:ethtool_cmd => 'ethtool'
|
||||||
:brctl => 'brctl'
|
|
||||||
|
|
||||||
def self.get_instances(big_hash)
|
def self.get_instances(big_hash)
|
||||||
big_hash.fetch(:port, {})
|
big_hash.fetch(:port, {})
|
||||||
@ -57,7 +56,7 @@ Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base
|
|||||||
peer = found_peer[0]
|
peer = found_peer[0]
|
||||||
_bridges = [jack[:bridge], peer[:bridge]].sort
|
_bridges = [jack[:bridge], peer[:bridge]].sort
|
||||||
_tails = ([jack[:bridge], peer[:bridge]] == _bridges ? [jack[:name], peer[:name]] : [peer[:name], jack[:name]])
|
_tails = ([jack[:bridge], peer[:bridge]] == _bridges ? [jack[:name], peer[:name]] : [peer[:name], jack[:name]])
|
||||||
_vlan_ids = [(jack[:vlan_id].to_i or 0), (peer[:vlan_id].to_i or 0)]
|
_vlan_ids = [jack[:vlan_id].to_i, peer[:vlan_id].to_i]
|
||||||
end
|
end
|
||||||
props = {
|
props = {
|
||||||
:ensure => :present,
|
:ensure => :present,
|
||||||
@ -95,12 +94,12 @@ Puppet::Type.type(:l2_patch).provide(:ovs, :parent => Puppet::Provider::Ovs_base
|
|||||||
vsctl('--may-exist', 'add-port', bridges[0], jack, '--', 'set', 'Interface', jack, 'type=internal')
|
vsctl('--may-exist', 'add-port', bridges[0], jack, '--', 'set', 'Interface', jack, 'type=internal')
|
||||||
if lnx_port_br_mapping.has_key? jack and lnx_port_br_mapping[jack][:bridge] != bridges[1]
|
if lnx_port_br_mapping.has_key? jack and lnx_port_br_mapping[jack][:bridge] != bridges[1]
|
||||||
# eject lnx-side jack from bridge, if jack aldeady a member
|
# eject lnx-side jack from bridge, if jack aldeady a member
|
||||||
brctl('delif', lnx_port_br_mapping[jack][:bridge], jack)
|
self.brctl(['delif', lnx_port_br_mapping[jack][:bridge], jack])
|
||||||
lnx_port_br_mapping.delete(jack)
|
lnx_port_br_mapping.delete(jack)
|
||||||
end
|
end
|
||||||
if !lnx_port_br_mapping.has_key? jack
|
if !lnx_port_br_mapping.has_key? jack
|
||||||
begin
|
begin
|
||||||
brctl('addif', bridges[1], jack)
|
self.class.brctl(['addif', bridges[1], jack])
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
if e.to_s =~ /device\s+#{jack}\s+is\s+already\s+a\s+member\s+of\s+a\s+bridge/
|
if e.to_s =~ /device\s+#{jack}\s+is\s+already\s+a\s+member\s+of\s+a\s+bridge/
|
||||||
notice("'#{jack}' already addeded to '#{bridges[1]}' by ghost event.")
|
notice("'#{jack}' already addeded to '#{bridges[1]}' by ghost event.")
|
||||||
@ -138,7 +137,7 @@ debug(cmds)
|
|||||||
jack = L23network.get_jack_name(@resource[:bridges], 0)
|
jack = L23network.get_jack_name(@resource[:bridges], 0)
|
||||||
# we don't normalize bridge ordering, because OVS bridge always first. by design.
|
# we don't normalize bridge ordering, because OVS bridge always first. by design.
|
||||||
if File.symlink?("/sys/class/net/#{@resource[:bridges][1]}/brif/#{jack}")
|
if File.symlink?("/sys/class/net/#{@resource[:bridges][1]}/brif/#{jack}")
|
||||||
brctl('delif', @resource[:bridges][1], jack)
|
self.class.brctl(['delif', @resource[:bridges][1], jack])
|
||||||
end
|
end
|
||||||
vsctl('del-port', @resource[:bridges][0], jack)
|
vsctl('del-port', @resource[:bridges][0], jack)
|
||||||
else
|
else
|
||||||
@ -207,6 +206,13 @@ debug(cmds)
|
|||||||
@property_flush[:vlan_ids] = val
|
@property_flush[:vlan_ids] = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mtu
|
||||||
|
'absent'
|
||||||
|
end
|
||||||
|
def mtu=(val)
|
||||||
|
@property_flush[:mtu] = val
|
||||||
|
end
|
||||||
|
|
||||||
def jacks
|
def jacks
|
||||||
@property_hash[:jacks]
|
@property_hash[:jacks]
|
||||||
end
|
end
|
||||||
|
@ -3,7 +3,6 @@ require File.join(File.dirname(__FILE__), '..','..','..','puppet/provider/lnx_ba
|
|||||||
Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base) do
|
||||||
defaultfor :osfamily => :linux
|
defaultfor :osfamily => :linux
|
||||||
commands :ethtool_cmd => 'ethtool',
|
commands :ethtool_cmd => 'ethtool',
|
||||||
:brctl => 'brctl',
|
|
||||||
:pkill => 'pkill'
|
:pkill => 'pkill'
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
|||||||
when :ovs
|
when :ovs
|
||||||
self.class.ovs_vsctl(['del-port', br_name, @resource[:interface]])
|
self.class.ovs_vsctl(['del-port', br_name, @resource[:interface]])
|
||||||
when :lnx
|
when :lnx
|
||||||
brctl('delif', br_name, @resource[:interface])
|
self.class.brctl(['delif', br_name, @resource[:interface]])
|
||||||
else
|
else
|
||||||
#pass
|
#pass
|
||||||
end
|
end
|
||||||
@ -137,7 +136,7 @@ Puppet::Type.type(:l2_port).provide(:lnx, :parent => Puppet::Provider::Lnx_base)
|
|||||||
self.class.ovs_vsctl(['add-port', @property_flush[:bridge], @resource[:interface]])
|
self.class.ovs_vsctl(['add-port', @property_flush[:bridge], @resource[:interface]])
|
||||||
when :lnx
|
when :lnx
|
||||||
begin
|
begin
|
||||||
brctl('addif', @property_flush[:bridge], @resource[:interface])
|
self.class.brctl(['addif', @property_flush[:bridge], @resource[:interface]])
|
||||||
rescue
|
rescue
|
||||||
# Sometimes interface may be automatically added to bridge if config file exists before interface creation,
|
# Sometimes interface may be automatically added to bridge if config file exists before interface creation,
|
||||||
# especially vlan interfaces. It appears on CentOS.
|
# especially vlan interfaces. It appears on CentOS.
|
||||||
|
@ -48,6 +48,7 @@ define l23network::l2::patch (
|
|||||||
$act_bridges = [$bridges[1], $bridges[0]]
|
$act_bridges = [$bridges[1], $bridges[0]]
|
||||||
$act_vlan_ids = undef
|
$act_vlan_ids = undef
|
||||||
} else {
|
} else {
|
||||||
|
$lnx2lnx = true
|
||||||
$act_bridges = $bridges
|
$act_bridges = $bridges
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,36 @@ define l23network::l2::patch (
|
|||||||
provider => $config_provider
|
provider => $config_provider
|
||||||
}
|
}
|
||||||
L23_stored_config[$patch_jacks_names[1]] -> L2_patch[$patch_name]
|
L23_stored_config[$patch_jacks_names[1]] -> L2_patch[$patch_name]
|
||||||
|
} elsif $lnx2lnx {
|
||||||
|
if ! defined(L23_stored_config[$patch_jacks_names[0]]) {
|
||||||
|
l23_stored_config { $patch_jacks_names[0]: }
|
||||||
|
}
|
||||||
|
L23_stored_config <| title == $patch_jacks_names[0] |> {
|
||||||
|
ensure => $ensure,
|
||||||
|
if_type => 'patch',
|
||||||
|
bridge => $act_bridges[0],
|
||||||
|
jacks => $patch_jacks_names,
|
||||||
|
onboot => true,
|
||||||
|
vendor_specific => $vendor_specific,
|
||||||
|
provider => $config_provider
|
||||||
|
}
|
||||||
|
L23_stored_config[$patch_jacks_names[0]] -> L2_patch[$patch_name]
|
||||||
|
|
||||||
|
if ! defined(L23_stored_config[$patch_jacks_names[1]]) {
|
||||||
|
l23_stored_config { $patch_jacks_names[1]: }
|
||||||
|
}
|
||||||
|
L23_stored_config <| title == $patch_jacks_names[1] |> {
|
||||||
|
ensure => $ensure,
|
||||||
|
if_type => 'patch',
|
||||||
|
bridge => $act_bridges[1],
|
||||||
|
jacks => $patch_jacks_names,
|
||||||
|
onboot => true,
|
||||||
|
vendor_specific => $vendor_specific,
|
||||||
|
provider => $config_provider
|
||||||
|
}
|
||||||
|
L23_stored_config[$patch_jacks_names[1]] -> L2_patch[$patch_name]
|
||||||
} else {
|
} else {
|
||||||
|
# ovs2lnx patch
|
||||||
if ! defined(L23_stored_config[$patch_jacks_names[0]]) {
|
if ! defined(L23_stored_config[$patch_jacks_names[0]]) {
|
||||||
# we use only one (first) patch jack name here and later,
|
# we use only one (first) patch jack name here and later,
|
||||||
# because a both jacks for patch are created by
|
# because a both jacks for patch are created by
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
auto br1
|
||||||
|
iface br1 inet static
|
||||||
|
bridge_ports p_33470efd-0
|
||||||
|
address 192.168.88.2/24
|
@ -0,0 +1,4 @@
|
|||||||
|
auto br2
|
||||||
|
iface br2 inet static
|
||||||
|
bridge_ports p_33470efd-1
|
||||||
|
address 192.168.99.2/24
|
@ -0,0 +1,5 @@
|
|||||||
|
auto p_33470efd-0
|
||||||
|
iface p_33470efd-0 inet manual
|
||||||
|
pre-up ip link add p_33470efd-0 type veth peer name p_33470efd-1
|
||||||
|
post-up ip link set up dev p_33470efd-1
|
||||||
|
post-down ip link del p_33470efd-0
|
@ -0,0 +1,5 @@
|
|||||||
|
auto p_33470efd-1
|
||||||
|
iface p_33470efd-1 inet manual
|
||||||
|
pre-up ip link add p_33470efd-0 type veth peer name p_33470efd-1
|
||||||
|
post-up ip link set up dev p_33470efd-1
|
||||||
|
post-down ip link del p_33470efd-0
|
@ -0,0 +1,173 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
resources_map = {
|
||||||
|
:'br1' => {
|
||||||
|
:name => "br1",
|
||||||
|
:onboot => "yes",
|
||||||
|
:method => "static",
|
||||||
|
:if_type => "bridge",
|
||||||
|
:ipaddr => "192.168.88.2/24",
|
||||||
|
:bridge_ports => ['p_33470efd-0'], # in real cases this value doesn't pass directly to stored_config,
|
||||||
|
:provider => "lnx_ubuntu", # but filled in generate() method of type
|
||||||
|
},
|
||||||
|
:'br2' => {
|
||||||
|
:name => "br2",
|
||||||
|
:onboot => "yes",
|
||||||
|
:method => "static",
|
||||||
|
:if_type => "bridge",
|
||||||
|
:ipaddr => "192.168.99.2/24",
|
||||||
|
:bridge_ports => ['p_33470efd-1'], # in real cases this value doesn't pass directly to stored_config,
|
||||||
|
:provider => "lnx_ubuntu", # but filled in generate() method of type
|
||||||
|
},
|
||||||
|
:'p_33470efd-0' => {
|
||||||
|
:name => 'p_33470efd-0',
|
||||||
|
:if_type => 'patch',
|
||||||
|
:bridge => ["br1"],
|
||||||
|
:jacks => ['p_33470efd-0', 'p_33470efd-1'],
|
||||||
|
:provider => "lnx_ubuntu",
|
||||||
|
},
|
||||||
|
:'p_33470efd-1' => {
|
||||||
|
:name => "p_33470efd-1",
|
||||||
|
:if_type => 'patch',
|
||||||
|
:bridge => ["br2"],
|
||||||
|
:jacks => ['p_33470efd-0', 'p_33470efd-1'],
|
||||||
|
:provider => "lnx_ubuntu",
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# This test is functional continue of .spec/classes/ovs2lnx_patch__spec.rb
|
||||||
|
describe Puppet::Type.type(:l23_stored_config).provider(:lnx_ubuntu) do
|
||||||
|
|
||||||
|
let(:input_data) { resources_map}
|
||||||
|
|
||||||
|
let(:resources) do
|
||||||
|
resources = {}
|
||||||
|
input_data.each do |name, res|
|
||||||
|
resources.store name, Puppet::Type.type(:l23_stored_config).new(res)
|
||||||
|
end
|
||||||
|
return resources
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:providers) do
|
||||||
|
providers = {}
|
||||||
|
resources.each do |name, resource|
|
||||||
|
provider = resource.provider
|
||||||
|
if ENV['SPEC_PUPPET_DEBUG']
|
||||||
|
class << provider
|
||||||
|
def debug(msg)
|
||||||
|
puts msg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
provider.create
|
||||||
|
providers.store name, provider
|
||||||
|
end
|
||||||
|
return providers
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
puppet_debug_override()
|
||||||
|
end
|
||||||
|
|
||||||
|
def fixture_path
|
||||||
|
File.join(PROJECT_ROOT, 'spec', 'fixtures', 'provider', 'l23_stored_config', 'lnx_ubuntu__lnx2lnx_patch__spec')
|
||||||
|
end
|
||||||
|
|
||||||
|
def fixture_file(file)
|
||||||
|
File.join(fixture_path, file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fixture_data(file)
|
||||||
|
File.read(fixture_file(file))
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when formating config files" do
|
||||||
|
|
||||||
|
context 'for LNX bridge br1' do
|
||||||
|
subject { providers[:'br1'] }
|
||||||
|
let(:cfg_file) { subject.class.format_file('filepath', [subject]) }
|
||||||
|
it { expect(cfg_file).to match(/auto\s+br1/) }
|
||||||
|
it { expect(cfg_file).to match(/iface\s+br1\s+inet\s+static/) }
|
||||||
|
it { expect(cfg_file).to match(/bridge_ports\s+p_33470efd-0/) }
|
||||||
|
it { expect(cfg_file).to match(/address\s+192.168.88.2\/24/) }
|
||||||
|
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(4) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for LNX bridge br2' do
|
||||||
|
subject { providers[:'br2'] }
|
||||||
|
let(:cfg_file) { subject.class.format_file('filepath', [subject]) }
|
||||||
|
it { expect(cfg_file).to match(/auto\s+br2/) }
|
||||||
|
it { expect(cfg_file).to match(/iface\s+br2\s+inet\s+static/) }
|
||||||
|
it { expect(cfg_file).to match(/bridge_ports\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/address\s+192.168.99.2\/24/) }
|
||||||
|
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(4) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for lnx2lnx patchcord p_33470efd-0' do
|
||||||
|
subject { providers[:'p_33470efd-0'] }
|
||||||
|
let(:cfg_file) { subject.class.format_file('filepath', [subject]) }
|
||||||
|
it { expect(cfg_file).to match(/auto\s+p_33470efd-0/) }
|
||||||
|
it { expect(cfg_file).to match(/iface\s+p_33470efd-0\s+inet\s+manual/) }
|
||||||
|
it { expect(cfg_file).to match(/pre-up\s+ip\s+link\s+add\s+p_33470efd-0\s+type\s+veth\s+peer\s+name\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/post-up\s+ip\s+link\s+set\s+up\s+dev\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/post-down\s+ip\s+link\s+del\s+p_33470efd-0/) }
|
||||||
|
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(5) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for lnx2lnx patchcord p_33470efd-1' do
|
||||||
|
subject { providers[:'p_33470efd-1'] }
|
||||||
|
let(:cfg_file) { subject.class.format_file('filepath', [subject]) }
|
||||||
|
it { expect(cfg_file).to match(/auto\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/iface\s+p_33470efd-1\s+inet\s+manual/) }
|
||||||
|
it { expect(cfg_file).to match(/pre-up\s+ip\s+link\s+add\s+p_33470efd-0\s+type\s+veth\s+peer\s+name\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/post-up\s+ip\s+link\s+set\s+up\s+dev\s+p_33470efd-1/) }
|
||||||
|
it { expect(cfg_file).to match(/post-down\s+ip\s+link\s+del\s+p_33470efd-0/) }
|
||||||
|
it { expect(cfg_file.split(/\n/).reject{|x| x=~/^\s*$/}.length). to eq(5) }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when parsing config files" do
|
||||||
|
|
||||||
|
context 'for LNX bridge br1' do
|
||||||
|
let(:res) { subject.class.parse_file('br1', fixture_data('ifcfg-br1'))[0] }
|
||||||
|
it { expect(res[:method]).to eq :static }
|
||||||
|
it { expect(res[:onboot]).to eq true }
|
||||||
|
it { expect(res[:name]).to eq 'br1' }
|
||||||
|
it { expect(res[:bridge_ports]).to eq ['p_33470efd-0'] }
|
||||||
|
it { expect(res[:if_type].to_s).to eq 'bridge' }
|
||||||
|
it { expect(res[:if_provider].to_s).to eq 'lnx' }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for LNX bridge br2' do
|
||||||
|
let(:res) { subject.class.parse_file('br2', fixture_data('ifcfg-br2'))[0] }
|
||||||
|
it { expect(res[:method]).to eq :static }
|
||||||
|
it { expect(res[:onboot]).to eq true }
|
||||||
|
it { expect(res[:name]).to eq 'br2' }
|
||||||
|
it { expect(res[:bridge_ports]).to eq ['p_33470efd-1'] }
|
||||||
|
it { expect(res[:if_type].to_s).to eq 'bridge' }
|
||||||
|
it { expect(res[:if_provider].to_s).to eq 'lnx' }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for lnx2lnx patchcord p_33470efd-0' do
|
||||||
|
let(:res) { subject.class.parse_file('p_33470efd-0', fixture_data('ifcfg-p_33470efd-0'))[0] }
|
||||||
|
it { expect(res[:method]).to eq :manual }
|
||||||
|
it { expect(res[:onboot]).to eq true }
|
||||||
|
it { expect(res[:name]).to eq 'p_33470efd-0' }
|
||||||
|
it { expect(res[:if_type].to_s).to eq 'patch' }
|
||||||
|
it { expect(res[:if_provider].to_s).to eq 'lnx' }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for lnx2lnx patchcord p_33470efd-1' do
|
||||||
|
let(:res) { subject.class.parse_file('p_33470efd-1', fixture_data('ifcfg-p_33470efd-1'))[0] }
|
||||||
|
it { expect(res[:method]).to eq :manual }
|
||||||
|
it { expect(res[:onboot]).to eq true }
|
||||||
|
it { expect(res[:name]).to eq 'p_33470efd-1' }
|
||||||
|
it { expect(res[:if_type].to_s).to eq 'patch' }
|
||||||
|
it { expect(res[:if_provider].to_s).to eq 'lnx' }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -0,0 +1,69 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Puppet::Type.type(:l2_patch).provider(:ovs) do
|
||||||
|
# NOTE! for bridges ['br1', 'br2'] jack names will be ['p_39a440c1-0', 'p_39a440c1-1']
|
||||||
|
|
||||||
|
|
||||||
|
let(:resource_br1) {
|
||||||
|
Puppet::Type.type(:l2_bridge).new(
|
||||||
|
:provider => 'lnx',
|
||||||
|
:name => 'br1',
|
||||||
|
:bridge => 'br1',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let(:provider_br1) { resource_br1.provider }
|
||||||
|
#let(:instance_br1_ovs) { provider_br1.class.instances }
|
||||||
|
|
||||||
|
let(:resource_patch) {
|
||||||
|
Puppet::Type.type(:l2_patch).new(
|
||||||
|
:provider => 'lnx',
|
||||||
|
:name => 'patch__br1--br2',
|
||||||
|
:bridges => ['br1', 'br2'],
|
||||||
|
:jacks => ['p_39a440c1-0', 'p_39a440c1-1'],
|
||||||
|
:mtu => '9000'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let(:provider_patch) { resource_patch.provider }
|
||||||
|
#let(:instance_patch_ovs) { provider_patch.class.instances }
|
||||||
|
|
||||||
|
describe "lnx-to-lnx patchcord" do
|
||||||
|
|
||||||
|
let(:resource_br2) {
|
||||||
|
Puppet::Type.type(:l2_bridge).new(
|
||||||
|
:provider => 'lnx',
|
||||||
|
:name => 'br2',
|
||||||
|
:bridge => 'br2',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let(:provider_br2) { resource_br2.provider }
|
||||||
|
#let(:instance_br2_ovs) { provider_br2.class.instances }
|
||||||
|
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
puppet_debug_override()
|
||||||
|
provider_br1.class.stubs(:iproute)
|
||||||
|
provider_br2.class.stubs(:iproute)
|
||||||
|
provider_br1.class.stubs(:brctl).with(['addbr', 'br1']).returns(true)
|
||||||
|
provider_br2.class.stubs(:brctl).with(['addbr', 'br2']).returns(true)
|
||||||
|
provider_patch.class.stubs(:iproute).with([
|
||||||
|
'link', 'add', 'dev', 'p_39a440c1-0', 'type', 'veth', 'peer', 'name', 'p_39a440c1-1'
|
||||||
|
]).returns(true)
|
||||||
|
provider_patch.class.stubs(:get_bridge_list).returns({
|
||||||
|
'br1' => {:br_type => :lnx},
|
||||||
|
'br2' => {:br_type => :lnx},
|
||||||
|
})
|
||||||
|
provider_patch.class.stubs(:iproute).with(['link', 'set', 'dev', 'p_39a440c1-0', 'master', 'br1']).returns(true)
|
||||||
|
provider_patch.class.stubs(:iproute).with(['link', 'set', 'dev', 'p_39a440c1-1', 'master', 'br2']).returns(true)
|
||||||
|
provider_patch.class.stubs(:interface_up).with('p_39a440c1-0', true).returns(true)
|
||||||
|
provider_patch.class.stubs(:interface_up).with('p_39a440c1-1', true).returns(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "Just create two bridges and connect it by patchcord" do
|
||||||
|
provider_br1.create
|
||||||
|
provider_br2.create
|
||||||
|
provider_patch.create
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -83,15 +83,16 @@ describe Puppet::Type.type(:l2_patch).provider(:ovs) do
|
|||||||
provider_br1.class.stubs(:vsctl).with('add-br', 'br1').returns(true)
|
provider_br1.class.stubs(:vsctl).with('add-br', 'br1').returns(true)
|
||||||
provider_br2.class.stubs(:iproute).with().returns(true)
|
provider_br2.class.stubs(:iproute).with().returns(true)
|
||||||
provider_br2.class.stubs(:iproute).with('link', 'set', 'up', 'dev', 'br2').returns(true)
|
provider_br2.class.stubs(:iproute).with('link', 'set', 'up', 'dev', 'br2').returns(true)
|
||||||
provider_br2.class.stubs(:brctl).with('addbr', 'br2').returns(true)
|
provider_br2.stubs(:brctl).with(['addbr', 'br2']).returns(true)
|
||||||
provider_patch.class.stubs(:brctl).with('addif', 'br2', 'p_39a440c1-0').returns(true)
|
provider_patch.class.stubs(:get_bridges_order_for_patch).with(['br1','br2']).returns(['br1','br2'])
|
||||||
|
File.stubs(:directory?).with('/sys/class/net/br2/bridge').returns(true)
|
||||||
provider_patch.class.stubs(:vsctl).with(
|
provider_patch.class.stubs(:vsctl).with(
|
||||||
'--may-exist', 'add-port', 'br1', 'p_39a440c1-0', '--', 'set', 'Interface', 'p_39a440c1-0', 'type=internal'
|
'--may-exist', 'add-port', 'br1', 'p_39a440c1-0', '--', 'set', 'Interface', 'p_39a440c1-0', 'type=internal'
|
||||||
).returns(true)
|
).returns(true)
|
||||||
File.stubs(:directory?).with('/sys/class/net/br2/bridge').returns(true)
|
|
||||||
provider_patch.class.stubs(:get_lnx_port_bridges_pairs).with().returns({})
|
provider_patch.class.stubs(:get_lnx_port_bridges_pairs).with().returns({})
|
||||||
provider_patch.class.stubs(:get_bridges_order_for_patch).with(['br1','br2']).returns(['br1','br2'])
|
provider_patch.stubs(:brctl).with(['addif', 'br2', 'p_39a440c1-0']).returns(true)
|
||||||
provider_patch.class.stubs(:iproute).with('link', 'set', 'up', 'dev', 'p_39a440c1-0').returns(true)
|
provider_patch.class.stubs(:iproute).with('link', 'set', 'up', 'dev', 'p_39a440c1-0').returns(true)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Just create two bridges and connect it by patchcord" do
|
it "Just create two bridges and connect it by patchcord" do
|
||||||
@ -100,6 +101,15 @@ describe Puppet::Type.type(:l2_patch).provider(:ovs) do
|
|||||||
provider_patch.create
|
provider_patch.create
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "Patch was connected to another bridge" do
|
||||||
|
provider_br1.create
|
||||||
|
provider_br2.create
|
||||||
|
provider_patch.class.stubs(:get_lnx_port_bridges_pairs).with().returns({'p_39a440c1-0'=>{:bridge=>'br-lnx1', :br_type=>:lnx},})
|
||||||
|
provider_patch.stubs(:brctl).with(['delif', 'br-lnx1', 'p_39a440c1-0']).returns(true)
|
||||||
|
provider_patch.stubs(:brctl).with(['addif', 'br2', 'p_39a440c1-0']).returns(true)
|
||||||
|
provider_patch.create
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user