Adjust MTU for child interfaces if it possible

For network scheme, like
---
network_scheme:
  version: 1.1
  provider: lnx
  interfaces:
    eth1:
      mtu: 9000
  transformations:
    - action: add-port
      name: eth1
    - action: add-port
      name: eth1.101
  endpoints:
    eth1.101:
      IP:
        - 192.168.34.56/24
  roles:
    xxx: eth1.101

interface 'eth1.101' should be created with MTU=9000

Closes-bug: #1453027
Change-Id: I170e9088d5e3bcd241da7e56dfa7b7934d6d810d
This commit is contained in:
Sergey Vasilenko 2015-05-15 15:48:22 -07:00
parent aece146fb4
commit 6071511de2
6 changed files with 214 additions and 76 deletions

View File

@ -261,14 +261,24 @@ Puppet::Parser::Functions::newfunction(:generate_network_config, :type => :rvalu
next if action == :noop
#debug("TXX: '#{t[:name]}' => '#{t.to_yaml.gsub('!ruby/sym ',':')}'.")
#debug("TXX: '#{t[:name]}' => '#{t.to_yaml.gsub('!ruby/sym ','')}'.")
trans = L23network.sanitize_transformation(t, default_provider)
#debug("TTT: '#{trans[:name]}' => '#{trans.to_yaml.gsub('!ruby/sym ',':')}'.")
#debug("TTT: '#{trans[:name]}' => '#{trans.to_yaml.gsub('!ruby/sym ','')}'.")
if !ports_properties[trans[:name].to_sym()].nil?
trans.merge! ports_properties[trans[:name].to_sym()]
end
if trans.has_key?(:mtu) && !trans[:name].nil? && trans[:name] != 'unnamed'
# MTU should be adjust to phys_dev if it possible
devices = L23network.get_phys_dev_by_transformation(trans[:name], lookupvar('l3_fqdn_hostname'))
if !devices.nil? && devices[0] != trans[:name]
if trans[:mtu].nil?
trans[:mtu] = L23network.get_property_for_transformation('MTU', devices[0], lookupvar('l3_fqdn_hostname'))
end
end
end
# create puppet resources for transformations
resource = res_factory[action]
resource_properties = { }

View File

@ -91,17 +91,7 @@ Puppet::Parser::Functions::newfunction(:get_network_role_property, :type => :rva
when 'IPADDR_NETMASK_PAIR'
rv = (ipaddr_cidr.nil? ? [nil,nil] : [prepare_cidr(ipaddr_cidr)[0].to_s, IPAddr.new('255.255.255.255').mask(prepare_cidr(ipaddr_cidr)[1]).to_s])
when 'PHYS_DEV'
devices = L23network::Scheme.get_phys_dev_by_endpoint(interface, cfg[:interfaces], cfg[:transformations])
if devices.any? { |dev| /^bond/ =~ dev }
for i in 0..cfg[:transformations].size-1
transform = cfg[:transformations][i]
name = transform[:name]
if transform[:name] == devices[0]
devices.push(transform[:interfaces])
end
end
end
rv = devices.flatten
rv = L23network.get_phys_dev_by_transformation(interface, lookupvar('l3_fqdn_hostname'))
end
rv

View File

@ -1,7 +1,7 @@
require 'puppetx/l23_network_scheme'
Puppet::Parser::Functions::newfunction(:get_transformation_property, :type => :rvalue, :doc => <<-EOS
This function gets an endpoint properties from transformations --
This function gets an properties from transformations
and returns information about the selected property
ex: get_transformation_property('mtu','eth0')
@ -20,46 +20,11 @@ Puppet::Parser::Functions::newfunction(:get_transformation_property, :type => :r
raise(Puppet::ParseError, "get_transformation_property(...): Wrong number of arguments.")
end
cfg = L23network::Scheme.get_config(lookupvar('l3_fqdn_hostname'))
if cfg.nil?
raise(Puppet::ParseError, "get_transformation_property(...): You must call prepare_network_config(...) first!")
end
trans_name = argv.flatten[0]
if !cfg[:roles] || !cfg[:endpoints] || cfg[:roles].class.to_s() != "Hash" || cfg[:endpoints].class.to_s() != "Hash"
raise(Puppet::ParseError, "get_transformation_property(...): Invalid cfg_hash format.")
end
transforms = cfg[:transformations]
ifaces = cfg[:interfaces]
all_ifaces = ifaces.keys.map(&:to_s)
devices = argv.flatten
mtu = []
rv = nil
case mode
when 'MTU'
devices.each do |device|
if all_ifaces.include? device and ifaces[device.to_sym][:mtu] != nil
mtu.push(ifaces[device.to_sym][:mtu])
else
for i in 0..transforms.size-1 do
transform = cfg[:transformations][i]
if transform[:name] == device and transform[:mtu] != nil
mtu.push(transform[:mtu])
end
end
end
if mtu.empty?
Puppet::debug("get_transformation_property(...): MTU value is not set for interface '#{device}'.")
rv = nil
else
rv = mtu.min
end
end
end
rv
rv = L23network.get_property_for_transformation(mode, trans_name, lookupvar('l3_fqdn_hostname'))
Puppet::debug("get_transformation_property(...): Can't find '#{mode}' value for transformation '#{trans_name}'.") if rv.nil?
return rv
end
# vim: set ts=2 sw=2 et :

View File

@ -7,36 +7,83 @@ module L23network
def self.get_config(h)
@network_scheme_hash[h.to_sym]
end
def self.get_phys_dev_by_endpoint(endpoint, interfaces, transformations)
rv = []
all_ifaces = interfaces.keys.map(&:to_s)
ifaces = []
end
if all_ifaces.include? endpoint
ifaces.push(endpoint)
return ifaces
def self.get_phys_dev_by_transformation(trans_name, host_name)
cfg = L23network::Scheme.get_config(host_name)
interfaces = cfg[:interfaces]
transformations = cfg[:transformations]
rv = []
phy_interfaces = interfaces.keys.map(&:to_s)
ifaces = []
if phy_interfaces.include? trans_name
ifaces.push(trans_name)
return ifaces
end
for i in 0..transformations.size-1 do
transform = transformations[i]
if transform[:name] == trans_name
if transform[:vlandev] != nil
ifaces.push(transform[:vlandev])
else
trans_name = transform[:name].split(".")[0]
if phy_interfaces.include? trans_name or transform[:action] == 'add-bond'
ifaces.push(trans_name.to_s)
break
end
if transform[:name] != trans_name
ifaces.push(L23network.get_phys_dev_by_transformation(trans_name, host_name))
end
end
elsif transform[:bridge] == trans_name
ifaces.push(transform[:name].split(".")[0])
elsif transform[:bridges] != nil and transform[:bridges][0] == trans_name
trans_name = transform[:bridges][1]
ifaces.push(L23network.get_phys_dev_by_transformation(trans_name, host_name))
end
end
for i in 0..transformations.size-1 do
transform = transformations[i]
if transform[:name] != nil and transform[:name].include? endpoint
if transform[:vlandev] != nil
ifaces.push(transform[:vlandev])
else
endpoint = transform[:name].split(".")[0]
if all_ifaces.include? endpoint
ifaces.push(endpoint.to_s)
if ifaces.flatten.uniq.any? { |dev| /^bond/ =~ dev }
for i in 0..transformations.size-1
transform = transformations[i]
name = transform[:name]
if transform[:name] == ifaces[0]
ifaces.push(transform[:interfaces])
end
end
end
return ifaces.flatten.uniq
end
def self.get_property_for_transformation(prop_name, trans_name, host_name)
cfg = L23network::Scheme.get_config(host_name)
transformations = cfg[:transformations]
ifaces = cfg[:interfaces]
rv = nil
case prop_name
when 'MTU'
mtu = []
all_ifaces = ifaces.keys.map(&:to_s)
if all_ifaces.include? trans_name and ifaces[trans_name.to_sym][:mtu] != nil
mtu.push(ifaces[trans_name.to_sym][:mtu])
else
for i in 0..transformations.size-1 do
transform = cfg[:transformations][i]
if transform[:name] == trans_name and transform[:mtu] != nil
mtu.push(transform[:mtu])
end
end
elsif transform[:bridge] == endpoint
ifaces.push(transform[:name].split(".")[0])
elsif transform[:bridges] != nil and transform[:bridges][0] == endpoint
endpoint = transform[:bridges][1]
ifaces.push(get_phys_dev_by_endpoint(endpoint, interfaces, transformations))
end
end
return ifaces.flatten.uniq
rv = (mtu.empty? ? nil : mtu.min() )
else
rv = nil
end
return rv
end
end
# vim: set ts=2 sw=2 et :

View File

@ -0,0 +1,87 @@
require 'spec_helper'
describe 'l23network::examples::run_network_scheme', :type => :class do
let(:network_scheme) do
<<eof
---
network_scheme:
version: 1.1
provider: lnx
interfaces:
eth1:
mtu: 1200
eth2: {}
eth3: {}
eth4: {}
transformations:
- action: add-br
name: br1
- action: add-port
name: eth1.101
bridge: br1
- action: add-bond
name: bond0
mtu: 9000
interfaces:
- eth2
- eth3
bond_properties:
mode: balance-rr
- action: add-port
name: bond0.201
- action: add-br
name: br4
- action: add-port
name: eth4.401
bridge: br4
- action: add-br
name: br10
endpoints: {}
roles: {}
eof
end
context 'Find phys_dev for each transformation and adjust MTU by them' do
let(:title) { 'Find phys_dev for each transformation and adjust MTU by them' }
let(:facts) {
{
:osfamily => 'Debian',
:operatingsystem => 'Ubuntu',
:kernel => 'Linux',
:l23_os => 'ubuntu',
:l3_fqdn_hostname => 'stupid_hostname',
}
}
let(:params) do {
:settings_yaml => network_scheme,
} end
it do
should compile
end
it { should contain_l2_port('eth1') }
it { should contain_l2_port('eth2') }
it { should contain_l2_port('eth3') }
it { should contain_l2_port('eth4') }
it { should contain_l2_port('eth1').with({ 'mtu' => '1200' }) }
it { should contain_l2_port('eth2').with({ 'mtu' => '9000' }) }
it { should contain_l2_port('eth3').with({ 'mtu' => '9000' }) }
it { should contain_l2_port('eth4').without('mtu') }
it { should contain_l2_bond('bond0').with({ 'mtu' => '9000' }) }
it { should contain_l2_port('bond0.201').with({ 'mtu' => '9000' }) }
it { should contain_l2_bridge('br10').without('mtu') }
it { should contain_l2_port('eth1.101').with({ 'mtu' => '1200' }) }
it { should contain_l2_port('eth4.401').without('mtu') }
end
end
###

View File

@ -16,7 +16,17 @@ let(:network_scheme) do
eth2: {}
eth3: {}
eth4: {}
eth5: {}
eth44: {}
transformations:
- action: add-br
name: br-aux
- action: add-port
name: eth5.105
bridge: br-aux
- action: add-port
name: bond0.110
bridge: br-aux
- action: add-br
name: br-storage
- action: add-br
@ -45,6 +55,8 @@ let(:network_scheme) do
- action: add-port
name: bond0.102
bridge: br-ex
- action: add-port
name: bond0.103
- action: add-br
name: br-floating
provider: ovs
@ -61,6 +73,11 @@ let(:network_scheme) do
- br-prv
- br-storage
provider: ovs
- action: add-br
name: br44
- action: add-port
name: eth44
bridge: br44
endpoints:
eth0:
IP: 'none'
@ -80,6 +97,12 @@ let(:network_scheme) do
IP: none
br-prv:
IP: none
br-aux:
IP: none
br44:
IP: none
bond0.103:
IP: none
roles:
admin: eth0
ex: br-ex
@ -88,6 +111,9 @@ let(:network_scheme) do
neutron/floating: br-floating
neutron/private: br-prv
xxx: eth4
custom: br-aux
zzz: br44
bond_103: bond0.103
eof
end
@ -141,6 +167,19 @@ end
should run.with_params('xxx', 'phys_dev').and_return(['eth4'])
end
it 'should return physical device name for subinterface of bond' do
should run.with_params('bond_103', 'phys_dev').and_return(["bond0", "eth2", "eth3"])
end
it 'should return physical devices names for "custom" network role (two interfaces)' do
should run.with_params('custom', 'phys_dev').and_return(["eth5", "bond0"])
end
it 'should return physical device name for endpoint with interface with long name, contains shot name of another interface' do
should run.with_params('zzz', 'phys_dev').and_return(['eth44'])
end
it 'should return NIL for "non-existent" network role' do
should run.with_params('non-existent', 'phys_dev').and_return(nil)
end