Check tunnel mode when generate defaults for predefined networks and physnets.
We shouldn't create physnet if segmentation type is GRE. Change-Id: I4adc202791b508d675b09a966de77206bc2cad15 Partial-bug: #1281573
This commit is contained in:
parent
4627f50edb
commit
f2deed5887
@ -1,8 +1,28 @@
|
|||||||
require 'rake'
|
require 'rake'
|
||||||
require 'rspec/core/rake_task'
|
require 'rspec/core/rake_task'
|
||||||
require 'puppetlabs_spec_helper/rake_tasks'
|
|
||||||
|
|
||||||
|
desc "Run all RSpec code examples"
|
||||||
RSpec::Core::RakeTask.new(:rspec) do |t|
|
RSpec::Core::RakeTask.new(:rspec) do |t|
|
||||||
t.pattern = 'spec/*/*__spec.rb'
|
|
||||||
t.rspec_opts = File.read("spec/spec.opts").chomp || ""
|
t.rspec_opts = File.read("spec/spec.opts").chomp || ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SPEC_SUITES = (Dir.entries('spec') - ['.', '..','fixtures']).select {|e| File.directory? "spec/#{e}" }
|
||||||
|
namespace :rspec do
|
||||||
|
SPEC_SUITES.each do |suite|
|
||||||
|
desc "Run #{suite} RSpec code examples"
|
||||||
|
RSpec::Core::RakeTask.new(suite) do |t|
|
||||||
|
t.pattern = "spec/#{suite}/**/*__spec.rb"
|
||||||
|
t.rspec_opts = File.read("spec/spec.opts").chomp || ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
task :default => :rspec
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Gem::Specification::find_by_name('puppet-lint')
|
||||||
|
require 'puppet-lint/tasks/puppet-lint'
|
||||||
|
PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "vendor/**/*.pp"]
|
||||||
|
task :default => [:rspec, :lint]
|
||||||
|
end
|
||||||
|
rescue Gem::LoadError
|
||||||
|
end
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'array_or_string_to_array' do
|
describe 'array_or_string_to_array' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'array_part' do
|
describe 'array_part' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'check_cidrs' do
|
describe 'check_cidrs' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'cidr_to_ipaddr' do
|
describe 'cidr_to_ipaddr' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'cidr_to_netmask' do
|
describe 'cidr_to_netmask' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
begin
|
begin
|
||||||
require 'puppet/parser/functions/lib/l23network_scheme.rb'
|
require 'puppet/parser/functions/lib/l23network_scheme.rb'
|
||||||
rescue LoadError => e
|
rescue LoadError => e
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
begin
|
begin
|
||||||
require 'puppet/parser/functions/lib/l23network_scheme.rb'
|
require 'puppet/parser/functions/lib/l23network_scheme.rb'
|
||||||
rescue LoadError => e
|
rescue LoadError => e
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'merge_arrays' do
|
describe 'merge_arrays' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
|
|
||||||
describe 'sanitize_bool_in_hash' do
|
describe 'sanitize_bool_in_hash' do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
@ -8,14 +12,14 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should convert string-boolean values to boolean' do
|
it 'should convert string-boolean values to boolean' do
|
||||||
should run.with_params({
|
expect(scope.function_sanitize_bool_in_hash([{
|
||||||
:s_true => 'true',
|
:s_true => 'true',
|
||||||
:s_false => 'false',
|
:s_false => 'false',
|
||||||
:s_none => 'none',
|
:s_none => 'none',
|
||||||
:s_null => 'null',
|
:s_null => 'null',
|
||||||
:s_nil => 'nil',
|
:s_nil => 'nil',
|
||||||
:s_nill => 'nill',
|
:s_nill => 'nill',
|
||||||
}).and_return({
|
}])).to eq({
|
||||||
:s_true => true,
|
:s_true => true,
|
||||||
:s_false => false,
|
:s_false => false,
|
||||||
:s_none => nil,
|
:s_none => nil,
|
||||||
@ -26,14 +30,14 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should convert UP-sace string-boolean values to boolean' do
|
it 'should convert UP-sace string-boolean values to boolean' do
|
||||||
should run.with_params({
|
expect(scope.function_sanitize_bool_in_hash([{
|
||||||
:s_true => 'TRUE',
|
:s_true => 'TRUE',
|
||||||
:s_false => 'FALSE',
|
:s_false => 'FALSE',
|
||||||
:s_none => 'NONE',
|
:s_none => 'NONE',
|
||||||
:s_null => 'NULL',
|
:s_null => 'NULL',
|
||||||
:s_nil => 'NIL',
|
:s_nil => 'NIL',
|
||||||
:s_nill => 'NILL',
|
:s_nill => 'NILL',
|
||||||
}).and_return({
|
}])).to eq({
|
||||||
:s_true => true,
|
:s_true => true,
|
||||||
:s_false => false,
|
:s_false => false,
|
||||||
:s_none => nil,
|
:s_none => nil,
|
||||||
@ -44,7 +48,7 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should convert reccursive hashes' do
|
it 'should convert reccursive hashes' do
|
||||||
should run.with_params({
|
expect(scope.function_sanitize_bool_in_hash([{
|
||||||
:bool_hash => {
|
:bool_hash => {
|
||||||
:str => 'aaa',
|
:str => 'aaa',
|
||||||
:int => 123,
|
:int => 123,
|
||||||
@ -71,7 +75,7 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
:f => false,
|
:f => false,
|
||||||
:n => nil
|
:n => nil
|
||||||
},
|
},
|
||||||
}).and_return({
|
}])).to eq({
|
||||||
:bool_hash => {
|
:bool_hash => {
|
||||||
:str => 'aaa',
|
:str => 'aaa',
|
||||||
:int => 123,
|
:int => 123,
|
||||||
@ -102,7 +106,7 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should convert array of hashes' do
|
it 'should convert array of hashes' do
|
||||||
should run.with_params({ :array => [
|
expect(scope.function_sanitize_bool_in_hash([{ :array => [
|
||||||
{:aaa=>1,"aaa"=>11, :bbb=>2,'bbb'=>12, :ccc=>3,'ccc'=>3},
|
{:aaa=>1,"aaa"=>11, :bbb=>2,'bbb'=>12, :ccc=>3,'ccc'=>3},
|
||||||
{:t=>'true','tt'=>'true', :f=>'false','ff'=>'false', :n=>'nil','nn'=>'nil'},
|
{:t=>'true','tt'=>'true', :f=>'false','ff'=>'false', :n=>'nil','nn'=>'nil'},
|
||||||
{
|
{
|
||||||
@ -121,7 +125,7 @@ describe 'sanitize_bool_in_hash' do
|
|||||||
:s_nil => 'NIL',
|
:s_nil => 'NIL',
|
||||||
:s_nill => 'NILL',
|
:s_nill => 'NILL',
|
||||||
},
|
},
|
||||||
]}).and_return({ :array => [
|
]}])).to eq({ :array => [
|
||||||
{:aaa=>1,"aaa"=>11, :bbb=>2,'bbb'=>12, :ccc=>3,'ccc'=>3},
|
{:aaa=>1,"aaa"=>11, :bbb=>2,'bbb'=>12, :ccc=>3,'ccc'=>3},
|
||||||
{:t=>true,'tt'=>true, :f=>false,'ff'=>false, :n=>nil,'nn'=>nil},
|
{:t=>true,'tt'=>true, :f=>false,'ff'=>false, :n=>nil,'nn'=>nil},
|
||||||
{
|
{
|
||||||
|
@ -87,7 +87,7 @@ class MrntNeutronNR
|
|||||||
previous = nil
|
previous = nil
|
||||||
segment_id = @neutron_config[:L2][:enable_tunneling] ? @neutron_config[:L2][:tunnel_id_ranges].split(':')[0].to_i : 0
|
segment_id = @neutron_config[:L2][:enable_tunneling] ? @neutron_config[:L2][:tunnel_id_ranges].split(':')[0].to_i : 0
|
||||||
@neutron_config[:predefined_networks].each do |net, ncfg|
|
@neutron_config[:predefined_networks].each do |net, ncfg|
|
||||||
Puppet::debug("-*- processing net '#{net}': #{ncfg.inspect}")
|
Puppet::debug("-*- processing net '#{net}': #{ncfg.to_yaml()}")
|
||||||
# config network resources parameters
|
# config network resources parameters
|
||||||
network_config = get_default_network_config()
|
network_config = get_default_network_config()
|
||||||
network_config[:net][:name] = net.to_s
|
network_config[:net][:name] = net.to_s
|
||||||
|
@ -162,10 +162,29 @@ class MrntNeutron
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_default_networks()
|
def get_phys_nets(tun_mode, net_hash)
|
||||||
|
return net_hash if net_hash
|
||||||
|
rv = {
|
||||||
|
:physnet1 => {
|
||||||
|
:bridge => get_bridge_name('public'),
|
||||||
|
:vlan_range => nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ! tun_mode
|
||||||
|
rv[:physnet2] = {
|
||||||
|
:bridge => get_bridge_name('private'),
|
||||||
|
:vlan_range => "3000:4094",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_predefined_networks(tun_mode, net_hash)
|
||||||
|
return net_hash if net_hash
|
||||||
net_ext = "10.100.100"
|
net_ext = "10.100.100"
|
||||||
net_int = "192.168.111"
|
net_int = "192.168.111"
|
||||||
{
|
int_physnet = tun_mode ? nil : 'physnet2'
|
||||||
|
return {
|
||||||
:net04_ext => {
|
:net04_ext => {
|
||||||
:shared => false,
|
:shared => false,
|
||||||
:tenant => get_tenant(),
|
:tenant => get_tenant(),
|
||||||
@ -189,7 +208,7 @@ class MrntNeutron
|
|||||||
:L2 => {
|
:L2 => {
|
||||||
:router_ext => false,
|
:router_ext => false,
|
||||||
:network_type => 'gre', # or vlan
|
:network_type => 'gre', # or vlan
|
||||||
:physnet => 'physnet2',
|
:physnet => int_physnet,
|
||||||
:segment_id => nil,
|
:segment_id => nil,
|
||||||
},
|
},
|
||||||
:L3 => {
|
:L3 => {
|
||||||
@ -264,18 +283,6 @@ class MrntNeutron
|
|||||||
:mac_generation_retries => 32,
|
:mac_generation_retries => 32,
|
||||||
:segmentation_type => "gre",
|
:segmentation_type => "gre",
|
||||||
:tunnel_id_ranges => "3000:65535",
|
:tunnel_id_ranges => "3000:65535",
|
||||||
:phys_nets => {
|
|
||||||
:physnet1 => {
|
|
||||||
:bridge => get_bridge_name('public'),
|
|
||||||
#:interface => 'eth2',
|
|
||||||
:vlan_range => nil,
|
|
||||||
},
|
|
||||||
:physnet2 => {
|
|
||||||
:bridge => get_bridge_name('private'),
|
|
||||||
#:interface => 'eth3',
|
|
||||||
:vlan_range => "3000:4094",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
:phys_bridges => nil, # will be calculated later from :phys_nets
|
:phys_bridges => nil, # will be calculated later from :phys_nets
|
||||||
:bridge_mappings => nil, # will be calculated later from :phys_nets
|
:bridge_mappings => nil, # will be calculated later from :phys_nets
|
||||||
:network_vlan_ranges => nil, # will be calculated later from :phys_nets
|
:network_vlan_ranges => nil, # will be calculated later from :phys_nets
|
||||||
@ -304,7 +311,6 @@ class MrntNeutron
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
:predefined_routers => get_default_routers(),
|
:predefined_routers => get_default_routers(),
|
||||||
:predefined_networks => get_default_networks(),
|
|
||||||
:root_helper => "sudo neutron-rootwrap /etc/neutron/rootwrap.conf",
|
:root_helper => "sudo neutron-rootwrap /etc/neutron/rootwrap.conf",
|
||||||
:polling_interval => 2,
|
:polling_interval => 2,
|
||||||
}
|
}
|
||||||
@ -329,9 +335,6 @@ class MrntNeutron
|
|||||||
@neutron_config[:database][:url] ||= MrntNeutron.get_database_url(@neutron_config[:database])
|
@neutron_config[:database][:url] ||= MrntNeutron.get_database_url(@neutron_config[:database])
|
||||||
@neutron_config[:keystone][:auth_url] ||= MrntNeutron.get_keystone_auth_url(@neutron_config[:keystone])
|
@neutron_config[:keystone][:auth_url] ||= MrntNeutron.get_keystone_auth_url(@neutron_config[:keystone])
|
||||||
@neutron_config[:server][:api_url] ||= get_neutron_srv_api_url(@neutron_config[:server])
|
@neutron_config[:server][:api_url] ||= get_neutron_srv_api_url(@neutron_config[:server])
|
||||||
@neutron_config[:L2][:network_vlan_ranges] = MrntNeutron.get_network_vlan_ranges(@neutron_config[:L2])
|
|
||||||
@neutron_config[:L2][:bridge_mappings] = MrntNeutron.get_bridge_mappings(@neutron_config[:L2])
|
|
||||||
@neutron_config[:L2][:phys_bridges] = MrntNeutron.get_phys_bridges(@neutron_config[:L2])
|
|
||||||
@neutron_config[:amqp] ||= MrntNeutron.get_amqp_config(@neutron_config[:amqp])
|
@neutron_config[:amqp] ||= MrntNeutron.get_amqp_config(@neutron_config[:amqp])
|
||||||
if [:gre, :vxlan, :lisp].include? @neutron_config[:L2][:segmentation_type].downcase.to_sym
|
if [:gre, :vxlan, :lisp].include? @neutron_config[:L2][:segmentation_type].downcase.to_sym
|
||||||
@neutron_config[:L2][:enable_tunneling] = true
|
@neutron_config[:L2][:enable_tunneling] = true
|
||||||
@ -342,6 +345,17 @@ class MrntNeutron
|
|||||||
if @neutron_config[:amqp][:passwd].nil?
|
if @neutron_config[:amqp][:passwd].nil?
|
||||||
@neutron_config[:amqp][:passwd] = get_amqp_passwd()
|
@neutron_config[:amqp][:passwd] = get_amqp_passwd()
|
||||||
end
|
end
|
||||||
|
@neutron_config[:predefined_networks] = get_predefined_networks(
|
||||||
|
@neutron_config[:L2][:enable_tunneling],
|
||||||
|
@neutron_config[:predefined_networks]
|
||||||
|
)
|
||||||
|
@neutron_config[:L2][:phys_nets] = get_phys_nets(
|
||||||
|
@neutron_config[:L2][:enable_tunneling],
|
||||||
|
@neutron_config[:L2][:phys_nets]
|
||||||
|
)
|
||||||
|
@neutron_config[:L2][:network_vlan_ranges] = MrntNeutron.get_network_vlan_ranges(@neutron_config[:L2])
|
||||||
|
@neutron_config[:L2][:bridge_mappings] = MrntNeutron.get_bridge_mappings(@neutron_config[:L2])
|
||||||
|
@neutron_config[:L2][:phys_bridges] = MrntNeutron.get_phys_bridges(@neutron_config[:L2])
|
||||||
return @neutron_config
|
return @neutron_config
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -384,7 +398,9 @@ Puppet::Parser::Functions::newfunction(:sanitize_neutron_config, :type => :rvalu
|
|||||||
q_conf = MrntNeutron.new(self, given_config, argv[1])
|
q_conf = MrntNeutron.new(self, given_config, argv[1])
|
||||||
rv = q_conf.generate_config()
|
rv = q_conf.generate_config()
|
||||||
# pUPPET not allow hashes with SYM keys. normalize keys
|
# pUPPET not allow hashes with SYM keys. normalize keys
|
||||||
JSON.load(rv.to_json)
|
rv = JSON.load(rv.to_json)
|
||||||
|
Puppet::debug("-*- Actual Neutron config is: #{rv.to_yaml()}")
|
||||||
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
# vim: set ts=2 sw=2 et :
|
# vim: set ts=2 sw=2 et :
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ class NeutronNRConfig
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'create_floating_ips_for_admin' , :type => :puppet_function do
|
describe 'get_floatingip_pool_size_for_admin' , :type => :puppet_function do
|
||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@ -71,8 +75,8 @@ describe 'create_floating_ips_for_admin' , :type => :puppet_function do
|
|||||||
Puppet::Parser::Functions.function('get_floatingip_pool_size_for_admin').should == 'function_get_floatingip_pool_size_for_admin'
|
Puppet::Parser::Functions.function('get_floatingip_pool_size_for_admin').should == 'function_get_floatingip_pool_size_for_admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Must return 10' do
|
it 'Should return 10' do
|
||||||
subject.call([@cfg, 'neutron_settings']).should == 10
|
expect(scope.function_get_floatingip_pool_size_for_admin([@cfg, 'neutron_settings'])).to eq(10)
|
||||||
# [
|
# [
|
||||||
# '10.100.100.244',
|
# '10.100.100.244',
|
||||||
# '10.100.100.245',
|
# '10.100.100.245',
|
||||||
@ -88,14 +92,19 @@ describe 'create_floating_ips_for_admin' , :type => :puppet_function do
|
|||||||
# ]
|
# ]
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Must return zero' do
|
it 'Should return zero' do
|
||||||
@cfg['predefined_networks']['net04_ext']['L3']['floating'] = "10.100.100.250:10.100.100.254"
|
@cfg['predefined_networks']['net04_ext']['L3']['floating'] = "10.100.100.250:10.100.100.254"
|
||||||
subject.call([@cfg, 'neutron_settings']).should == 0 #[]
|
expect(scope.function_get_floatingip_pool_size_for_admin([@cfg, 'neutron_settings'])).to eq(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'Must return array of 3 ip address' do
|
it 'Should return 2' do
|
||||||
@cfg['predefined_networks']['net04_ext']['L3']['floating'] = "10.100.100.247:10.100.100.254"
|
@cfg['predefined_networks']['net04_ext']['L3']['floating'] = "10.100.100.247:10.100.100.254"
|
||||||
subject.call([@cfg, 'neutron_settings']).should == 3 #["10.100.100.252", "10.100.100.253", "10.100.100.254"]
|
expect(scope.function_get_floatingip_pool_size_for_admin([@cfg, 'neutron_settings'])).to eq(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'Should return 10' do
|
||||||
|
@cfg['predefined_networks']['net04_ext']['L3']['floating'] = "10.100.100.237:10.100.100.254"
|
||||||
|
expect(scope.function_get_floatingip_pool_size_for_admin([@cfg, 'neutron_settings'])).to eq(10)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# require 'puppet'
|
||||||
|
# require 'rspec'
|
||||||
|
# require 'rspec-puppet'
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'yaml'
|
require 'yaml'
|
||||||
#require 'puppet/parser/functions/lib/sanitize_bool_in_hash.rb'
|
#require 'puppet/parser/functions/lib/sanitize_bool_in_hash.rb'
|
||||||
@ -205,12 +209,6 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
# node = Puppet::Node.new("floppy", :environment => 'production')
|
|
||||||
# @compiler = Puppet::Parser::Compiler.new(node)
|
|
||||||
# @scope = Puppet::Parser::Scope.new(@compiler)
|
|
||||||
# @topscope = @scope.compiler.topscope
|
|
||||||
# @scope.parent = @topscope
|
|
||||||
# Puppet::Parser::Functions.function(:create_resources)
|
|
||||||
@q_config = NeutronConfig.new({
|
@q_config = NeutronConfig.new({
|
||||||
:management_vip => '192.168.0.254',
|
:management_vip => '192.168.0.254',
|
||||||
:management_ip => '192.168.0.11'
|
:management_ip => '192.168.0.11'
|
||||||
@ -232,9 +230,49 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
# should run.with_params({},'neutron_settings').and_return(@res_cfg)
|
# should run.with_params({},'neutron_settings').and_return(@res_cfg)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
it 'should return default config if default config given as incoming' do
|
it 'should return default config for GRE if default config given as incoming' do
|
||||||
@res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
cfg = Marshal.load(Marshal.dump(@cfg))
|
||||||
should run.with_params(@cfg,'neutron_settings').and_return(@res_cfg)
|
cfg['neutron_settings']['L2']['segmentation_type'] = 'gre'
|
||||||
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
|
res_cfg['L2']['segmentation_type'] = 'gre'
|
||||||
|
#res_cfg['L2']['enable_tunneling'] = true
|
||||||
|
res_cfg['L2']['phys_bridges'] = ["br-ex"]
|
||||||
|
res_cfg['L2']['network_vlan_ranges'] = "physnet1"
|
||||||
|
res_cfg['L2']['bridge_mappings'] = "physnet1:br-ex"
|
||||||
|
res_cfg['L2']['phys_nets'] = {
|
||||||
|
"physnet1" => {
|
||||||
|
"bridge" => "br-ex",
|
||||||
|
"vlan_range" => nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res_cfg['predefined_networks']['net04']['L2']['physnet'] = nil
|
||||||
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
|
rv = scope.function_sanitize_neutron_config([cfg, 'neutron_settings'])
|
||||||
|
expect(rv).to eq(res_cfg)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return default config for VLAN if default config given as incoming' do
|
||||||
|
cfg = Marshal.load(Marshal.dump(@cfg))
|
||||||
|
cfg['neutron_settings']['L2']['segmentation_type'] = 'vlan'
|
||||||
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
|
res_cfg['L2']['segmentation_type'] = 'vlan'
|
||||||
|
res_cfg['L2']['enable_tunneling'] = false
|
||||||
|
res_cfg['L2']['tunnel_id_ranges'] = nil
|
||||||
|
res_cfg['L2']['phys_bridges'] = ["br-ex", "br-prv"]
|
||||||
|
res_cfg['L2']['bridge_mappings'] = "physnet1:br-ex,physnet2:br-prv"
|
||||||
|
res_cfg['L2']['phys_nets'] = {
|
||||||
|
"physnet1" => {
|
||||||
|
"bridge" => "br-ex",
|
||||||
|
"vlan_range" => nil
|
||||||
|
},
|
||||||
|
"physnet2" => {
|
||||||
|
"bridge" => "br-prv",
|
||||||
|
"vlan_range" => "3000:4094"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
|
rv = scope.function_sanitize_neutron_config([cfg, 'neutron_settings'])
|
||||||
|
expect(rv).to eq(res_cfg)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (amqp)' do
|
it 'should substitute default values if missing required field in config (amqp)' do
|
||||||
@ -242,7 +280,8 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['amqp'].should == res_cfg['amqp']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['amqp']).to eq(res_cfg['amqp'])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (database)' do
|
it 'should substitute default values if missing required field in config (database)' do
|
||||||
@ -250,7 +289,8 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['database'].should == res_cfg['database']
|
rv = scope.function_sanitize_neutron_config([cfg, 'neutron_settings'])
|
||||||
|
expect(rv['database']).to eq res_cfg['database']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (server)' do
|
it 'should substitute default values if missing required field in config (server)' do
|
||||||
@ -258,7 +298,8 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['server'].should == res_cfg['server']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['server']).to eq res_cfg['server']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (keystone)' do
|
it 'should substitute default values if missing required field in config (keystone)' do
|
||||||
@ -266,15 +307,27 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['keystone'].should == res_cfg['keystone']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['keystone']).to eq res_cfg['keystone']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (L2)' do
|
it 'should substitute default values if missing required field in config (L2)' do
|
||||||
cfg = Marshal.load(Marshal.dump(@cfg))
|
cfg = Marshal.load(Marshal.dump(@cfg))
|
||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
|
res_cfg['L2']['enable_tunneling'] = true
|
||||||
|
res_cfg['L2']['phys_bridges'] = ["br-ex"]
|
||||||
|
res_cfg['L2']['network_vlan_ranges'] = "physnet1"
|
||||||
|
res_cfg['L2']['bridge_mappings'] = "physnet1:br-ex"
|
||||||
|
res_cfg['L2']['phys_nets'] = {
|
||||||
|
"physnet1" => {
|
||||||
|
"bridge" => "br-ex",
|
||||||
|
"vlan_range" => nil
|
||||||
|
}
|
||||||
|
}
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['L2'].should == res_cfg['L2']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['L2']).to eq res_cfg['L2']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (L3)' do
|
it 'should substitute default values if missing required field in config (L3)' do
|
||||||
@ -282,15 +335,18 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['L3'].should == res_cfg['L3']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['L3']).to eq res_cfg['L3']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (predefined_networks)' do
|
it 'should substitute default values if missing required field in config (predefined_networks)' do
|
||||||
cfg = Marshal.load(Marshal.dump(@cfg))
|
cfg = Marshal.load(Marshal.dump(@cfg))
|
||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
|
res_cfg['predefined_networks']['net04']['L2']['physnet'] = nil
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['predefined_networks'].should == res_cfg['predefined_networks']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['predefined_networks']).to eq res_cfg['predefined_networks']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should substitute default values if missing required field in config (predefined_routers)' do
|
it 'should substitute default values if missing required field in config (predefined_routers)' do
|
||||||
@ -298,12 +354,14 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
cfg['neutron_settings']['L3'].delete('dhcp_agent')
|
||||||
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
res_cfg = Marshal.load(Marshal.dump(@res_cfg))
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
subject.call([@cfg, 'neutron_settings'])['predefined_routers'].should == res_cfg['predefined_routers']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['predefined_routers']).to eq res_cfg['predefined_routers']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should calculate database url if database properties not given' do
|
it 'should calculate database url if database properties not given' do
|
||||||
@cfg['neutron_settings']['database'] = {}
|
@cfg['neutron_settings']['database'] = {}
|
||||||
subject.call([@cfg, 'neutron_settings'])['database']['url'].should == "mysql://neutron:neutron@192.168.0.254:3306/neutron"
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['database']['url']).to eq "mysql://neutron:neutron@192.168.0.254:3306/neutron"
|
||||||
end
|
end
|
||||||
it 'should calculate database url if some database properties given' do
|
it 'should calculate database url if some database properties given' do
|
||||||
@cfg['neutron_settings']['database'] = {
|
@cfg['neutron_settings']['database'] = {
|
||||||
@ -314,33 +372,54 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
'host' => '5.4.3.2',
|
'host' => '5.4.3.2',
|
||||||
'port' => 666,
|
'port' => 666,
|
||||||
}
|
}
|
||||||
subject.call([@cfg, 'neutron_settings'])['database']['url'].should == "mysql://qq_username:qq_password@5.4.3.2:666/qq_database"
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['database']['url']).to eq "mysql://qq_username:qq_password@5.4.3.2:666/qq_database"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should can substitute values in deep level' do
|
it 'should can substitute values in deep level' do
|
||||||
@cfg['neutron_settings']['amqp']['provider'] = "XXXXXXXXXXxxxx"
|
cfg = Marshal.load(Marshal.dump(@cfg))
|
||||||
@cfg['neutron_settings']['L2']['base_mac'] = "aa:aa:aa:00:00:00"
|
cfg['neutron_settings']['L2']['segmentation_type'] = 'gre'
|
||||||
@cfg['neutron_settings']['L2']['integration_bridge'] = "xx-xxx"
|
cfg['neutron_settings']['amqp']['provider'] = "XXXXXXXXXXxxxx"
|
||||||
@cfg['neutron_settings']['L2']['local_ip'] = "9.9.9.9"
|
cfg['neutron_settings']['L2']['base_mac'] = "aa:aa:aa:00:00:00"
|
||||||
@cfg['neutron_settings']['predefined_networks']['net04_ext']['L3']['nameservers'] = ["127.0.0.1"]
|
cfg['neutron_settings']['L2']['integration_bridge'] = "xx-xxx"
|
||||||
res_cfg = Marshal.load(Marshal.dump(@cfg['neutron_settings']))
|
cfg['neutron_settings']['L2']['local_ip'] = "9.9.9.9"
|
||||||
|
res_cfg = Marshal.load(Marshal.dump(cfg['neutron_settings']))
|
||||||
|
res_cfg['L2']['segmentation_type'] = 'gre'
|
||||||
|
#res_cfg['L2']['enable_tunneling'] = true
|
||||||
|
res_cfg['L2']['phys_bridges'] = ["br-ex"]
|
||||||
|
res_cfg['L2']['network_vlan_ranges'] = "physnet1"
|
||||||
|
res_cfg['L2']['bridge_mappings'] = "physnet1:br-ex"
|
||||||
|
res_cfg['L2']['phys_nets'] = {
|
||||||
|
"physnet1" => {
|
||||||
|
"bridge" => "br-ex",
|
||||||
|
"vlan_range" => nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res_cfg['predefined_networks']['net04']['L2']['physnet'] = nil
|
||||||
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
res_cfg['database']['url'] = 'mysql://neutron:neutron@192.168.0.254:3306/neutron'
|
||||||
res_cfg['L2']['enable_tunneling'] = true
|
res_cfg['L2']['enable_tunneling'] = true
|
||||||
#should run.with_params(@cfg,'neutron_settings').and_return(res_cfg)
|
#should run.with_params(@cfg,'neutron_settings').and_return(res_cfg)
|
||||||
subject.call([@cfg, 'neutron_settings']).should == res_cfg
|
rv = scope.function_sanitize_neutron_config([cfg, 'neutron_settings'])
|
||||||
|
#expect(rv['L2']).to eq res_cfg['L2']
|
||||||
|
#expect(rv['L3']).to eq res_cfg['L3']
|
||||||
|
#expect(rv['predefined_networks']).to eq res_cfg['predefined_networks']
|
||||||
|
expect(rv).to eq res_cfg
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should calculate hostname if amqp host not given' do
|
it 'should calculate hostname if amqp host not given' do
|
||||||
@cfg['neutron_settings']['amqp'] = {
|
@cfg['neutron_settings']['amqp'] = {
|
||||||
'provider' => "rabbitmq",
|
'provider' => "rabbitmq",
|
||||||
}
|
}
|
||||||
subject.call([@cfg, 'neutron_settings'])['amqp'].should == @res_cfg['amqp']
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['amqp']).to eq @res_cfg['amqp']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should calculate auth url if auth properties not given' do
|
it 'should calculate auth url if auth properties not given' do
|
||||||
@cfg['neutron_settings']['keystone'] = {}
|
@cfg['neutron_settings']['keystone'] = {}
|
||||||
subject.call([@cfg, 'neutron_settings'])['keystone']['auth_url'].should == "http://192.168.0.254:35357/v2.0"
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['keystone']['auth_url']).to eq "http://192.168.0.254:35357/v2.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should calculate auth url if some auth properties given' do
|
it 'should calculate auth url if some auth properties given' do
|
||||||
@cfg['neutron_settings']['keystone'] = {
|
@cfg['neutron_settings']['keystone'] = {
|
||||||
'auth_host' => "1.2.3.4",
|
'auth_host' => "1.2.3.4",
|
||||||
@ -353,16 +432,19 @@ describe 'sanitize_neutron_config' , :type => :puppet_function do
|
|||||||
'admin_password' => "pass_q",
|
'admin_password' => "pass_q",
|
||||||
'admin_email' => "test.neutron@localhost",
|
'admin_email' => "test.neutron@localhost",
|
||||||
}
|
}
|
||||||
subject.call([@cfg, 'neutron_settings'])['keystone']['auth_url'].should == "https://1.2.3.4:666/v10.0"
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['keystone']['auth_url']).to eq "https://1.2.3.4:666/v10.0"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'enable_tunneling must be True if segmentation_type is GRE' do
|
it 'enable_tunneling must be True if segmentation_type is GRE' do
|
||||||
@cfg['neutron_settings']['L2']['segmentation_type'] = 'gre'
|
@cfg['neutron_settings']['L2']['segmentation_type'] = 'gre'
|
||||||
subject.call([@cfg, 'neutron_settings'])['L2']['enable_tunneling'].should == true
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['L2']['enable_tunneling']).to eq true
|
||||||
end
|
end
|
||||||
it 'enable_tunneling must be False if segmentation_type is VLAN' do
|
it 'enable_tunneling must be False if segmentation_type is VLAN' do
|
||||||
@cfg['neutron_settings']['L2']['segmentation_type'] = 'vlan'
|
@cfg['neutron_settings']['L2']['segmentation_type'] = 'vlan'
|
||||||
subject.call([@cfg, 'neutron_settings'])['L2']['enable_tunneling'].should == false
|
rv = scope.function_sanitize_neutron_config([@cfg, 'neutron_settings'])
|
||||||
|
expect(rv['L2']['enable_tunneling']).to eq false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user