Support ssl options for ovn db

This change introduces support for some options to enable ssl in OVN
northbound DB and OVN southbound DB. This also adds an option to inject
arbitrary options so that users can add additional options which are
not directly supported.

Change-Id: I8d70d691ff661f1341f546eedb2683549f08a3e7
This commit is contained in:
Takashi Kajinami 2023-02-26 16:06:01 +09:00
parent 9f91e4b106
commit 66187619f2
6 changed files with 382 additions and 14 deletions

View File

@ -110,6 +110,22 @@
# install new ones.
# Defaults to 8000
#
# [*ovn_controller_ssl_key*]
# OVN Controller SSL private key file
# Defaults to undef
#
# [*ovn_controller_ssl_cert*]
# OVN Controller SSL certificate file
# Defaults to undef
#
# [*ovn_controller_ssl_ca_cert*]
# OVN Controller SSL CA certificate file
# Defaults to undef
#
# [*ovn_controller_extra_opts*]
# Additional command line options for ovn-controller service
# Defaults to []
#
class ovn::controller(
$ovn_remote,
$ovn_encap_ip,
@ -131,7 +147,11 @@ class ovn::controller(
$ovn_chassis_mac_map = [],
$ovn_monitor_all = false,
$manage_ovs_bridge = true,
$ovn_ofctrl_wait_before_clear = 8000
$ovn_ofctrl_wait_before_clear = 8000,
$ovn_controller_ssl_key = undef,
$ovn_controller_ssl_cert = undef,
$ovn_controller_ssl_ca_cert = undef,
$ovn_controller_extra_opts = [],
) {
include ovn::params
@ -140,6 +160,7 @@ class ovn::controller(
validate_legacy(String, 'validate_string', $ovn_remote)
validate_legacy(String, 'validate_string', $ovn_encap_ip)
validate_legacy(Boolean, 'validate_bool', $manage_ovs_bridge)
validate_legacy(Array, 'validate_array', $ovn_controller_extra_opts)
if $enable_dpdk and ! $datapath_type {
fail('Datapath type must be set when DPDK is enabled')
@ -168,6 +189,27 @@ class ovn::controller(
name => $::ovn::params::ovn_controller_package_name,
}
if $ovn_controller_ssl_key and $ovn_controller_ssl_cert and $ovn_controller_ssl_ca_cert {
$ovn_controller_ssl_opts = [
"--ovn-controller-ssl-key=${ovn_controller_ssl_key}",
"--ovn-controller-ssl-cert=${ovn_controller_ssl_cert}",
"--ovn-controller-ssl-ca-cert=${ovn_controller_ssl_ca_cert}"
]
} elsif ! ($ovn_controller_ssl_key or $ovn_controller_ssl_cert or $ovn_controller_ssl_ca_cert) {
$ovn_controller_ssl_opts = []
} else {
fail('The ovn_controller_ssl_key, cert and ca_cert are required to use SSL.')
}
$ovn_controller_opts = join($ovn_controller_ssl_opts, ' ')
augeas { 'config-ovn-controller':
context => $::ovn::params::ovn_controller_context,
changes => "set ${$::ovn::params::ovn_controller_option_name} '\"${ovn_controller_opts}\"'",
require => Package[$::ovn::params::ovn_controller_package_name],
notify => Service['controller'],
}
$config_items = {
'external_ids:ovn-remote' => { 'value' => $ovn_remote },
'external_ids:ovn-encap-type' => { 'value' => $ovn_encap_type },

View File

@ -39,6 +39,34 @@
# OVN Northd SSL CA certificate file
# Defaults to undef
#
# [*ovn_nb_db_ssl_key*]
# OVN NB DB SSL private key file
# Defaults to undef
#
# [*ovn_nb_db_ssl_cert*]
# OVN NB DB SSL certificate file
# Defaults to undef
#
# [*ovn_nb_db_ssl_ca_cert*]
# OVN NB DB SSL CA certificate file
# Defaults to undef
#
# [*ovn_sb_db_ssl_key*]
# OVN SB DB SSL private key file
# Defaults to undef
#
# [*ovn_sb_db_ssl_cert*]
# OVN SB DB SSL certificate file
# Defaults to undef
#
# [*ovn_sb_db_ssl_ca_cert*]
# OVN SB DB SSL CA certificate file
# Defaults to undef
#
# [*ovn_northd_extra_opts*]
# Additional command line options for ovn-northd service
# Defaults to []
#
class ovn::northd(
$package_ensure = 'present',
$dbs_listen_ip = '0.0.0.0',
@ -49,34 +77,72 @@ class ovn::northd(
$ovn_northd_ssl_key = undef,
$ovn_northd_ssl_cert = undef,
$ovn_northd_ssl_ca_cert = undef,
$ovn_nb_db_ssl_key = undef,
$ovn_nb_db_ssl_cert = undef,
$ovn_nb_db_ssl_ca_cert = undef,
$ovn_sb_db_ssl_key = undef,
$ovn_sb_db_ssl_cert = undef,
$ovn_sb_db_ssl_ca_cert = undef,
$ovn_northd_extra_opts = [],
) {
include ovn::params
include vswitch::ovs
validate_legacy(Array, 'validate_array', $ovn_northd_extra_opts)
$dbs_listen_ip_real = normalize_ip_for_uri($dbs_listen_ip)
$ovn_northd_opts_addr = [
"--db-nb-addr=${dbs_listen_ip_real}",
"--db-sb-addr=${dbs_listen_ip_real}",
'--db-nb-create-insecure-remote=yes',
'--db-sb-create-insecure-remote=yes'
]
# NOTE(tkajinam): --db-(n|s)b-create-insecure-remote enables remote without
# ssl ( ptcp:<port>:<ip> ).
$ovn_northd_opts_nb_create_insecure_remote = $ovn_nb_db_ssl_key ? {
undef => ['--db-nb-create-insecure-remote=yes'],
default => ['--db-nb-create-insecure-remote=no']
}
$ovn_northd_opts_sb_create_insecure_remote = $ovn_sb_db_ssl_key ? {
undef => ['--db-sb-create-insecure-remote=yes'],
default => ['--db-sb-create-insecure-remote=no']
}
if $dbs_cluster_local_addr {
$ovn_northd_opts_nb_cluster_local_proto = $ovn_nb_db_ssl_key ? {
undef => [],
default => ['--db-nb-cluster-local-proto=ssl'],
}
$ovn_northd_opts_sb_cluster_local_proto = $ovn_nb_db_ssl_key ? {
undef => [],
default => ['--db-sb-cluster-local-proto=ssl'],
}
$ovn_northd_opts_cluster_local_addr = [
"--db-nb-cluster-local-addr=${dbs_cluster_local_addr}",
"--db-sb-cluster-local-addr=${dbs_cluster_local_addr}"
]
} else {
$ovn_northd_opts_nb_cluster_local_proto = []
$ovn_northd_opts_sb_cluster_local_proto = []
$ovn_northd_opts_cluster_local_addr = []
}
if $dbs_cluster_remote_addr {
$ovn_northd_opts_nb_cluster_remote_proto = $ovn_nb_db_ssl_key ? {
undef => [],
default => ['--db-nb-cluster-remote-proto=ssl']
}
$ovn_northd_opts_sb_cluster_remote_proto = $ovn_sb_db_ssl_key ? {
undef => [],
default => ['--db-sb-cluster-remote-proto=ssl']
}
$ovn_northd_opts_cluster_remote_addr = [
"--db-nb-cluster-remote-addr=${dbs_cluster_remote_addr}",
"--db-sb-cluster-remote-addr=${dbs_cluster_remote_addr}"
]
} else {
$ovn_northd_opts_nb_cluster_remote_proto = []
$ovn_northd_opts_sb_cluster_remote_proto = []
$ovn_northd_opts_cluster_remote_addr = []
}
@ -106,19 +172,52 @@ class ovn::northd(
fail('The ovn_northd_ssl_key, cert and ca_cert are required to use SSL.')
}
if $ovn_nb_db_ssl_key and $ovn_nb_db_ssl_cert and $ovn_nb_db_ssl_ca_cert {
$ovn_nb_db_ssl_opts = [
"--ovn-nb-db-ssl-key=${ovn_nb_db_ssl_key}",
"--ovn-nb-db-ssl-cert=${ovn_nb_db_ssl_cert}",
"--ovn-nb-db-ssl-ca-cert=${ovn_nb_db_ssl_ca_cert}"
]
} elsif ! ($ovn_nb_db_ssl_key or $ovn_nb_db_ssl_cert or $ovn_nb_db_ssl_ca_cert) {
$ovn_nb_db_ssl_opts = []
} else {
fail('The ovn_nb_db_ssl_key, cert and ca_cert are required to use SSL.')
}
if $ovn_sb_db_ssl_key and $ovn_sb_db_ssl_cert and $ovn_sb_db_ssl_ca_cert {
$ovn_sb_db_ssl_opts = [
"--ovn-sb-db-ssl-key=${ovn_sb_db_ssl_key}",
"--ovn-sb-db-ssl-cert=${ovn_sb_db_ssl_cert}",
"--ovn-sb-db-ssl-ca-cert=${ovn_sb_db_ssl_ca_cert}"
]
} elsif ! ($ovn_sb_db_ssl_key or $ovn_sb_db_ssl_cert or $ovn_sb_db_ssl_ca_cert) {
$ovn_sb_db_ssl_opts = []
} else {
fail('The ovn_sb_db_ssl_key, cert and ca_cert are required to use SSL.')
}
$ovn_northd_opts = join($ovn_northd_opts_addr +
$ovn_northd_opts_nb_create_insecure_remote +
$ovn_northd_opts_sb_create_insecure_remote +
$ovn_northd_opts_nb_cluster_local_proto +
$ovn_northd_opts_sb_cluster_local_proto +
$ovn_northd_opts_cluster_local_addr +
$ovn_northd_opts_nb_cluster_remote_proto +
$ovn_northd_opts_sb_cluster_remote_proto +
$ovn_northd_opts_cluster_remote_addr +
$ovn_northd_nb_db_opts +
$ovn_northd_sb_db_opts +
$ovn_northd_ssl_opts,
$ovn_northd_ssl_opts +
$ovn_nb_db_ssl_opts +
$ovn_sb_db_ssl_opts +
$ovn_northd_extra_opts,
' ')
augeas { 'config-ovn-northd':
context => $::ovn::params::ovn_northd_context,
changes => "set ${$::ovn::params::ovn_northd_option_name} '\"${ovn_northd_opts}\"'",
require => Package[$::vswitch::params::ovn_northd_package_name],
notify => Service['northd'],
require => Package[$::ovn::params::ovn_northd_package_name],
before => Service['northd'],
}
service { 'northd':
@ -136,4 +235,27 @@ class ovn::northd(
notify => Service['northd'],
require => Package[$::vswitch::params::ovs_package_name]
}
# NOTE(tkajinam): We have to escapte [ and ] otherwise egrep intereprets
# these wrongly.
$dbs_listen_ip_reg = regsubst(regsubst($dbs_listen_ip_real, '\]$', '\\]'), '^\[', '\\[')
if $ovn_nb_db_ssl_key {
exec { 'ovn-nb-set-connection':
command => "ovn-nbctl set-connection pssl:6641:${dbs_listen_ip_real}",
path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
unless => "ovn-nbctl get-connection | egrep -e '^pssl:6641:${dbs_listen_ip_reg}$'",
tag => 'ovn-db-set-connections',
require => Service['northd']
}
}
if $ovn_sb_db_ssl_key {
exec { 'ovn-sb-set-connection':
command => "ovn-sbctl set-connection pssl:6642:${dbs_listen_ip_real}",
path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
unless => "ovn-sbctl get-connection | egrep -e ' pssl:6642:${dbs_listen_ip_reg}$'",
tag => 'ovn-db-set-connections',
require => Service['northd']
}
}
}

View File

@ -17,6 +17,8 @@ class ovn::params {
$ovn_controller_service_name = 'ovn-controller'
$ovn_controller_service_status = true
$ovn_controller_service_pattern = undef
$ovn_controller_context = '/files/etc/sysconfig/ovn-controller'
$ovn_controller_option_name = 'OVN_CONTROLLER_OPTS'
}
'Debian': {
$ovn_northd_package_name = 'ovn-central'
@ -29,6 +31,8 @@ class ovn::params {
$ovn_controller_service_name = 'ovn-host'
$ovn_controller_service_status = false # status broken in UCA
$ovn_controller_service_pattern = 'ovn-controller'
$ovn_controller_context = '/files/etc/default/ovn-host'
$ovn_controller_option_name = 'OVN_CTL_OPTS'
}
default: {
fail " Osfamily ${::osfamily} not supported yet"

View File

@ -0,0 +1,13 @@
---
features:
- |
The ``ovn::northd`` class now supports configuring ssl for OVN northbound
DB and OVN southbound DB.
- |
The ``ovn::controller`` class now supports configuring ssl certificates for
connection to OVN SB DB.
- |
Now this module supports configuring additional command line options of
ovn-northd and ovn-controller.

View File

@ -36,6 +36,13 @@ describe 'ovn::controller' do
)
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-controller').with({
:context => platform_params[:ovn_controller_context],
:changes => "set " + platform_params[:ovn_controller_option_name] + " '\"\"'",
})
end
context 'with required parameters' do
it 'configures ovsdb' do
is_expected.to contain_vs_config('external_ids:ovn-remote').with(
@ -229,6 +236,25 @@ describe 'ovn::controller' do
end
end
end
context 'with ovn controller ssl' do
before :each do
params.merge!({
:ovn_controller_ssl_key => 'key.pem',
:ovn_controller_ssl_cert => 'cert.pem',
:ovn_controller_ssl_ca_cert => 'cacert.pem',
})
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-controller').with({
:context => platform_params[:ovn_controller_context],
:changes => "set " + platform_params[:ovn_controller_option_name] + " '\"" +
"--ovn-controller-ssl-key=key.pem --ovn-controller-ssl-cert=cert.pem --ovn-controller-ssl-ca-cert=cacert.pem" +
"\"'",
})
end
end
end
on_supported_os({
@ -248,7 +274,9 @@ describe 'ovn::controller' do
:ovn_controller_package_name => 'ovn-host',
:ovn_controller_service_name => 'ovn-host',
:ovn_controller_service_status => false,
:ovn_controller_service_pattern => 'ovn-controller'
:ovn_controller_service_pattern => 'ovn-controller',
:ovn_controller_context => '/files/etc/default/ovn-host',
:ovn_controller_option_name => 'OVN_CTL_OPTS'
}
end
it_behaves_like 'ovn controller'
@ -258,7 +286,9 @@ describe 'ovn::controller' do
:ovn_controller_package_name => 'openvswitch-ovn-host',
:ovn_controller_service_name => 'ovn-controller',
:ovn_controller_service_status => true,
:ovn_controller_service_pattern => nil
:ovn_controller_service_pattern => nil,
:ovn_controller_context => '/files/etc/sysconfig/ovn-controller',
:ovn_controller_option_name => 'OVN_CONTROLLER_OPTS'
}
end
it_behaves_like 'ovn controller'

View File

@ -10,10 +10,16 @@ describe 'ovn::northd' do
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] +
" '\"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0 --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=yes\"'",
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0" +
" --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=yes" +
"\"'",
})
end
it 'does not configure db connections' do
is_expected.to_not contain_exec('ovn-nb-set-connection')
is_expected.to_not contain_exec('ovn-sb-set-connection')
end
end
context 'with ipv6' do
@ -46,24 +52,175 @@ describe 'ovn::northd' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0 --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=yes" +
" --ovn-northd-nb-db=ssl:192.0.2.1:6645,ssl:192.0.2.2:6645,ssl:192.0.2.3:6645 --ovn-northd-sb-db=ssl:192.0.2.1:6646,ssl:192.0.2.2:6646,ssl:192.0.2.3:6646" +
"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0" +
" --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=yes" +
" --ovn-northd-nb-db=ssl:192.0.2.1:6645,ssl:192.0.2.2:6645,ssl:192.0.2.3:6645" +
" --ovn-northd-sb-db=ssl:192.0.2.1:6646,ssl:192.0.2.2:6646,ssl:192.0.2.3:6646" +
" --ovn-northd-ssl-key=key.pem --ovn-northd-ssl-cert=cert.pem --ovn-northd-ssl-ca-cert=cacert.pem" +
"\"'",
})
end
it 'does not configures db connections' do
is_expected.to_not contain_exec('ovn-nb-set-connection')
is_expected.to_not contain_exec('ovn-sb-set-connection')
end
end
context 'with bad ssl parameters' do
context 'with nb db ssl enabled' do
let :params do
{
:ovn_northd_ssl_key => 'key.pem',
:ovn_nb_db_ssl_key => 'dbkey.pem',
:ovn_nb_db_ssl_cert => 'dbcert.pem',
:ovn_nb_db_ssl_ca_cert => 'dbcacert.pem',
}
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0" +
" --db-nb-create-insecure-remote=no --db-sb-create-insecure-remote=yes" +
" --ovn-nb-db-ssl-key=dbkey.pem --ovn-nb-db-ssl-cert=dbcert.pem --ovn-nb-db-ssl-ca-cert=dbcacert.pem" +
"\"'",
})
end
it 'configures db connections' do
is_expected.to contain_exec('ovn-nb-set-connection').with({
:command => 'ovn-nbctl set-connection pssl:6641:0.0.0.0',
:path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
:unless => 'ovn-nbctl get-connection | egrep -e \'^pssl:6641:0.0.0.0$\'',
:tag => 'ovn-db-set-connections',
})
is_expected.to_not contain_exec('ovn-sb-set-connection')
end
end
context 'with ipv6 and nb db ssl enabled' do
let :params do
{
:dbs_listen_ip => '::1',
:ovn_nb_db_ssl_key => 'dbkey.pem',
:ovn_nb_db_ssl_cert => 'dbcert.pem',
:ovn_nb_db_ssl_ca_cert => 'dbcacert.pem',
}
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=[::1] --db-sb-addr=[::1]" +
" --db-nb-create-insecure-remote=no --db-sb-create-insecure-remote=yes" +
" --ovn-nb-db-ssl-key=dbkey.pem --ovn-nb-db-ssl-cert=dbcert.pem --ovn-nb-db-ssl-ca-cert=dbcacert.pem" +
"\"'",
})
end
it 'configures db connections' do
is_expected.to contain_exec('ovn-nb-set-connection').with({
:command => 'ovn-nbctl set-connection pssl:6641:[::1]',
:path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
:unless => 'ovn-nbctl get-connection | egrep -e \'^pssl:6641:\\[::1\\]$\'',
:tag => 'ovn-db-set-connections',
})
is_expected.to_not contain_exec('ovn-sb-set-connection')
end
end
context 'with sb db ssl enabled' do
let :params do
{
:ovn_sb_db_ssl_key => 'dbkey.pem',
:ovn_sb_db_ssl_cert => 'dbcert.pem',
:ovn_sb_db_ssl_ca_cert => 'dbcacert.pem',
}
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=0.0.0.0 --db-sb-addr=0.0.0.0" +
" --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=no" +
" --ovn-sb-db-ssl-key=dbkey.pem --ovn-sb-db-ssl-cert=dbcert.pem --ovn-sb-db-ssl-ca-cert=dbcacert.pem" +
"\"'",
})
end
it 'configures db connections' do
is_expected.to_not contain_exec('ovn-nb-set-connection')
is_expected.to contain_exec('ovn-sb-set-connection').with({
:command => 'ovn-sbctl set-connection pssl:6642:0.0.0.0',
:path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
:unless => 'ovn-sbctl get-connection | egrep -e \' pssl:6642:0.0.0.0$\'',
:tag => 'ovn-db-set-connections',
})
end
end
context 'with ipv6 and sb db ssl enabled' do
let :params do
{
:dbs_listen_ip => '::1',
:ovn_sb_db_ssl_key => 'dbkey.pem',
:ovn_sb_db_ssl_cert => 'dbcert.pem',
:ovn_sb_db_ssl_ca_cert => 'dbcacert.pem',
}
end
it 'creates systemd conf' do
is_expected.to contain_augeas('config-ovn-northd').with({
:context => platform_params[:ovn_northd_context],
:changes => "set " + platform_params[:ovn_northd_option_name] + " '\"" +
"--db-nb-addr=[::1] --db-sb-addr=[::1]" +
" --db-nb-create-insecure-remote=yes --db-sb-create-insecure-remote=no" +
" --ovn-sb-db-ssl-key=dbkey.pem --ovn-sb-db-ssl-cert=dbcert.pem --ovn-sb-db-ssl-ca-cert=dbcacert.pem" +
"\"'",
})
end
it 'configures db connections' do
is_expected.to_not contain_exec('ovn-nb-set-connection')
is_expected.to contain_exec('ovn-sb-set-connection').with({
:command => 'ovn-sbctl set-connection pssl:6642:[::1]',
:path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'],
:unless => 'ovn-sbctl get-connection | egrep -e \' pssl:6642:\\[::1\\]$\'',
:tag => 'ovn-db-set-connections',
})
end
end
context 'with bad northd ssl parameters' do
let :params do
{
:ovn_northd_ssl_key => 'key.pem',
}
end
it { should raise_error(Puppet::Error, /The ovn_northd_ssl_key, cert and ca_cert are required to use SSL/) }
end
context 'with bad nb db ssl parameters' do
let :params do
{
:ovn_nb_db_ssl_key => 'key.pem',
}
end
it { should raise_error(Puppet::Error, /The ovn_nb_db_ssl_key, cert and ca_cert are required to use SSL/) }
end
context 'with bad sb db ssl parameters' do
let :params do
{
:ovn_sb_db_ssl_key => 'key.pem',
}
end
it { should raise_error(Puppet::Error, /The ovn_sb_db_ssl_key, cert and ca_cert are required to use SSL/) }
end
end
shared_examples_for 'ovn northd' do