From 2adc9e8f5a925ce5245f609fdc1ce69791abc252 Mon Sep 17 00:00:00 2001 From: Stanislav Makar Date: Mon, 16 Nov 2015 16:07:34 +0000 Subject: [PATCH] dyn-gen-physnet-set functions Implement generate_bridge_mappings Implement generate_physnet_vlan_ranges CI disable, because next patch in the chain has valuable CI check. Only functions located here. no calls. Fuel-CI: disable Change-Id: I0cfd3d38ab62d07216e767e391109fcac74691b4 blueprint: dyn-gen-physnet-set --- .../functions/generate_bridge_mappings.rb | 39 ++++ .../functions/generate_physnet_vlan_ranges.rb | 40 +++++ .../generate_bridge_mappings__spec.rb | 170 ++++++++++++++++++ .../generate_physnet_vlan_ranges__spec.rb | 170 ++++++++++++++++++ 4 files changed, 419 insertions(+) create mode 100644 deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_bridge_mappings.rb create mode 100644 deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_physnet_vlan_ranges.rb create mode 100644 deployment/puppet/osnailyfacter/spec/functions/generate_bridge_mappings__spec.rb create mode 100644 deployment/puppet/osnailyfacter/spec/functions/generate_physnet_vlan_ranges__spec.rb diff --git a/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_bridge_mappings.rb b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_bridge_mappings.rb new file mode 100644 index 0000000000..7a70363a80 --- /dev/null +++ b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_bridge_mappings.rb @@ -0,0 +1,39 @@ +Puppet::Parser::Functions::newfunction(:generate_bridge_mappings, :type => :rvalue, :doc => <<-EOS +This function gets neutron_config, network_scheme, flags and formats physnet bridge mapping according to flags. +EOS +) do |args| + + raise ArgumentError, ("generate_bridge_mappings(): wrong number of arguments (#{args.length}; must be 3)") if args.length < 3 + raise ArgumentError, ("generate_bridge_mappings(): wrong number of arguments (#{args.length}; must be 3)") if args.length > 3 + args.each do | arg | + raise ArgumentError, "generate_bridge_mappings(): #{arg} is not hash!" if !arg.is_a?(Hash) + end + + neutron_config = args[0] + network_scheme = args[1] + flags = args[2] + #flags = { do_floating => true, do_tenant => true, do_provider => false } + + debug "Collecting phys_nets and bridges" + physnet_bridge_map = {} + neutron_config['L2']['phys_nets'].each do |k,v| + next if !v['bridge'] + bridge = v['bridge'] + physnet_bridge_map[k] = bridge if !network_scheme['transformations'].select{ |x| x['name'] == bridge }.empty? + end + + if !flags['do_floating'] + debug("Perform floating networks") + physnet_bridge_map.each do | net, br | + physnet_bridge_map.delete(net) if !neutron_config['predefined_networks'].select{ |pnet, value| value['L2']['physnet'] == net and value['L2']['router_ext'] }.empty? + end + end + + debug("Formatng the output") + result = [] + physnet_bridge_map.each do |net, br| + result << "#{net}:#{br}" + end + debug("Format is done, value is: #{result}") + result +end diff --git a/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_physnet_vlan_ranges.rb b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_physnet_vlan_ranges.rb new file mode 100644 index 0000000000..10d662e252 --- /dev/null +++ b/deployment/puppet/osnailyfacter/lib/puppet/parser/functions/generate_physnet_vlan_ranges.rb @@ -0,0 +1,40 @@ +Puppet::Parser::Functions::newfunction(:generate_physnet_vlan_ranges, :type => :rvalue, :doc => <<-EOS +This function gets neutron_config, network_scheme, flags and formats physnet to vlan ranges according to flags. +EOS +) do |args| + + raise ArgumentError, ("generate_physnet_vlan_ranges(): wrong number of arguments (#{args.length}; must be 3)") if args.length < 3 + raise ArgumentError, ("generate_physnet_vlan_ranges(): wrong number of arguments (#{args.length}; must be 3)") if args.length > 3 + args.each do | arg | + raise ArgumentError, "generate_physnet_vlan_ranges(): #{arg} is not hash!" if !arg.is_a?(Hash) + end + + neutron_config = args[0] + network_scheme = args[1] + flags = args[2] + #flags = { do_floating => true, do_tenant => true, do_provider => false } + + debug "Collecting phys_nets and bridges" + physnet_bridge_map = {} + neutron_config['L2']['phys_nets'].each do |k,v| + next if !v['bridge'] + bridge = v['bridge'] + physnet_bridge_map[k] = v['vlan_range'] if !network_scheme['transformations'].select{ |x| x['name'] == bridge }.empty? + end + + if !flags['do_floating'] + debug("Perform floating networks") + physnet_bridge_map.each do | net, br | + physnet_bridge_map.delete(net) if !neutron_config['predefined_networks'].select{ |pnet, value| value['L2']['physnet'] == net and value['L2']['router_ext'] }.empty? + end + end + + debug("Formatng the output") + result = [] + physnet_bridge_map.each do |net, vr| + record = vr ? ":#{vr}" : '' + result << "#{net}"+ record + end + debug("Format is done, value is: #{result}") + result +end diff --git a/deployment/puppet/osnailyfacter/spec/functions/generate_bridge_mappings__spec.rb b/deployment/puppet/osnailyfacter/spec/functions/generate_bridge_mappings__spec.rb new file mode 100644 index 0000000000..556f20a6b0 --- /dev/null +++ b/deployment/puppet/osnailyfacter/spec/functions/generate_bridge_mappings__spec.rb @@ -0,0 +1,170 @@ +require 'puppet' +require 'spec_helper' + +describe 'function for formating allocation pools for neutron subnet resource' do + + def setup_scope + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production')) + if Puppet.version =~ /^3\./ + @scope = Puppet::Parser::Scope.new(@compiler) + else + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + end + @topscope = @topscope + @scope.parent = @topscope + Puppet::Parser::Functions.function(:generate_bridge_mappings) + end + + describe 'basic tests' do + + before :each do + setup_scope + puppet_debug_override + end + + let :network_scheme do +{"transformations"=> + [{"action"=>"add-br", "name"=>"br-fw-admin"}, + {"action"=>"add-br", "name"=>"br-mgmt"}, + {"action"=>"add-br", "name"=>"br-storage"}, + {"action"=>"add-br", "name"=>"br-ex"}, + {"action"=>"add-br", "name"=>"br-floating", "provider"=>"ovs"}, + {"action"=>"add-patch", + "bridges"=>["br-floating", "br-ex"], + "provider"=>"ovs", + "mtu"=>65000}, + {"action"=>"add-br", "name"=>"br-prv", "provider"=>"ovs"}, + {"action"=>"add-br", "name"=>"br-aux"}, + {"action"=>"add-patch", + "bridges"=>["br-prv", "br-aux"], + "provider"=>"ovs", + "mtu"=>65000}, + {"action"=>"add-port", "bridge"=>"br-fw-admin", "name"=>"eth0"}, + {"action"=>"add-port", "bridge"=>"br-ex", "name"=>"eth1"}, + {"bridge"=>"br-aux", + "name"=>"bond0", + "interfaces"=>["eth2", "eth3"], + "bond_properties"=>{"mode"=>"active-backup"}, + "interface_properties"=>{"vendor_specific"=>{"disable_offloading"=>true}}, + "action"=>"add-bond"}, + {"action"=>"add-port", "bridge"=>"br-mgmt", "name"=>"bond0.101"}, + {"action"=>"add-port", "bridge"=>"br-storage", "name"=>"bond0.102"}], + "roles"=> + {"keystone/api"=>"br-mgmt", + "neutron/api"=>"br-mgmt", + "mgmt/database"=>"br-mgmt", + "sahara/api"=>"br-mgmt", + "heat/api"=>"br-mgmt", + "ceilometer/api"=>"br-mgmt", + "ex"=>"br-ex", + "ceph/public"=>"br-mgmt", + "mgmt/messaging"=>"br-mgmt", + "management"=>"br-mgmt", + "swift/api"=>"br-mgmt", + "storage"=>"br-storage", + "mgmt/corosync"=>"br-mgmt", + "cinder/api"=>"br-mgmt", + "public/vip"=>"br-ex", + "swift/replication"=>"br-storage", + "ceph/radosgw"=>"br-ex", + "admin/pxe"=>"br-fw-admin", + "mongo/db"=>"br-mgmt", + "neutron/private"=>"br-prv", + "neutron/floating"=>"br-floating", + "fw-admin"=>"br-fw-admin", + "glance/api"=>"br-mgmt", + "mgmt/vip"=>"br-mgmt", + "murano/api"=>"br-mgmt", + "nova/api"=>"br-mgmt", + "horizon"=>"br-mgmt", + "nova/migration"=>"br-mgmt", + "mgmt/memcache"=>"br-mgmt", + "cinder/iscsi"=>"br-storage", + "ceph/replication"=>"br-storage"}, + "interfaces"=> + {"eth5"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:08.0"}}, + "eth4"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:07.0"}}, + "eth3"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:06.0"}}, + "eth2"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:05.0"}}, + "eth1"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:04.0"}}, + "eth0"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:03.0"}}}, + "version"=>"1.1", + "provider"=>"lnx", + "endpoints"=> + {"br-fw-admin"=>{"IP"=>["10.109.0.4/24"]}, + "br-prv"=>{"IP"=>"none"}, + "br-floating"=>{"IP"=>"none"}, + "br-storage"=>{"IP"=>["192.168.1.1/24"]}, + "br-mgmt"=>{"IP"=>["192.168.0.4/24"]}, + "br-ex"=>{"IP"=>["10.109.1.4/24"], "gateway"=>"10.109.1.1"}} + } + end + + let :neutron_config do + {"default_floating_net"=>"admin_floating_net", + "database"=>{"passwd"=>"2eaczPxjQNxkR6qik3sZlsaW"}, + "default_private_net"=>"admin_internal_net", + "keystone"=>{"admin_password"=>"EanTYjYlXqzATHAriBPkllal"}, + "L3"=>{"use_namespaces"=>true}, + "L2"=>{"phys_nets"=>{"physnet1"=>{"bridge"=>"br-floating", "vlan_range"=>"1000:1030"}, + "physnet2"=>{"bridge"=>"br-prv", "vlan_range"=>"1000:1030"}}, + "base_mac"=>"fa:16:3e:00:00:00", + "segmentation_type"=>"vlan"}, + "predefined_networks"=>{ + "admin_floating_net"=>{ + "shared"=>false, + "L2"=>{"network_type"=>"local", + "router_ext"=>true, + "physnet"=>'physnet2', + "segment_id"=>nil}, + "L3"=>{"nameservers"=>[], + "subnet"=>"10.109.1.0/24", + "floating"=>["10.109.1.130:10.109.1.254"], + "gateway"=>"10.109.1.1", + "enable_dhcp"=>false}, + "tenant"=>"admin"}, + "admin_internal_net"=>{ + "shared"=>false, + "L2"=>{"network_type"=>"vlan", + "router_ext"=>false, + "physnet"=>"physnet2", + "segment_id"=>nil}, + "L3"=>{"nameservers"=>["8.8.4.4", "8.8.8.8"], + "subnet"=>"192.168.111.0/24", + "floating"=>nil, + "gateway"=>"192.168.111.1", + "enable_dhcp"=>true}, + "tenant"=>"admin"}}, + "metadata"=>{"metadata_proxy_shared_secret"=>"uLLpFlxwX848GYnTUse2PjMp"} + } + end + + it "should exist" do + Puppet::Parser::Functions.function(:generate_bridge_mappings).should == "function_generate_bridge_mappings" + end + + it 'error if no arguments' do + lambda { @scope.function_generate_bridge_mappings([]) }.should raise_error(ArgumentError, 'generate_bridge_mappings(): wrong number of arguments (0; must be 3)') + end + + it 'should require one argument' do + lambda { @scope.function_generate_bridge_mappings(['foo', 'wee', 'ee', 'rr']) }.should raise_error(ArgumentError, 'generate_bridge_mappings(): wrong number of arguments (4; must be 3)') + end + + + it 'should be able to return floating nets to bridge map' do + expect(@scope.function_generate_bridge_mappings([neutron_config, network_scheme, { 'do_floating' => true, 'do_tenant' => true, 'do_provider' => false }])).to eq(["physnet1:br-floating", "physnet2:br-prv"]) + end + + it 'should be able to return without floating nets to bridge map' do + expect(@scope.function_generate_bridge_mappings([neutron_config, network_scheme, { 'do_floating' => false, 'do_tenant' => true, 'do_provider' => false }])).to eq(["physnet1:br-floating"]) + end + + end +end diff --git a/deployment/puppet/osnailyfacter/spec/functions/generate_physnet_vlan_ranges__spec.rb b/deployment/puppet/osnailyfacter/spec/functions/generate_physnet_vlan_ranges__spec.rb new file mode 100644 index 0000000000..2130d13f0f --- /dev/null +++ b/deployment/puppet/osnailyfacter/spec/functions/generate_physnet_vlan_ranges__spec.rb @@ -0,0 +1,170 @@ +require 'puppet' +require 'spec_helper' + +describe 'function for formating allocation pools for neutron subnet resource' do + + def setup_scope + @compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production')) + if Puppet.version =~ /^3\./ + @scope = Puppet::Parser::Scope.new(@compiler) + else + @scope = Puppet::Parser::Scope.new(:compiler => @compiler) + end + @topscope = @topscope + @scope.parent = @topscope + Puppet::Parser::Functions.function(:generate_physnet_vlan_ranges) + end + + describe 'basic tests' do + + before :each do + setup_scope + puppet_debug_override + end + + let :network_scheme do +{"transformations"=> + [{"action"=>"add-br", "name"=>"br-fw-admin"}, + {"action"=>"add-br", "name"=>"br-mgmt"}, + {"action"=>"add-br", "name"=>"br-storage"}, + {"action"=>"add-br", "name"=>"br-ex"}, + {"action"=>"add-br", "name"=>"br-floating", "provider"=>"ovs"}, + {"action"=>"add-patch", + "bridges"=>["br-floating", "br-ex"], + "provider"=>"ovs", + "mtu"=>65000}, + {"action"=>"add-br", "name"=>"br-prv", "provider"=>"ovs"}, + {"action"=>"add-br", "name"=>"br-aux"}, + {"action"=>"add-patch", + "bridges"=>["br-prv", "br-aux"], + "provider"=>"ovs", + "mtu"=>65000}, + {"action"=>"add-port", "bridge"=>"br-fw-admin", "name"=>"eth0"}, + {"action"=>"add-port", "bridge"=>"br-ex", "name"=>"eth1"}, + {"bridge"=>"br-aux", + "name"=>"bond0", + "interfaces"=>["eth2", "eth3"], + "bond_properties"=>{"mode"=>"active-backup"}, + "interface_properties"=>{"vendor_specific"=>{"disable_offloading"=>true}}, + "action"=>"add-bond"}, + {"action"=>"add-port", "bridge"=>"br-mgmt", "name"=>"bond0.101"}, + {"action"=>"add-port", "bridge"=>"br-storage", "name"=>"bond0.102"}], + "roles"=> + {"keystone/api"=>"br-mgmt", + "neutron/api"=>"br-mgmt", + "mgmt/database"=>"br-mgmt", + "sahara/api"=>"br-mgmt", + "heat/api"=>"br-mgmt", + "ceilometer/api"=>"br-mgmt", + "ex"=>"br-ex", + "ceph/public"=>"br-mgmt", + "mgmt/messaging"=>"br-mgmt", + "management"=>"br-mgmt", + "swift/api"=>"br-mgmt", + "storage"=>"br-storage", + "mgmt/corosync"=>"br-mgmt", + "cinder/api"=>"br-mgmt", + "public/vip"=>"br-ex", + "swift/replication"=>"br-storage", + "ceph/radosgw"=>"br-ex", + "admin/pxe"=>"br-fw-admin", + "mongo/db"=>"br-mgmt", + "neutron/private"=>"br-prv", + "neutron/floating"=>"br-floating", + "fw-admin"=>"br-fw-admin", + "glance/api"=>"br-mgmt", + "mgmt/vip"=>"br-mgmt", + "murano/api"=>"br-mgmt", + "nova/api"=>"br-mgmt", + "horizon"=>"br-mgmt", + "nova/migration"=>"br-mgmt", + "mgmt/memcache"=>"br-mgmt", + "cinder/iscsi"=>"br-storage", + "ceph/replication"=>"br-storage"}, + "interfaces"=> + {"eth5"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:08.0"}}, + "eth4"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:07.0"}}, + "eth3"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:06.0"}}, + "eth2"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:05.0"}}, + "eth1"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:04.0"}}, + "eth0"=> + {"vendor_specific"=>{"driver"=>"e1000", "bus_info"=>"0000:00:03.0"}}}, + "version"=>"1.1", + "provider"=>"lnx", + "endpoints"=> + {"br-fw-admin"=>{"IP"=>["10.109.0.4/24"]}, + "br-prv"=>{"IP"=>"none"}, + "br-floating"=>{"IP"=>"none"}, + "br-storage"=>{"IP"=>["192.168.1.1/24"]}, + "br-mgmt"=>{"IP"=>["192.168.0.4/24"]}, + "br-ex"=>{"IP"=>["10.109.1.4/24"], "gateway"=>"10.109.1.1"}} + } + end + + let :neutron_config do + {"default_floating_net"=>"admin_floating_net", + "database"=>{"passwd"=>"2eaczPxjQNxkR6qik3sZlsaW"}, + "default_private_net"=>"admin_internal_net", + "keystone"=>{"admin_password"=>"EanTYjYlXqzATHAriBPkllal"}, + "L3"=>{"use_namespaces"=>true}, + "L2"=>{"phys_nets"=>{"physnet1"=>{"bridge"=>"br-floating", "vlan_range"=>"1000:1030"}, + "physnet2"=>{"bridge"=>"br-prv", "vlan_range"=>nil}}, + "base_mac"=>"fa:16:3e:00:00:00", + "segmentation_type"=>"vlan"}, + "predefined_networks"=>{ + "admin_floating_net"=>{ + "shared"=>false, + "L2"=>{"network_type"=>"local", + "router_ext"=>true, + "physnet"=>'physnet2', + "segment_id"=>nil}, + "L3"=>{"nameservers"=>[], + "subnet"=>"10.109.1.0/24", + "floating"=>["10.109.1.130:10.109.1.254"], + "gateway"=>"10.109.1.1", + "enable_dhcp"=>false}, + "tenant"=>"admin"}, + "admin_internal_net"=>{ + "shared"=>false, + "L2"=>{"network_type"=>"vlan", + "router_ext"=>false, + "physnet"=>"physnet2", + "segment_id"=>nil}, + "L3"=>{"nameservers"=>["8.8.4.4", "8.8.8.8"], + "subnet"=>"192.168.111.0/24", + "floating"=>nil, + "gateway"=>"192.168.111.1", + "enable_dhcp"=>true}, + "tenant"=>"admin"}}, + "metadata"=>{"metadata_proxy_shared_secret"=>"uLLpFlxwX848GYnTUse2PjMp"} + } + end + + it "should exist" do + Puppet::Parser::Functions.function(:generate_physnet_vlan_ranges).should == "function_generate_physnet_vlan_ranges" + end + + it 'error if no arguments' do + lambda { @scope.function_generate_physnet_vlan_ranges([]) }.should raise_error(ArgumentError, 'generate_physnet_vlan_ranges(): wrong number of arguments (0; must be 3)') + end + + it 'should require one argument' do + lambda { @scope.function_generate_physnet_vlan_ranges(['foo', 'wee', 'ee', 'rr']) }.should raise_error(ArgumentError, 'generate_physnet_vlan_ranges(): wrong number of arguments (4; must be 3)') + end + + + it 'should be able to return floating nets to bridge map' do + expect(@scope.function_generate_physnet_vlan_ranges([neutron_config, network_scheme, { 'do_floating' => true, 'do_tenant' => true, 'do_provider' => false }])).to eq(["physnet1:1000:1030", "physnet2"]) + end + + it 'should be able to return without floating nets to bridge map' do + expect(@scope.function_generate_physnet_vlan_ranges([neutron_config, network_scheme, { 'do_floating' => false, 'do_tenant' => true, 'do_provider' => false }])).to eq(["physnet1:1000:1030"]) + end + + end +end