Adds TLS support to configuring OVS with OpenDaylight
Enables configuring OVS with SSL configuration, as well as setting OVS managers and ODL check url to use SSL/TLS. Each OVS will also register their certificate with OpenDaylight's truststore. Partially-Implements: blueprint opendaylight-ssl-support Depends-On: Ic026ee0bc4f385e0f8cd7076b3044feeb935ae45 Change-Id: I719e8dddbd00d19fd8e1bd2a20dabd600b7b9d1c Signed-off-by: Tim Rozet <trozet@redhat.com>
This commit is contained in:
parent
bcb2a54cb4
commit
65107cb5a8
|
@ -0,0 +1,19 @@
|
|||
Puppet::Functions.create_function(:convert_cert_to_string) do
|
||||
dispatch :convert_cert_to_string do
|
||||
param 'String', :cert_file
|
||||
end
|
||||
|
||||
def convert_cert_to_string(cert_file)
|
||||
unless File.file?(cert_file)
|
||||
raise puppet::ParseError, "Certificate file not found: #{cert_file}"
|
||||
end
|
||||
text=File.readlines(cert_file)
|
||||
cert_string = ''
|
||||
text.each do |line|
|
||||
unless line.include? '-----'
|
||||
cert_string += line.strip
|
||||
end
|
||||
end
|
||||
return cert_string
|
||||
end
|
||||
end
|
|
@ -71,6 +71,22 @@
|
|||
# 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.
|
||||
#
|
||||
class neutron::plugins::ovs::opendaylight (
|
||||
$tunnel_ip,
|
||||
$odl_username,
|
||||
|
@ -86,7 +102,11 @@ class neutron::plugins::ovs::opendaylight (
|
|||
$enable_dpdk = false,
|
||||
$vhostuser_socket_dir = '/var/run/openvswitch',
|
||||
$vhostuser_mode = 'client',
|
||||
$enable_hw_offload = false
|
||||
$enable_hw_offload = false,
|
||||
$enable_tls = false,
|
||||
$tls_key_file = undef,
|
||||
$tls_cert_file = undef,
|
||||
$tls_ca_cert_file = undef
|
||||
) {
|
||||
|
||||
include ::neutron::deps
|
||||
|
@ -94,16 +114,98 @@ class neutron::plugins::ovs::opendaylight (
|
|||
# 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']
|
||||
}
|
||||
}
|
||||
|
||||
if $odl_ovsdb_iface =~ /^tcp/ {
|
||||
warning('TLS enabled but odl_ovsdb_iface set to tcp. Will override to ssl')
|
||||
$odl_ovsdb_iface_parsed = regsubst($odl_ovsdb_iface, '^tcp', 'ssl')
|
||||
}
|
||||
|
||||
if $ovsdb_server_iface =~ /^ptcp/ {
|
||||
warning('TLS enabled but ovsdb_server_iface set to ptcp. Will override to pssl')
|
||||
$ovsdb_server_iface_parsed = regsubst($ovsdb_server_iface, '^ptcp', 'pssl')
|
||||
}
|
||||
|
||||
if $odl_check_url =~ /^http:/ {
|
||||
warning('TLS enabled but odl_check_url set to http. Will override to https')
|
||||
$odl_check_url_parsed = regsubst($odl_check_url, '^http:', 'https:')
|
||||
} else {
|
||||
$odl_check_url_parsed = $odl_check_url
|
||||
}
|
||||
|
||||
$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
|
||||
$odl_url_prefix = $odl_check_url_parsed ? {
|
||||
/^(https:\/\/.*?)\// => $1,
|
||||
default => undef
|
||||
}
|
||||
if $odl_url_prefix == undef {
|
||||
fail("Unable to parse URL prefix from ${odl_check_url_parsed}")
|
||||
}
|
||||
$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'"
|
||||
$cert_rest_url = "${odl_url_prefix}/restconf/operations/aaa-cert-rpc:setNodeCertifcate"
|
||||
$cert_rest_get = "${odl_url_prefix}/restconf/operations/aaa-cert-rpc:getNodeCertifcate"
|
||||
$rest_get_data = @("END":json/L)
|
||||
{\
|
||||
"aaa-cert-rpc:input": {\
|
||||
"aaa-cert-rpc:node-alias": "${::hostname}"\
|
||||
}\
|
||||
}
|
||||
|-END
|
||||
exec { "Add trusted cert: ${tls_cert_file}":
|
||||
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_parsed = $odl_ovsdb_iface
|
||||
$ovsdb_server_iface_parsed = $ovsdb_server_iface
|
||||
$odl_check_url_parsed = $odl_check_url
|
||||
}
|
||||
|
||||
exec { 'Wait for NetVirt OVSDB to come up':
|
||||
command => "curl -o /dev/null --fail --silent --head -u ${odl_username}:${odl_password} ${odl_check_url}",
|
||||
command => "curl -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} ${odl_ovsdb_iface}",
|
||||
unless => "ovs-vsctl show | grep 'Manager \"${ovsdb_server_iface} ${odl_ovsdb_iface}\"'",
|
||||
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',
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Enables using TLS in Open vSwitch (OVS) with OpenDaylight. OVS is
|
||||
configured to with certificates and private key to use in enabling a
|
||||
secure connection to OpenDaylight via OVSDB.
|
|
@ -2,16 +2,6 @@ require 'spec_helper'
|
|||
|
||||
describe 'neutron::plugins::ovs::opendaylight' do
|
||||
|
||||
let :pre_condition do
|
||||
"class { '::neutron::keystone::authtoken':
|
||||
password => 'passw0rd',
|
||||
}
|
||||
class { 'neutron::server': }
|
||||
class { 'neutron':
|
||||
rabbit_password => 'passw0rd',
|
||||
core_plugin => 'ml2' }"
|
||||
end
|
||||
|
||||
let :default_params do
|
||||
{
|
||||
:odl_check_url => 'http://127.0.0.1:8080/restconf/operational/network-topology:network-topology/topology/netvirt:1',
|
||||
|
@ -25,7 +15,8 @@ describe 'neutron::plugins::ovs::opendaylight' do
|
|||
:enable_dpdk => false,
|
||||
:vhostuser_socket_dir => '/var/run/openvswitch',
|
||||
:vhostuser_mode => 'client',
|
||||
:enable_hw_offload => false
|
||||
:enable_hw_offload => false,
|
||||
:enable_tls => false,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -70,7 +61,53 @@ describe 'neutron::plugins::ovs::opendaylight' do
|
|||
end
|
||||
it_raises 'a Puppet::Error',/Enabling hardware offload and DPDK is not allowed/
|
||||
end
|
||||
|
||||
it_configures 'with default parameters'
|
||||
|
||||
context 'with TLS and no key or certificates' do
|
||||
before do
|
||||
params.merge!({ :enable_tls => true })
|
||||
end
|
||||
it_raises 'a Puppet::Error',/When enabling TLS, tls_key_file and tls_cert_file must be provided/
|
||||
end
|
||||
|
||||
context 'with TLS and no CA cert' do
|
||||
before do
|
||||
File.stubs(:file?).returns(true)
|
||||
File.stubs(:readlines).returns(["MIIFGjCCBAKgAwIBAgICA"])
|
||||
params.merge!({
|
||||
:enable_tls => true,
|
||||
:tls_key_file => 'dummy.pem',
|
||||
:tls_cert_file => 'dummy.crt'})
|
||||
end
|
||||
it_configures 'with TLS enabled'
|
||||
it {is_expected.to contain_vs_ssl('system').with(
|
||||
'ensure' => 'present',
|
||||
'key_file' => 'dummy.pem',
|
||||
'cert_file' => 'dummy.crt',
|
||||
'bootstrap' => true,
|
||||
'before' => 'Exec[Set OVS Manager to OpenDaylight]'
|
||||
)}
|
||||
end
|
||||
context 'with TLS and CA cert' do
|
||||
before do
|
||||
File.stubs(:file?).returns(true)
|
||||
File.stubs(:readlines).returns(["MIIFGjCCBAKgAwIBAgICA"])
|
||||
params.merge!({
|
||||
:enable_tls => true,
|
||||
:tls_key_file => 'dummy.pem',
|
||||
:tls_cert_file => 'dummy.crt',
|
||||
:tls_ca_cert_file => 'ca.crt'})
|
||||
end
|
||||
it_configures 'with TLS enabled'
|
||||
it {is_expected.to contain_vs_ssl('system').with(
|
||||
'ensure' => 'present',
|
||||
'key_file' => 'dummy.pem',
|
||||
'cert_file' => 'dummy.crt',
|
||||
'ca_file' => 'ca.crt',
|
||||
'before' => 'Exec[Set OVS Manager to OpenDaylight]'
|
||||
)}
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'with default parameters' do
|
||||
|
@ -110,6 +147,17 @@ describe 'neutron::plugins::ovs::opendaylight' do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'with TLS enabled' do
|
||||
it 'configures OVS for ODL' do
|
||||
is_expected.to contain_exec('Add trusted cert: dummy.crt')
|
||||
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')
|
||||
end
|
||||
end
|
||||
|
||||
context 'on RedHat platforms' do
|
||||
let :facts do
|
||||
@default_facts.merge(test_facts.merge({
|
||||
|
|
Loading…
Reference in New Issue