# # Configure OVS to use OpenDaylight # # === Parameters # # [*tunnel_ip*] # (required) The IP of the host to use for tunneling tenant VXLAN/GRE over # # [*odl_username*] # (optional) The opendaylight controller username # # [*odl_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' # # [*odl_ovsdb_iface*] # (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' # # [*provider_mappings*] # (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 # # [*retry_count*] # (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, flat, vlan, gre, vxlan # Defaults to ['local', 'flat', '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 the VIF when creating vhostuser ports. # Valid values are 'client' or 'server'. In client mode, openvswitch # will be responsible for creating the vhostuser socket. In server mode, # the hypervisor will create the vhostuser socket. # Defaults to "server" # # [*enable_hw_offload*] # (optional) Configure OVS to use # Hardware Offload. This feature is # supported from ovs 2.8.0. # Defaults to False. # # [*enable_tls*] # (optional) Configure OVS to use SSL/TLS # Defaults to False. # # [*tls_key_file*] # (optional) Private key file path to use for TLS configuration # Defaults to False. Required if enabling TLS. # # [*tls_cert_file*] # (optional) Certificate file path to use for TLS configuration # Defaults to False. Required if enabling TLS. # # [*tls_ca_cert_file*] # (optional) CA Certificate file path to use for TLS configuration # Defaults to False. # # [*enable_ipv6*] # (optional) If we should enable ipv6. # Defaults to False. # 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, $host_id = $fqdn, $allowed_network_types = ['local', 'flat', 'vlan', 'vxlan', 'gre'], $enable_dpdk = false, $vhostuser_socket_dir = '/var/run/openvswitch', $vhostuser_mode = 'server', $enable_hw_offload = false, $enable_tls = false, $tls_key_file = undef, $tls_cert_file = undef, $tls_ca_cert_file = undef, $enable_ipv6 = false, ) { include neutron::deps # Handle the case where ODL controller is also on this host Service<| title == 'opendaylight' |> -> Exec <| title == 'Wait for NetVirt OVSDB to come up' |> if $enable_tls { if empty($tls_key_file) or empty($tls_cert_file) { fail('When enabling TLS, tls_key_file and tls_cert_file must be provided') } if ! empty($tls_ca_cert_file) { vs_ssl { 'system': ensure => present, key_file => $tls_key_file, cert_file => $tls_cert_file, ca_file => $tls_ca_cert_file, before => Exec['Set OVS Manager to OpenDaylight'] } } else { vs_ssl { 'system': ensure => present, key_file => $tls_key_file, cert_file => $tls_cert_file, bootstrap => true, before => Exec['Set OVS Manager to OpenDaylight'] } } warning('TLS enabled, overriding all protocols') $odl_ovsdb_iface_proto = 'ssl' $ovsdb_server_iface_proto = 'pssl' $odl_check_url_proto = 'https' $cert_data = convert_cert_to_string($tls_cert_file) $rest_data = @("END":json/L) {\ "aaa-cert-rpc:input": {\ "aaa-cert-rpc:node-alias": "${::hostname}",\ "aaa-cert-rpc:node-cert": "${cert_data}"\ }\ } |-END $curl_post = "curl -k -X POST -o /dev/null --fail --silent -H 'Content-Type: application/json' -H 'Cache-Control: no-cache'" $curl_get = "curl -k -X POST --fail --silent -H 'Content-Type: application/json' -H 'Cache-Control: no-cache'" $rest_get_data = @("END":json/L) {\ "aaa-cert-rpc:input": {\ "aaa-cert-rpc:node-alias": "${::hostname}"\ }\ } |-END $ovsdb_arr = split($odl_ovsdb_iface, ' ') $odl_rest_port = regsubst($odl_check_url, '^.*:([0-9]+)/.*$', '\1') $ovsdb_arr.each |$ovsdb_uri| { $odl_ip = regsubst($ovsdb_uri, 'ssl:(.+):[0-9]+', '\1') $odl_url_prefix = "https://${odl_ip}:${odl_rest_port}" $cert_rest_url = "${odl_url_prefix}/restconf/operations/aaa-cert-rpc:setNodeCertifcate" $cert_rest_get = "${odl_url_prefix}/restconf/operations/aaa-cert-rpc:getNodeCertifcate" exec { "Add trusted cert: ${tls_cert_file} to ${odl_url_prefix}": command => "${curl_post} -u ${odl_username}:${odl_password} -d '${rest_data}' ${cert_rest_url}", tries => 5, try_sleep => 30, unless => "${curl_get} -u ${odl_username}:${odl_password} -d '${rest_get_data}' ${cert_rest_get} | grep -q ${cert_data}", path => '/usr/sbin:/usr/bin:/sbin:/bin', before => Exec['Set OVS Manager to OpenDaylight'], require => Exec['Wait for NetVirt OVSDB to come up'] } } } else { $odl_ovsdb_iface_proto = 'tcp' $ovsdb_server_iface_proto = 'ptcp' $odl_check_url_proto = 'http' } if $enable_ipv6 { $ovsdb_server_ip = '[::1]' } else { $ovsdb_server_ip = '127.0.0.1' } $odl_ovsdb_iface_parsed = regsubst($odl_ovsdb_iface, 'tcp', $odl_ovsdb_iface_proto, 'G') $ovsdb_server_iface_parsed = "${ovsdb_server_iface_proto}:6639:${ovsdb_server_ip}" $odl_check_url_parsed = regsubst($odl_check_url, 'http', $odl_check_url_proto) exec { 'Wait for NetVirt OVSDB to come up': command => "curl -g -k -o /dev/null --fail --silent --head -u ${odl_username}:${odl_password} ${odl_check_url_parsed}", tries => $retry_count, try_sleep => $retry_interval, path => '/usr/sbin:/usr/bin:/sbin:/bin', } # OVS manager -> exec { 'Set OVS Manager to OpenDaylight': command => "ovs-vsctl set-manager ${ovsdb_server_iface_parsed} ${odl_ovsdb_iface_parsed}", unless => "ovs-vsctl show | grep 'Manager \"${ovsdb_server_iface_parsed} ${odl_ovsdb_iface_parsed}\"'", path => '/usr/sbin:/usr/bin:/sbin:/bin', } # local ip 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), ',') 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, } # Set hostname to FQDN instead of default 'localhost' vs_config {'external_ids:hostname': value => $host_id, } $json_network_types = convert_to_json_string($allowed_network_types) $json_bridge_mappings = convert_to_json_string($provider_mappings) if $enable_hw_offload and $enable_dpdk { fail('Enabling hardware offload and DPDK is not allowed') } 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 } elsif $enable_hw_offload { require vswitch::ovs $host_config = @("END":json/L) {\ "supported_vnic_types": [{\ "vnic_type": "normal",\ "vif_type": "ovs",\ "vif_details": {}\ },{\ "vnic_type": "direct",\ "vif_type": "ovs",\ "vif_details": {}\ }],\ "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 } }