Adds TLS support for OpenDaylight
Allows enabling TLS for the ODL service as well as OVS. Partially-Implements: blueprint opendaylight-ssl-support Depends-On: I719e8dddbd00d19fd8e1bd2a20dabd600b7b9d1c Change-Id: Id579aea77bf8d679b514ef9851af36d9170e93a1 Signed-off-by: Tim Rozet <trozet@redhat.com>
This commit is contained in:
parent
cd8dd6c0d7
commit
10468ae5f9
77
manifests/certmonger/opendaylight.pp
Normal file
77
manifests/certmonger/opendaylight.pp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Copyright 2017 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# == Class: tripleo::certmonger::opendaylight
|
||||||
|
#
|
||||||
|
# Request a certificate for the opendaylight service and do the necessary setup.
|
||||||
|
#
|
||||||
|
# === Parameters
|
||||||
|
#
|
||||||
|
# [*hostname*]
|
||||||
|
# The hostname of the node. this will be set in the CN of the certificate.
|
||||||
|
#
|
||||||
|
# [*service_certificate*]
|
||||||
|
# The path to the certificate that will be used for TLS in this service.
|
||||||
|
#
|
||||||
|
# [*service_key*]
|
||||||
|
# The path to the key that will be used for TLS in this service.
|
||||||
|
#
|
||||||
|
# [*certmonger_ca*]
|
||||||
|
# (Optional) The CA that certmonger will use to generate the certificates.
|
||||||
|
# Defaults to hiera('certmonger_ca', 'local').
|
||||||
|
#
|
||||||
|
# [*postsave_cmd*]
|
||||||
|
# (Optional) Specifies the command to execute after requesting a certificate.
|
||||||
|
# Defaults to 'if systemctl -q is-active opendaylight; then systemctl restart opendaylight; else true; fi'
|
||||||
|
#
|
||||||
|
# [*principal*]
|
||||||
|
# (Optional) The haproxy service principal that is set for opendaylight in kerberos.
|
||||||
|
# Defaults to undef
|
||||||
|
#
|
||||||
|
class tripleo::certmonger::opendaylight (
|
||||||
|
$hostname,
|
||||||
|
$service_certificate,
|
||||||
|
$service_key,
|
||||||
|
$certmonger_ca = hiera('certmonger_ca', 'local'),
|
||||||
|
$postsave_cmd = 'if systemctl -q is-active opendaylight; then systemctl restart opendaylight; else true; fi',
|
||||||
|
$principal = undef,
|
||||||
|
) {
|
||||||
|
include ::certmonger
|
||||||
|
|
||||||
|
certmonger_certificate { 'opendaylight' :
|
||||||
|
ensure => 'present',
|
||||||
|
certfile => $service_certificate,
|
||||||
|
keyfile => $service_key,
|
||||||
|
hostname => $hostname,
|
||||||
|
dnsname => $hostname,
|
||||||
|
principal => $principal,
|
||||||
|
postsave_cmd => $postsave_cmd,
|
||||||
|
ca => $certmonger_ca,
|
||||||
|
wait => true,
|
||||||
|
require => Class['::certmonger'],
|
||||||
|
}
|
||||||
|
file { $service_certificate :
|
||||||
|
owner => 'odl',
|
||||||
|
group => 'odl',
|
||||||
|
require => Certmonger_certificate['opendaylight']
|
||||||
|
}
|
||||||
|
file { $service_key :
|
||||||
|
owner => 'odl',
|
||||||
|
group => 'odl',
|
||||||
|
require => Certmonger_certificate['opendaylight']
|
||||||
|
}
|
||||||
|
|
||||||
|
File[$service_certificate] -> Odl_keystore<| title == 'controller' |>
|
||||||
|
File[$service_key] -> Odl_keystore<| title == 'controller' |>
|
||||||
|
}
|
74
manifests/certmonger/openvswitch.pp
Normal file
74
manifests/certmonger/openvswitch.pp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Copyright 2017 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# == Class: tripleo::certmonger::openvswitch
|
||||||
|
#
|
||||||
|
# Request a certificate for the openvswitch service and do the necessary setup.
|
||||||
|
#
|
||||||
|
# === Parameters
|
||||||
|
#
|
||||||
|
# [*hostname*]
|
||||||
|
# The hostname of the node. this will be set in the CN of the certificate.
|
||||||
|
#
|
||||||
|
# [*service_certificate*]
|
||||||
|
# The path to the certificate that will be used for TLS in this service.
|
||||||
|
#
|
||||||
|
# [*service_key*]
|
||||||
|
# The path to the key that will be used for TLS in this service.
|
||||||
|
#
|
||||||
|
# [*certmonger_ca*]
|
||||||
|
# (Optional) The CA that certmonger will use to generate the certificates.
|
||||||
|
# Defaults to hiera('certmonger_ca', 'local').
|
||||||
|
#
|
||||||
|
# [*postsave_cmd*]
|
||||||
|
# (Optional) Specifies the command to execute after requesting a certificate.
|
||||||
|
# Defaults to "systemctl reload openvswitch"
|
||||||
|
#
|
||||||
|
# [*principal*]
|
||||||
|
# (Optional) The haproxy service principal that is set for openvswitch in kerberos.
|
||||||
|
# Defaults to undef
|
||||||
|
#
|
||||||
|
class tripleo::certmonger::openvswitch (
|
||||||
|
$hostname,
|
||||||
|
$service_certificate,
|
||||||
|
$service_key,
|
||||||
|
$certmonger_ca = hiera('certmonger_ca', 'local'),
|
||||||
|
$postsave_cmd = 'systemctl reload openvswitch',
|
||||||
|
$principal = undef,
|
||||||
|
) {
|
||||||
|
include ::certmonger
|
||||||
|
|
||||||
|
certmonger_certificate { 'openvswitch' :
|
||||||
|
ensure => 'present',
|
||||||
|
certfile => $service_certificate,
|
||||||
|
keyfile => $service_key,
|
||||||
|
hostname => $hostname,
|
||||||
|
dnsname => $hostname,
|
||||||
|
principal => $principal,
|
||||||
|
postsave_cmd => $postsave_cmd,
|
||||||
|
ca => $certmonger_ca,
|
||||||
|
wait => true,
|
||||||
|
require => Class['::certmonger'],
|
||||||
|
}
|
||||||
|
file { $service_certificate :
|
||||||
|
owner => 'openvswitch',
|
||||||
|
group => 'hugetlbfs',
|
||||||
|
require => Certmonger_certificate['openvswitch'],
|
||||||
|
}
|
||||||
|
file { $service_key :
|
||||||
|
owner => 'openvswitch',
|
||||||
|
group => 'hugetlbfs',
|
||||||
|
require => Certmonger_certificate['openvswitch'],
|
||||||
|
}
|
||||||
|
}
|
@ -688,6 +688,7 @@ class tripleo::haproxy (
|
|||||||
$nova_osapi_network = hiera('nova_api_network', undef),
|
$nova_osapi_network = hiera('nova_api_network', undef),
|
||||||
$nova_placement_network = hiera('nova_placement_network', undef),
|
$nova_placement_network = hiera('nova_placement_network', undef),
|
||||||
$octavia_network = hiera('octavia_api_network', undef),
|
$octavia_network = hiera('octavia_api_network', undef),
|
||||||
|
$opendaylight_network = hiera('opendaylight_api_network', undef),
|
||||||
$panko_network = hiera('panko_api_network', undef),
|
$panko_network = hiera('panko_api_network', undef),
|
||||||
$ovn_dbs_network = hiera('ovn_dbs_network', undef),
|
$ovn_dbs_network = hiera('ovn_dbs_network', undef),
|
||||||
$ec2_api_network = hiera('ec2_api_network', undef),
|
$ec2_api_network = hiera('ec2_api_network', undef),
|
||||||
@ -1494,6 +1495,8 @@ class tripleo::haproxy (
|
|||||||
ip_addresses => hiera('opendaylight_api_node_ips', $controller_hosts_real),
|
ip_addresses => hiera('opendaylight_api_node_ips', $controller_hosts_real),
|
||||||
server_names => hiera('opendaylight_api_node_names', $controller_hosts_names_real),
|
server_names => hiera('opendaylight_api_node_names', $controller_hosts_names_real),
|
||||||
mode => 'http',
|
mode => 'http',
|
||||||
|
member_options => union($haproxy_member_options, $internal_tls_member_options),
|
||||||
|
service_network => $opendaylight_network,
|
||||||
listen_options => {
|
listen_options => {
|
||||||
'balance' => 'source',
|
'balance' => 'source',
|
||||||
},
|
},
|
||||||
@ -1505,6 +1508,8 @@ class tripleo::haproxy (
|
|||||||
ip_addresses => hiera('opendaylight_api_node_ips', $controller_hosts_real),
|
ip_addresses => hiera('opendaylight_api_node_ips', $controller_hosts_real),
|
||||||
server_names => hiera('opendaylight_api_node_names', $controller_hosts_names_real),
|
server_names => hiera('opendaylight_api_node_names', $controller_hosts_names_real),
|
||||||
mode => 'http',
|
mode => 'http',
|
||||||
|
haproxy_listen_bind_param => [], # We don't use a transparent proxy (diverting non-destined haproxy traffic)
|
||||||
|
service_network => $opendaylight_network,
|
||||||
listen_options => {
|
listen_options => {
|
||||||
# NOTE(jaosorior): Websockets have more overhead in establishing
|
# NOTE(jaosorior): Websockets have more overhead in establishing
|
||||||
# connections than regular HTTP connections. Also, since it begins
|
# connections than regular HTTP connections. Also, since it begins
|
||||||
|
@ -83,6 +83,16 @@
|
|||||||
# it will create.
|
# it will create.
|
||||||
# Defaults to hiera('tripleo::profile::base::etcd::certificate_specs', {}).
|
# Defaults to hiera('tripleo::profile::base::etcd::certificate_specs', {}).
|
||||||
#
|
#
|
||||||
|
# [*odl_certificate_specs*]
|
||||||
|
# (Optional) The specifications to give to certmonger for the certificate(s)
|
||||||
|
# it will create.
|
||||||
|
# Defaults to hiera('tripleo::profile::base::odl::certificate_specs', {}).
|
||||||
|
#
|
||||||
|
# [*ovs_certificate_specs*]
|
||||||
|
# (Optional) The specifications to give to certmonger for the certificate(s)
|
||||||
|
# it will create.
|
||||||
|
# Defaults to hiera('tripleo::profile::base::ovs::certificate_specs', {}).
|
||||||
|
#
|
||||||
class tripleo::profile::base::certmonger_user (
|
class tripleo::profile::base::certmonger_user (
|
||||||
$apache_certificates_specs = hiera('apache_certificates_specs', {}),
|
$apache_certificates_specs = hiera('apache_certificates_specs', {}),
|
||||||
$apache_postsave_cmd = undef,
|
$apache_postsave_cmd = undef,
|
||||||
@ -94,6 +104,8 @@ class tripleo::profile::base::certmonger_user (
|
|||||||
$mysql_certificate_specs = hiera('tripleo::profile::base::database::mysql::certificate_specs', {}),
|
$mysql_certificate_specs = hiera('tripleo::profile::base::database::mysql::certificate_specs', {}),
|
||||||
$rabbitmq_certificate_specs = hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}),
|
$rabbitmq_certificate_specs = hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}),
|
||||||
$etcd_certificate_specs = hiera('tripleo::profile::base::etcd::certificate_specs', {}),
|
$etcd_certificate_specs = hiera('tripleo::profile::base::etcd::certificate_specs', {}),
|
||||||
|
$odl_certificate_specs = hiera('tripleo::profile::base::neutron::opendaylight::certificate_specs', {}),
|
||||||
|
$ovs_certificate_specs = hiera('tripleo::profile::base::neutron::plugins::ovs::opendaylight::certificate_specs', {}),
|
||||||
) {
|
) {
|
||||||
unless empty($haproxy_certificates_specs) {
|
unless empty($haproxy_certificates_specs) {
|
||||||
$reload_haproxy = ['systemctl reload haproxy']
|
$reload_haproxy = ['systemctl reload haproxy']
|
||||||
@ -140,4 +152,10 @@ class tripleo::profile::base::certmonger_user (
|
|||||||
unless empty($etcd_certificate_specs) {
|
unless empty($etcd_certificate_specs) {
|
||||||
ensure_resource('class', 'tripleo::certmonger::etcd', $etcd_certificate_specs)
|
ensure_resource('class', 'tripleo::certmonger::etcd', $etcd_certificate_specs)
|
||||||
}
|
}
|
||||||
|
unless empty($odl_certificate_specs) {
|
||||||
|
ensure_resource('class', 'tripleo::certmonger::opendaylight', $odl_certificate_specs)
|
||||||
|
}
|
||||||
|
unless empty($ovs_certificate_specs) {
|
||||||
|
ensure_resource('class', 'tripleo::certmonger::openvswitch', $ovs_certificate_specs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,15 +26,39 @@
|
|||||||
# (Optional) List of OpenStack Controller IPs for ODL API
|
# (Optional) List of OpenStack Controller IPs for ODL API
|
||||||
# Defaults to hiera('opendaylight_api_node_ips')
|
# Defaults to hiera('opendaylight_api_node_ips')
|
||||||
#
|
#
|
||||||
# [*node_name*]
|
# [*certificate_specs*]
|
||||||
# (Optional) The short hostname of node
|
# (Optional) The specifications to give to certmonger for the certificate
|
||||||
# Defaults to hiera('bootstrap_nodeid')
|
# it will create. Note that the certificate nickname must be 'etcd' in
|
||||||
|
# the case of this service.
|
||||||
|
# Example with hiera:
|
||||||
|
# tripleo::profile::base::etcd::certificate_specs:
|
||||||
|
# hostname: <overcloud controller fqdn>
|
||||||
|
# service_certificate: <service certificate path>
|
||||||
|
# service_key: <service key path>
|
||||||
|
# principal: "etcd/<overcloud controller fqdn>"
|
||||||
|
# Defaults to {}.
|
||||||
|
#
|
||||||
|
# [*enable_internal_tls*]
|
||||||
|
# (Optional) Whether TLS in the internal network is enabled or not.
|
||||||
|
# Defaults to hiera('enable_internal_tls', false)
|
||||||
#
|
#
|
||||||
class tripleo::profile::base::neutron::opendaylight (
|
class tripleo::profile::base::neutron::opendaylight (
|
||||||
$step = Integer(hiera('step')),
|
$step = Integer(hiera('step')),
|
||||||
$odl_api_ips = hiera('opendaylight_api_node_ips'),
|
$odl_api_ips = hiera('opendaylight_api_node_ips'),
|
||||||
|
$certificate_specs = {},
|
||||||
|
$enable_internal_tls = hiera('enable_internal_tls', false),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
validate_hash($certificate_specs)
|
||||||
|
|
||||||
|
if $enable_internal_tls {
|
||||||
|
$tls_certfile = $certificate_specs['service_certificate']
|
||||||
|
$tls_keyfile = $certificate_specs['service_key']
|
||||||
|
} else {
|
||||||
|
$tls_certfile = undef
|
||||||
|
$tls_keyfile = undef
|
||||||
|
}
|
||||||
|
|
||||||
if $step >= 1 {
|
if $step >= 1 {
|
||||||
validate_array($odl_api_ips)
|
validate_array($odl_api_ips)
|
||||||
if empty($odl_api_ips) {
|
if empty($odl_api_ips) {
|
||||||
@ -45,9 +69,16 @@ class tripleo::profile::base::neutron::opendaylight (
|
|||||||
class { '::opendaylight':
|
class { '::opendaylight':
|
||||||
enable_ha => true,
|
enable_ha => true,
|
||||||
ha_node_ips => $odl_api_ips,
|
ha_node_ips => $odl_api_ips,
|
||||||
|
enable_tls => $enable_internal_tls,
|
||||||
|
tls_key_file => $tls_keyfile,
|
||||||
|
tls_cert_file => $tls_certfile
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
include ::opendaylight
|
class { '::opendaylight':
|
||||||
|
enable_tls => $enable_internal_tls,
|
||||||
|
tls_key_file => $tls_keyfile,
|
||||||
|
tls_cert_file => $tls_certfile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,15 @@
|
|||||||
#
|
#
|
||||||
# [*conn_proto*]
|
# [*conn_proto*]
|
||||||
# (Optional) Protocol to use to for ODL REST access
|
# (Optional) Protocol to use to for ODL REST access
|
||||||
# Defaults to hiera('opendaylight::nb_connection_protocol')
|
# Defaults to 'http'
|
||||||
|
#
|
||||||
|
# [*enable_internal_tls*]
|
||||||
|
# (Optional) Whether TLS in the internal network is enabled or not.
|
||||||
|
# Defaults to hiera('enable_internal_tls', false)
|
||||||
|
#
|
||||||
|
# [*internal_api_fqdn*]
|
||||||
|
# (Optional) FQDN.
|
||||||
|
# Defaults to hiera('cloud_name_internal_api')
|
||||||
#
|
#
|
||||||
# [*step*]
|
# [*step*]
|
||||||
# (Optional) The current step in deployment. See tripleo-heat-templates
|
# (Optional) The current step in deployment. See tripleo-heat-templates
|
||||||
@ -48,17 +56,24 @@ class tripleo::profile::base::neutron::plugins::ml2::opendaylight (
|
|||||||
$odl_username = hiera('opendaylight::username'),
|
$odl_username = hiera('opendaylight::username'),
|
||||||
$odl_password = hiera('opendaylight::password'),
|
$odl_password = hiera('opendaylight::password'),
|
||||||
$odl_url_ip = hiera('opendaylight_api_vip'),
|
$odl_url_ip = hiera('opendaylight_api_vip'),
|
||||||
$conn_proto = hiera('opendaylight::nb_connection_protocol'),
|
$conn_proto = 'http',
|
||||||
|
$enable_internal_tls = hiera('enable_internal_tls', false),
|
||||||
|
$internal_api_fqdn = hiera('cloud_name_internal_api'),
|
||||||
$step = Integer(hiera('step')),
|
$step = Integer(hiera('step')),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if $step >= 4 {
|
if $step >= 4 {
|
||||||
if ! $odl_url_ip { fail('OpenDaylight API VIP is Empty') }
|
if $enable_internal_tls {
|
||||||
|
if empty($internal_api_fqdn) { fail('Internal API FQDN is Empty') }
|
||||||
|
$odl_url_addr = $internal_api_fqdn
|
||||||
|
} else {
|
||||||
|
if empty($odl_url_ip) { fail('OpenDaylight API VIP is Empty') }
|
||||||
|
$odl_url_addr = $odl_url_ip
|
||||||
|
}
|
||||||
class { '::neutron::plugins::ml2::opendaylight':
|
class { '::neutron::plugins::ml2::opendaylight':
|
||||||
odl_username => $odl_username,
|
odl_username => $odl_username,
|
||||||
odl_password => $odl_password,
|
odl_password => $odl_password,
|
||||||
odl_url => "${conn_proto}://${odl_url_ip}:${odl_port}/controller/nb/v2/neutron",
|
odl_url => "${conn_proto}://${odl_url_addr}:${odl_port}/controller/nb/v2/neutron",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,27 @@
|
|||||||
#
|
#
|
||||||
# [*conn_proto*]
|
# [*conn_proto*]
|
||||||
# (Optional) Protocol to use to for ODL REST access
|
# (Optional) Protocol to use to for ODL REST access
|
||||||
# Defaults to hiera('opendaylight::nb_connection_protocol')
|
# Defaults to 'http'
|
||||||
|
#
|
||||||
|
# [*certificate_specs*]
|
||||||
|
# (Optional) The specifications to give to certmonger for the certificate
|
||||||
|
# it will create. Note that the certificate nickname must be 'etcd' in
|
||||||
|
# the case of this service.
|
||||||
|
# Example with hiera:
|
||||||
|
# tripleo::profile::base::etcd::certificate_specs:
|
||||||
|
# hostname: <overcloud controller fqdn>
|
||||||
|
# service_certificate: <service certificate path>
|
||||||
|
# service_key: <service key path>
|
||||||
|
# principal: "etcd/<overcloud controller fqdn>"
|
||||||
|
# Defaults to {}.
|
||||||
|
#
|
||||||
|
# [*enable_internal_tls*]
|
||||||
|
# (Optional) Whether TLS in the internal network is enabled or not.
|
||||||
|
# Defaults to hiera('enable_internal_tls', false)
|
||||||
|
#
|
||||||
|
# [*tunnel_ip*]
|
||||||
|
# (Optional) IP to use for Tenant VXLAN/GRE tunneling source address
|
||||||
|
# Defaults to hiera('neutron::agents::ml2::ovs::local_ip')
|
||||||
#
|
#
|
||||||
# [*step*]
|
# [*step*]
|
||||||
# (Optional) The current step in deployment. See tripleo-heat-templates
|
# (Optional) The current step in deployment. See tripleo-heat-templates
|
||||||
@ -48,24 +68,39 @@ class tripleo::profile::base::neutron::plugins::ovs::opendaylight (
|
|||||||
$odl_check_url = hiera('opendaylight_check_url'),
|
$odl_check_url = hiera('opendaylight_check_url'),
|
||||||
$odl_api_ips = hiera('opendaylight_api_node_ips'),
|
$odl_api_ips = hiera('opendaylight_api_node_ips'),
|
||||||
$odl_url_ip = hiera('opendaylight_api_vip'),
|
$odl_url_ip = hiera('opendaylight_api_vip'),
|
||||||
$conn_proto = hiera('opendaylight::nb_connection_protocol'),
|
$conn_proto = 'http',
|
||||||
|
$certificate_specs = {},
|
||||||
|
$enable_internal_tls = hiera('enable_internal_tls', false),
|
||||||
|
$tunnel_ip = hiera('neutron::agents::ml2::ovs::local_ip'),
|
||||||
$step = Integer(hiera('step')),
|
$step = Integer(hiera('step')),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if $step >= 4 {
|
if $step >= 4 {
|
||||||
if empty($odl_api_ips) { fail('No IPs assigned to OpenDaylight Api Service') }
|
|
||||||
|
|
||||||
if ! $odl_url_ip { fail('OpenDaylight API VIP is Empty') }
|
if empty($odl_api_ips) { fail('No IPs assigned to OpenDaylight API Service') }
|
||||||
|
|
||||||
|
if empty($odl_url_ip) { fail('OpenDaylight API VIP is Empty') }
|
||||||
|
|
||||||
# Build URL to check if ODL is up before connecting OVS
|
# Build URL to check if ODL is up before connecting OVS
|
||||||
$opendaylight_url = "${conn_proto}://${odl_url_ip}:${odl_port}/${odl_check_url}"
|
$opendaylight_url = "${conn_proto}://${odl_url_ip}:${odl_port}/${odl_check_url}"
|
||||||
|
|
||||||
|
if $enable_internal_tls {
|
||||||
|
$tls_certfile = $certificate_specs['service_certificate']
|
||||||
|
$tls_keyfile = $certificate_specs['service_key']
|
||||||
|
$odl_ovsdb_str = join(regsubst($odl_api_ips, '.+', 'ssl:\0:6640'), ' ')
|
||||||
|
} else {
|
||||||
|
$tls_certfile = undef
|
||||||
|
$tls_keyfile = undef
|
||||||
$odl_ovsdb_str = join(regsubst($odl_api_ips, '.+', 'tcp:\0:6640'), ' ')
|
$odl_ovsdb_str = join(regsubst($odl_api_ips, '.+', 'tcp:\0:6640'), ' ')
|
||||||
|
}
|
||||||
|
|
||||||
class { '::neutron::plugins::ovs::opendaylight':
|
class { '::neutron::plugins::ovs::opendaylight':
|
||||||
tunnel_ip => hiera('neutron::agents::ml2::ovs::local_ip'),
|
tunnel_ip => $tunnel_ip,
|
||||||
odl_check_url => $opendaylight_url,
|
odl_check_url => $opendaylight_url,
|
||||||
odl_ovsdb_iface => $odl_ovsdb_str,
|
odl_ovsdb_iface => $odl_ovsdb_str,
|
||||||
|
enable_tls => $enable_internal_tls,
|
||||||
|
tls_key_file => $tls_keyfile,
|
||||||
|
tls_cert_file => $tls_certfile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds support for deploying OpenDaylight with TLS. Open vSwitch is also
|
||||||
|
configured with TLS in this deployment.
|
71
spec/classes/tripleo_certmonger_opendaylight_spec.rb
Normal file
71
spec/classes/tripleo_certmonger_opendaylight_spec.rb
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2017 Red Hat Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# Unit tests for tripleo
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'tripleo::certmonger::opendaylight' do
|
||||||
|
|
||||||
|
let :params do
|
||||||
|
{ :hostname => 'localhost',
|
||||||
|
:service_certificate => '/etc/pki/tls/certs/odl.crt',
|
||||||
|
:service_key => '/etc/pki/tls/private/odl.key',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples_for 'tripleo::certmonger::opendaylight' do
|
||||||
|
before :each do
|
||||||
|
facts.merge!({ :step => 1 })
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should include the base for using certmonger' do
|
||||||
|
is_expected.to contain_class('certmonger')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should request a certificate' do
|
||||||
|
is_expected.to contain_certmonger_certificate('opendaylight').with(
|
||||||
|
:ensure => 'present',
|
||||||
|
:certfile => params[:service_certificate],
|
||||||
|
:keyfile => params[:service_key],
|
||||||
|
:hostname => 'localhost',
|
||||||
|
:dnsname => 'localhost',
|
||||||
|
:ca => 'local',
|
||||||
|
:wait => true,
|
||||||
|
)
|
||||||
|
is_expected.to contain_file(params[:service_certificate]).with(
|
||||||
|
:owner => 'odl',
|
||||||
|
:group => 'odl',
|
||||||
|
:require => 'Certmonger_certificate[opendaylight]'
|
||||||
|
)
|
||||||
|
is_expected.to contain_file(params[:service_key]).with(
|
||||||
|
:owner => 'odl',
|
||||||
|
:group => 'odl',
|
||||||
|
:require => 'Certmonger_certificate[opendaylight]'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on_supported_os.each do |os, facts|
|
||||||
|
context "on #{os}" do
|
||||||
|
let(:facts) do
|
||||||
|
facts.merge({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'tripleo::certmonger::opendaylight'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
68
spec/classes/tripleo_certmonger_openvswitch_spec.rb
Normal file
68
spec/classes/tripleo_certmonger_openvswitch_spec.rb
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2017 Red Hat Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
# Unit tests for tripleo
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'tripleo::certmonger::openvswitch' do
|
||||||
|
|
||||||
|
shared_examples_for 'tripleo::certmonger::openvswitch' do
|
||||||
|
let :params do
|
||||||
|
{
|
||||||
|
:hostname => 'localhost',
|
||||||
|
:service_certificate => '/etc/pki/cert.crt',
|
||||||
|
:service_key => '/etc/pki/key.pem',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should include the base for using certmonger' do
|
||||||
|
is_expected.to contain_class('certmonger')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should request a certificate' do
|
||||||
|
is_expected.to contain_certmonger_certificate('openvswitch').with(
|
||||||
|
:ensure => 'present',
|
||||||
|
:certfile => '/etc/pki/cert.crt',
|
||||||
|
:keyfile => '/etc/pki/key.pem',
|
||||||
|
:hostname => 'localhost',
|
||||||
|
:dnsname => 'localhost',
|
||||||
|
:ca => 'local',
|
||||||
|
:wait => true,
|
||||||
|
)
|
||||||
|
is_expected.to contain_file('/etc/pki/cert.crt').with(
|
||||||
|
:owner => 'openvswitch',
|
||||||
|
:group => 'hugetlbfs',
|
||||||
|
:require => 'Certmonger_certificate[openvswitch]'
|
||||||
|
)
|
||||||
|
is_expected.to contain_file('/etc/pki/key.pem').with(
|
||||||
|
:owner => 'openvswitch',
|
||||||
|
:group => 'hugetlbfs',
|
||||||
|
:require => 'Certmonger_certificate[openvswitch]'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on_supported_os.each do |os, facts|
|
||||||
|
context "on #{os}" do
|
||||||
|
let(:facts) do
|
||||||
|
facts.merge({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'tripleo::certmonger::openvswitch'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,97 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'tripleo::profile::base::neutron::plugins::ml2::opendaylight' do
|
||||||
|
let :params do
|
||||||
|
{ :step => 4,
|
||||||
|
:odl_port => 8081,
|
||||||
|
:odl_username => 'dummy',
|
||||||
|
:odl_password => 'dummy'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
shared_examples_for 'tripleo::profile::base::neutron::plugins::ml2::opendaylight' do
|
||||||
|
before :each do
|
||||||
|
facts.merge!({ :step => params[:step] })
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with no TLS and API IP empty' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:odl_url_ip => '',
|
||||||
|
:internal_api_fqdn => [],
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it_raises 'a Puppet::Error',/OpenDaylight API VIP is Empty/
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with no TLS' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:odl_url_ip => '192.168.24.2',
|
||||||
|
:internal_api_fqdn => [],
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should configure ML2' do
|
||||||
|
is_expected.to contain_class('neutron::plugins::ml2::opendaylight').with(
|
||||||
|
:odl_username => params[:odl_username],
|
||||||
|
:odl_password => params[:odl_password],
|
||||||
|
:odl_url => "http://#{params[:odl_url_ip]}:#{params[:odl_port]}/controller/nb/v2/neutron"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with TLS and FQDN empty' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:enable_internal_tls => true,
|
||||||
|
:internal_api_fqdn => [],
|
||||||
|
:odl_url_ip => '192.168.24.2'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it_raises 'a Puppet::Error',/Internal API FQDN is Empty/
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with TLS' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:enable_internal_tls => true,
|
||||||
|
:conn_proto => 'https',
|
||||||
|
:internal_api_fqdn => 'example.cloud.org',
|
||||||
|
:odl_url_ip => '192.168.24.2'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should configure ML2' do
|
||||||
|
is_expected.to contain_class('neutron::plugins::ml2::opendaylight').with(
|
||||||
|
:odl_username => params[:odl_username],
|
||||||
|
:odl_password => params[:odl_password],
|
||||||
|
:odl_url => "https://#{params[:internal_api_fqdn]}:#{params[:odl_port]}/controller/nb/v2/neutron"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on_supported_os.each do |os, facts|
|
||||||
|
context "on #{os}" do
|
||||||
|
let(:facts) do
|
||||||
|
facts.merge({ :hostname => 'node.example.com' })
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'tripleo::profile::base::neutron::plugins::ml2::opendaylight'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -67,6 +67,46 @@ describe 'tripleo::profile::base::neutron::opendaylight' do
|
|||||||
end
|
end
|
||||||
it 'should install and configure OpenDaylight in HA' do
|
it 'should install and configure OpenDaylight in HA' do
|
||||||
is_expected.to contain_class('opendaylight').with(
|
is_expected.to contain_class('opendaylight').with(
|
||||||
|
:enable_ha => true,
|
||||||
|
:ha_node_ips => params[:odl_api_ips],
|
||||||
|
:enable_tls => false
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with TLS enabled' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:enable_internal_tls => true,
|
||||||
|
:certificate_specs => {
|
||||||
|
"service_certificate" => "/etc/pki/tls/certs/odl.crt",
|
||||||
|
"service_key" => "/etc/pki/tls/private/odl.key"}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should and configure OpenDaylight with TLS' do
|
||||||
|
is_expected.to contain_class('opendaylight').with(
|
||||||
|
:enable_tls => true,
|
||||||
|
:tls_key_file => params[:certificate_specs]['service_key'],
|
||||||
|
:tls_cert_file => params[:certificate_specs]['service_certificate']
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with TLS and HA enabled' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:enable_internal_tls => true,
|
||||||
|
:certificate_specs => {
|
||||||
|
"service_certificate" => "/etc/pki/tls/certs/odl.crt",
|
||||||
|
"service_key" => "/etc/pki/tls/private/odl.key"},
|
||||||
|
:odl_api_ips => ['192.0.2.5', '192.0.2.6', '192.0.2.7']
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should and configure OpenDaylight with TLS and HA' do
|
||||||
|
is_expected.to contain_class('opendaylight').with(
|
||||||
|
:enable_tls => true,
|
||||||
|
:tls_key_file => params[:certificate_specs]['service_key'],
|
||||||
|
:tls_cert_file => params[:certificate_specs]['service_certificate'],
|
||||||
:enable_ha => true,
|
:enable_ha => true,
|
||||||
:ha_node_ips => params[:odl_api_ips]
|
:ha_node_ips => params[:odl_api_ips]
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2018 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'tripleo::profile::base::neutron::plugins::ovs::opendaylight' do
|
||||||
|
let :params do
|
||||||
|
{ :step => 4,
|
||||||
|
:odl_port => 8081,
|
||||||
|
:odl_check_url => 'restconf/operational/network-topology:network-topology/topology/netvirt:1'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
shared_examples_for 'tripleo::profile::base::neutron::plugins::ovs::opendaylight' do
|
||||||
|
before :each do
|
||||||
|
facts.merge!({ :step => params[:step] })
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with empty OpenDaylight API IPs' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:odl_api_ips => [],
|
||||||
|
:tunnel_ip => '11.0.0.5',
|
||||||
|
:odl_url_ip => '192.0.2.6',
|
||||||
|
:odl_port => 8081
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should fail to configure OVS' do
|
||||||
|
is_expected.to compile.and_raise_error(/No IPs assigned to OpenDaylight API Service/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with empty OpenDaylight VIP' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:odl_api_ips => ['192.0.2.5'],
|
||||||
|
:odl_url_ip => [],
|
||||||
|
:tunnel_ip => '11.0.0.5',
|
||||||
|
:odl_port => 8081
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should fail to configure OVS' do
|
||||||
|
is_expected.to compile.and_raise_error(/OpenDaylight API VIP is Empty/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with no TLS' do
|
||||||
|
before do
|
||||||
|
params.merge!({
|
||||||
|
:odl_api_ips => ['192.0.2.5'],
|
||||||
|
:odl_url_ip => '192.0.2.6',
|
||||||
|
:tunnel_ip => '11.0.0.5',
|
||||||
|
:odl_port => 8081
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should configure OVS for ODL' do
|
||||||
|
is_expected.to contain_class('neutron::plugins::ovs::opendaylight').with(
|
||||||
|
:tunnel_ip => params[:tunnel_ip],
|
||||||
|
:odl_check_url => "http://#{params[:odl_url_ip]}:#{params[:odl_port]}/#{params[:odl_check_url]}",
|
||||||
|
:odl_ovsdb_iface => "tcp:#{params[:odl_api_ips][0]}:6640",
|
||||||
|
:enable_tls => false,
|
||||||
|
:tls_key_file => nil,
|
||||||
|
:tls_cert_file => nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with TLS enabled' do
|
||||||
|
before do
|
||||||
|
File.stubs(:file?).returns(true)
|
||||||
|
File.stubs(:readlines).returns(["MIIFGjCCBAKgAwIBAgICA"])
|
||||||
|
params.merge!({
|
||||||
|
:odl_api_ips => ['192.0.2.5'],
|
||||||
|
:odl_url_ip => '192.0.2.6',
|
||||||
|
:tunnel_ip => '11.0.0.5',
|
||||||
|
:enable_internal_tls => true,
|
||||||
|
:conn_proto => 'https',
|
||||||
|
:odl_port => 8081,
|
||||||
|
:certificate_specs => {
|
||||||
|
"service_certificate" => "/etc/pki/tls/certs/ovs.crt",
|
||||||
|
"service_key" => "/etc/pki/tls/private/ovs.key"}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
it 'should configure OVS for ODL' do
|
||||||
|
is_expected.to contain_class('neutron::plugins::ovs::opendaylight').with(
|
||||||
|
:tunnel_ip => params[:tunnel_ip],
|
||||||
|
:odl_check_url => "https://#{params[:odl_url_ip]}:#{params[:odl_port]}/#{params[:odl_check_url]}",
|
||||||
|
:odl_ovsdb_iface => "ssl:#{params[:odl_api_ips][0]}:6640",
|
||||||
|
:enable_tls => true,
|
||||||
|
:tls_key_file => params[:certificate_specs]['service_key'],
|
||||||
|
:tls_cert_file => params[:certificate_specs]['service_certificate']
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
on_supported_os.each do |os, facts|
|
||||||
|
context "on #{os}" do
|
||||||
|
let(:facts) do
|
||||||
|
facts.merge({ :hostname => 'node.example.com' })
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'tripleo::profile::base::neutron::plugins::ovs::opendaylight'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
3
spec/fixtures/hieradata/step1.yaml
vendored
3
spec/fixtures/hieradata/step1.yaml
vendored
@ -1,2 +1,5 @@
|
|||||||
---
|
---
|
||||||
step: 1
|
step: 1
|
||||||
|
opendaylight_api_node_ips:
|
||||||
|
- '192.0.2.5'
|
||||||
|
opendaylight::tls_keystore_password: 'password'
|
||||||
|
3
spec/fixtures/hieradata/step4.yaml
vendored
3
spec/fixtures/hieradata/step4.yaml
vendored
@ -25,4 +25,5 @@ fluentd::plugin_provider: "yum"
|
|||||||
fluentd::repo_install: false
|
fluentd::repo_install: false
|
||||||
fluentd::service_name: "fluentd"
|
fluentd::service_name: "fluentd"
|
||||||
fluentd::service_provider: "systemd"
|
fluentd::service_provider: "systemd"
|
||||||
|
neutron::plugins::ovs::opendaylight::odl_username: 'admin'
|
||||||
|
neutron::plugins::ovs::opendaylight::odl_password: 'admin'
|
||||||
|
Loading…
Reference in New Issue
Block a user