From 63a00045929fb3483866df9eea0390ebee5f52c5 Mon Sep 17 00:00:00 2001 From: Tim Rozet Date: Thu, 13 Jul 2017 22:10:50 -0400 Subject: [PATCH] Adds support for host config and cleanup Changes Include: - Adds host config necessary per OVS to allow ODL to work with pseudo agent binding controller (for port binding) - Cleans up some execs and uses the real vswitch provider - Fixes parameter spacing Closes-Bug: 1704206 Change-Id: Icc41c9936cae773f23281d6852a3a5e9cf4b9f89 Signed-off-by: Tim Rozet --- .../functions/convert_to_json_string.rb | 16 ++ manifests/plugins/ovs/opendaylight.pp | 144 +++++++++++++----- .../add_odl_host_config-e2b2810cfe9528a7.yaml | 4 + .../neutron_plugins_ovs_opendaylight_spec.rb | 53 +++++-- 4 files changed, 171 insertions(+), 46 deletions(-) create mode 100644 lib/puppet/parser/functions/convert_to_json_string.rb create mode 100644 releasenotes/notes/add_odl_host_config-e2b2810cfe9528a7.yaml diff --git a/lib/puppet/parser/functions/convert_to_json_string.rb b/lib/puppet/parser/functions/convert_to_json_string.rb new file mode 100644 index 000000000..ecc20015f --- /dev/null +++ b/lib/puppet/parser/functions/convert_to_json_string.rb @@ -0,0 +1,16 @@ +module Puppet::Parser::Functions + newfunction(:convert_to_json_string, :type => :rvalue) do |args| + require 'json' + value = args[0] + if (value.kind_of? Array) && value.all? {|x| x.include? ":"} + h = {} + value.each do |s| + k,v = s.split(/:/) + h[k] = v + end + return h.to_json + else + return value.to_json + end + end +end diff --git a/manifests/plugins/ovs/opendaylight.pp b/manifests/plugins/ovs/opendaylight.pp index 996391ba7..9f88609d8 100644 --- a/manifests/plugins/ovs/opendaylight.pp +++ b/manifests/plugins/ovs/opendaylight.pp @@ -4,51 +4,82 @@ # === Parameters # # [*tunnel_ip*] -# (required) The IP of the host to use for tunneling -# tenant VXLAN/GRE over +# (required) The IP of the host to use for tunneling tenant VXLAN/GRE over # # [*odl_username*] -# (optional) The opendaylight controller username +# (optional) The opendaylight controller username # # [*odl_password*] -# (optional) The opendaylight controller password +# (optional) The opendaylight controller password # # [*odl_check_url*] -# (optional) The URL used to check ODL is available and ready -# Defaults to 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1' +# (optional) The URL used to check ODL is available and ready +# Defaults to 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1' # # [*odl_ovsdb_iface*] -# (optional) The ODL southbound interface for OVSDB -# Defaults to 'tcp:127.0.0.1:6640' +# (optional) The ODL southbound interface for OVSDB +# Defaults to 'tcp:127.0.0.1:6640' # # [*ovsdb_server_iface*] -# (optional) The interface for OVSDB local server to listen on -# Defaults to 'ptcp:6639:127.0.0.1' +# (optional) The interface for OVSDB local server to listen on +# Defaults to 'ptcp:6639:127.0.0.1' # # [*provider_mappings*] -# (optional) List of : -# Required for VLAN provider networks. -# Required for Flat provider networks when using new NetVirt -# Defaults to empty list +# (optional) List of : +# Required for VLAN provider networks. +# Required for Flat provider networks when using new NetVirt +# Defaults to empty list # # [*retry_interval*] -# (optional) The time (in seconds) to wait between ODL availability checks -# Defaults to 60 +# (optional) The time (in seconds) to wait between ODL availability checks +# Defaults to 60 # # [*retry_count*] -# (optional) The number of ODL availability checks to run before failing -# Defaults to 20 +# (optional) The number of ODL availability checks to run before failing +# Defaults to 20 +# +# [*host_id*] +# (optional) The desired hostname for this node +# Defaults to FQDN hostname of the server +# +# [*allowed_network_types*] +# (optional) List of network_types to allocate as tenant networks. +# The value 'local' is only useful for single-box testing +# but provides no connectivity between hosts. +# Should be an array that can have these elements: +# local, vlan, gre, vxlan +# Defaults to ['local', 'vlan', 'gre', 'vxlan'] +# +# [*enable_dpdk*] +# (optional) Enables vhostuser VIF host configuration for OVS DPDK. +# Defaults to false. +# +# [*vhostuser_socket_dir*] +# (optional) Specify the directory to use for vhostuser sockets. +# Defaults to "/var/run/openvswitch" +# +# [*vhostuser_mode*] +# (optional) Specify the mode for OVS when creating vhostuser ports. +# Valid values are 'client' or 'server'. In client mode, the hypervisor +# will be responsible for creating the vhostuser socket. In server mode, +# OVS will create the vhostuser socket. +# Defaults to "client" # class neutron::plugins::ovs::opendaylight ( $tunnel_ip, $odl_username, $odl_password, - $odl_check_url = 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1', - $odl_ovsdb_iface = 'tcp:127.0.0.1:6640', - $ovsdb_server_iface = 'ptcp:6639:127.0.0.1', - $provider_mappings = [], - $retry_interval = 60, - $retry_count = 20, + $odl_check_url = 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1', + $odl_ovsdb_iface = 'tcp:127.0.0.1:6640', + $ovsdb_server_iface = 'ptcp:6639:127.0.0.1', + $provider_mappings = [], + $retry_interval = 60, + $retry_count = 20, + $host_id = $fqdn, + $allowed_network_types = ['local', 'vlan', 'vxlan', 'gre'], + $enable_dpdk = false, + $vhostuser_socket_dir = '/var/run/openvswitch', + $vhostuser_mode = 'client' ) { include ::neutron::deps @@ -64,24 +95,67 @@ class neutron::plugins::ovs::opendaylight ( } # OVS manager -> exec { 'Set OVS Manager to OpenDaylight': - command => "ovs-vsctl set-manager ${ovsdb_server_iface} ${odl_ovsdb_iface}", - unless => "ovs-vsctl show | grep 'Manager \"${ovsdb_server_iface} ${odl_ovsdb_iface}\"'", - path => '/usr/sbin:/usr/bin:/sbin:/bin', + command => "ovs-vsctl set-manager ${ovsdb_server_iface} ${odl_ovsdb_iface}", + unless => "ovs-vsctl show | grep 'Manager \"${ovsdb_server_iface} ${odl_ovsdb_iface}\"'", + path => '/usr/sbin:/usr/bin:/sbin:/bin', } + # local ip - -> exec { 'Set local_ip Other Option': - command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl get Open_vSwitch . _uuid) other_config:local_ip=${tunnel_ip}", - unless => "ovs-vsctl list Open_vSwitch | grep 'local_ip=\"${tunnel_ip}\"'", - path => '/usr/sbin:/usr/bin:/sbin:/bin', + vs_config {'other_config:local_ip': + value => $tunnel_ip, } # set mappings for VLAN or Flat provider networks if $provider_mappings and ! empty($provider_mappings) { $pr_map_str = join(any2array($provider_mappings), ',') - exec { 'Set provider_mappings Other Option': - command => "ovs-vsctl set Open_vSwitch $(ovs-vsctl get Open_vSwitch . _uuid) other_config:provider_mappings=${pr_map_str}", - unless => "ovs-vsctl list Open_vSwitch | grep 'provider_mappings' | grep ${pr_map_str}", - path => '/usr/sbin:/usr/bin:/sbin:/bin', + vs_config {'other_config:provider_mappings': + value => $pr_map_str } } + + # host config for pseudo agent binding type + vs_config {'external_ids:odl_os_hostconfig_hostid': + value => $host_id, + } + + $json_network_types = convert_to_json_string($allowed_network_types) + $json_bridge_mappings = convert_to_json_string($provider_mappings) + + if $enable_dpdk { + $host_config = @("END":json/$L) + {\ + "supported_vnic_types": [{\ + "vnic_type": "normal",\ + "vif_type": "vhostuser",\ + "vif_details": {\ + "uuid": "${::ovs_uuid}",\ + "has_datapath_type_netdev": true,\ + "port_prefix": "vhu_",\ + "vhostuser_socket_dir": "${vhostuser_socket_dir}",\ + "vhostuser_ovs_plug": true,\ + "vhostuser_mode": "${vhostuser_mode}",\ + "vhostuser_socket": "${vhostuser_socket_dir}/vhu_\$PORT_ID"\ + }\ + }],\ + "allowed_network_types": ${json_network_types},\ + "bridge_mappings": ${json_bridge_mappings}\ + } + |-END + } else { + $host_config = @("END":json/L) + {\ + "supported_vnic_types": [{\ + "vnic_type": "normal",\ + "vif_type": "ovs",\ + "vif_details": {}\ + }],\ + "allowed_network_types": ${json_network_types},\ + "bridge_mappings": ${json_bridge_mappings}\ + } + |-END + } + + vs_config {'external_ids:odl_os_hostconfig_config_odl_l2': + value => $host_config + } } diff --git a/releasenotes/notes/add_odl_host_config-e2b2810cfe9528a7.yaml b/releasenotes/notes/add_odl_host_config-e2b2810cfe9528a7.yaml new file mode 100644 index 000000000..98d56628c --- /dev/null +++ b/releasenotes/notes/add_odl_host_config-e2b2810cfe9528a7.yaml @@ -0,0 +1,4 @@ +--- +features: + - Adds support for host config for OVS when used with + OpenDaylight pseudo-agent port binding. diff --git a/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb b/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb index e7498e5ba..97d490d1a 100644 --- a/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb +++ b/spec/classes/neutron_plugins_ovs_opendaylight_spec.rb @@ -14,18 +14,23 @@ describe 'neutron::plugins::ovs::opendaylight' do let :default_params do { - :odl_check_url => 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1', - :odl_ovsdb_iface => 'tcp:127.0.0.1:6640', - :ovsdb_server_iface => 'ptcp:6639:127.0.0.1', - :provider_mappings => [], - :retry_interval => 60, - :retry_count => 20, + :odl_check_url => 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1', + :odl_ovsdb_iface => 'tcp:127.0.0.1:6640', + :ovsdb_server_iface => 'ptcp:6639:127.0.0.1', + :provider_mappings => [], + :retry_interval => 60, + :retry_count => 20, + :host_id => "dummy_host", + :allowed_network_types => ['local', 'vlan', 'vxlan', 'gre'], + :enable_dpdk => false, + :vhostuser_socket_dir => '/var/run/openvswitch', + :vhostuser_mode => 'client' } end let :params do { - :tunnel_ip => '127.0.0.1', + :tunnel_ip => '127.0.0.1', :odl_username => 'user', :odl_password => 'password', } @@ -50,6 +55,13 @@ describe 'neutron::plugins::ovs::opendaylight' do end it_configures 'with provider mappings' end + + context 'with DPDK enabled' do + before do + params.merge!({ :enable_dpdk => true }) + end + it_configures 'with DPDK enabled' + end it_configures 'with default parameters' end @@ -57,8 +69,10 @@ describe 'neutron::plugins::ovs::opendaylight' do it 'configures OVS for ODL' do is_expected.to contain_exec('Wait for NetVirt OVSDB to come up') is_expected.to contain_exec('Set OVS Manager to OpenDaylight') - is_expected.to contain_exec('Set local_ip Other Option') - is_expected.not_to contain_exec('Set provider_mappings Other Option') + is_expected.to contain_vs_config('other_config:local_ip') + is_expected.not_to contain_vs_config('other_config:provider_mappings') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_hostid') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_config_odl_l2') end end @@ -66,8 +80,25 @@ describe 'neutron::plugins::ovs::opendaylight' do it 'configures OVS for ODL' do is_expected.to contain_exec('Wait for NetVirt OVSDB to come up') is_expected.to contain_exec('Set OVS Manager to OpenDaylight') - is_expected.to contain_exec('Set local_ip Other Option') - is_expected.to contain_exec('Set provider_mappings Other Option') + is_expected.to contain_vs_config('other_config:local_ip') + is_expected.to contain_vs_config('other_config:provider_mappings') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_hostid') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_config_odl_l2').with( + :value => /bridge_mappings\": {\"default\":\"br-ex\"}/ + ) + end + end + + shared_examples_for 'with DPDK enabled' do + it 'configures OVS for ODL' do + is_expected.to contain_exec('Wait for NetVirt OVSDB to come up') + is_expected.to contain_exec('Set OVS Manager to OpenDaylight') + is_expected.to contain_vs_config('other_config:local_ip') + is_expected.not_to contain_vs_config('other_config:provider_mappings') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_hostid') + is_expected.to contain_vs_config('external_ids:odl_os_hostconfig_config_odl_l2').with( + :value => /vhostuser/, + ) end end