diff options
88 files changed, 2697 insertions, 297 deletions
@@ -1,9 +1,11 @@ pkg/ Gemfile.lock vendor/ -spec/fixtures/ +spec/fixtures/modules +spec/fixtures/manifests .vagrant/ .bundle/ +.bundle*/ coverage/ .idea/ *.swp @@ -1,9 +1,7 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org" group :development, :test, :system_tests do - gem 'puppet-openstack_spec_helper', - :git => 'https://git.openstack.org/openstack/puppet-openstack_spec_helper', - :require => false + gem 'puppet-openstack_spec_helper', :require => 'false', :git => 'https://git.openstack.org/openstack/puppet-openstack_spec_helper' end if facterversion = ENV['FACTER_GEM_VERSION'] diff --git a/Puppetfile_extras b/Puppetfile_extras index f224b9a..4bc9d3f 100644 --- a/Puppetfile_extras +++ b/Puppetfile_extras @@ -27,7 +27,7 @@ mod 'datacat', mod 'etcd', :git => 'https://github.com/cristifalcas/puppet-etcd', - :ref => '1.10.0' + :ref => '1.11.0' mod 'fdio', :git => 'https://git.fd.io/puppet-fdio', @@ -46,7 +46,7 @@ mod 'systemd', :ref => 'master' mod 'opendaylight', - :git => 'https://github.com/dfarrell07/puppet-opendaylight', + :git => 'https://git.opendaylight.org/gerrit/integration/packaging/puppet-opendaylight', :ref => 'master' mod 'ssh', @@ -1,2 +1,11 @@ # This is a cross-platform list tracking distribution packages needed by tests; # see http://docs.openstack.org/infra/bindep/ for additional information. + +libxml2-devel [test platform:rpm] +libxml2-dev [test platform:dpkg] +libxslt-devel [test platform:rpm] +libxslt1-dev [test platform:dpkg] +ruby-devel [test platform:rpm] +ruby-dev [test platform:dpkg] +zlib1g-dev [test platform:dpkg] +zlib-devel [test platform:rpm] diff --git a/manifests/certmonger/etcd.pp b/manifests/certmonger/etcd.pp new file mode 100644 index 0000000..0bddfb4 --- /dev/null +++ b/manifests/certmonger/etcd.pp @@ -0,0 +1,73 @@ +# 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::etcd +# +# Request a certificate for the etcd 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'). +# +# [*principal*] +# (Optional) The haproxy service principal that is set for etcd in kerberos. +# Defaults to undef +# +class tripleo::certmonger::etcd ( + $hostname, + $service_certificate, + $service_key, + $certmonger_ca = hiera('certmonger_ca', 'local'), + $principal = undef, +) { + include ::certmonger + + $postsave_cmd = 'systemctl reload etcd' + certmonger_certificate { 'etcd' : + 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 => 'etcd', + group => 'etcd', + require => Certmonger_certificate['etcd'], + } + file { $service_key : + owner => 'etcd', + group => 'etcd', + require => Certmonger_certificate['etcd'], + } + + File[$service_certificate] ~> Service<| title == 'etcd' |> + File[$service_key] ~> Service<| title == 'etcd' |> +} diff --git a/manifests/certmonger/haproxy.pp b/manifests/certmonger/haproxy.pp index 6668440..a5d1bf8 100644 --- a/manifests/certmonger/haproxy.pp +++ b/manifests/certmonger/haproxy.pp @@ -40,6 +40,11 @@ # (Optional) The CA that certmonger will use to generate the certificates. # Defaults to hiera('certmonger_ca', 'local'). # +# [*dnsnames*] +# (Optional) The DNS names that will be added for the SubjectAltNames entry +# in the certificate. If left unset, the value will be set to the $hostname. +# Defaults to undef +# # [*principal*] # The haproxy service principal that is set for HAProxy in kerberos. # @@ -50,6 +55,7 @@ define tripleo::certmonger::haproxy ( $hostname, $postsave_cmd, $certmonger_ca = hiera('certmonger_ca', 'local'), + $dnsnames = undef, $principal = undef, ){ include ::certmonger @@ -62,11 +68,17 @@ define tripleo::certmonger::haproxy ( } } + if $dnsnames { + $dnsnames_real = $dnsnames + } else { + $dnsnames_real = $hostname + } + certmonger_certificate { "${title}-cert": ensure => 'present', ca => $certmonger_ca, hostname => $hostname, - dnsname => $hostname, + dnsname => $dnsnames_real, certfile => $service_certificate, keyfile => $service_key, postsave_cmd => $postsave_cmd, diff --git a/manifests/certmonger/httpd.pp b/manifests/certmonger/httpd.pp index 74c0b5a..e9754f7 100644 --- a/manifests/certmonger/httpd.pp +++ b/manifests/certmonger/httpd.pp @@ -31,6 +31,11 @@ # (Optional) The CA that certmonger will use to generate the certificates. # Defaults to hiera('certmonger_ca', 'local'). # +# [*dnsnames*] +# (Optional) The DNS names that will be added for the SubjectAltNames entry +# in the certificate. If left unset, the value will be set to the $hostname. +# Defaults to undef +# # [*principal*] # The haproxy service principal that is set for HAProxy in kerberos. # @@ -39,18 +44,25 @@ define tripleo::certmonger::httpd ( $service_certificate, $service_key, $certmonger_ca = hiera('certmonger_ca', 'local'), + $dnsnames = undef, $principal = undef, ) { include ::certmonger include ::apache::params + if $dnsnames { + $dnsnames_real = $dnsnames + } else { + $dnsnames_real = $hostname + } + $postsave_cmd = "systemctl reload ${::apache::params::service_name}" certmonger_certificate { $name : ensure => 'present', certfile => $service_certificate, keyfile => $service_key, hostname => $hostname, - dnsname => $hostname, + dnsname => $dnsnames_real, principal => $principal, postsave_cmd => $postsave_cmd, ca => $certmonger_ca, diff --git a/manifests/certmonger/mongodb.pp b/manifests/certmonger/mongodb.pp new file mode 100644 index 0000000..0b2dd6a --- /dev/null +++ b/manifests/certmonger/mongodb.pp @@ -0,0 +1,87 @@ +# 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::mongodb +# +# Request a certificate for MongoDB 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. +# +# [*service_pem*] +# The file in PEM format that the HAProxy service will use as a certificate. +# +# [*certmonger_ca*] +# (Optional) The CA that certmonger will use to generate the certificates. +# Defaults to hiera('certmonger_ca', 'local'). +# +# [*principal*] +# (Optional) The service principal that is set for the service in kerberos. +# Defaults to undef +# +class tripleo::certmonger::mongodb ( + $hostname, + $service_certificate, + $service_key, + $service_pem, + $certmonger_ca = hiera('certmonger_ca', 'local'), + $principal = undef, +) { + include ::certmonger + include ::mongodb::params + + $postsave_cmd = "systemctl restart ${::mongodb::params::service_name}" + certmonger_certificate { 'mongodb' : + 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'], + } + + concat { $service_pem : + ensure => present, + mode => '0640', + owner => $::mongodb::params::user, + group => $::mongodb::params::group, + } + concat::fragment { 'mongodb-key-fragment': + target => $service_pem, + source => $service_key, + order => '01', + require => Certmonger_certificate['mongodb'], + } + concat::fragment { 'mongodb-cert-fragment': + target => $service_pem, + source => $service_certificate, + order => '10', + require => Certmonger_certificate['mongodb'], + } + + Concat::Fragment['mongodb-key-fragment'] ~> Service<| title == $::mongodb::params::service_name |> + Concat::Fragment['mongodb-cert-fragment'] ~> Service<| title == $::mongodb::params::service_name |> +} diff --git a/manifests/firewall.pp b/manifests/firewall.pp index 8c6a53b..b4d51d9 100644 --- a/manifests/firewall.pp +++ b/manifests/firewall.pp @@ -63,7 +63,7 @@ class tripleo::firewall( # anyone can add your own rules # example with Hiera: # - # tripleo::firewall::rules: + # tripleo::firewall::firewall_rules: # '300 allow custom application 1': # port: 999 # proto: udp diff --git a/manifests/firewall/post.pp b/manifests/firewall/post.pp index b76db75..7b5f563 100644 --- a/manifests/firewall/post.pp +++ b/manifests/firewall/post.pp @@ -36,7 +36,7 @@ class tripleo::firewall::post( if $debug { warning('debug is enabled, the traffic is not blocked.') } else { - firewall { '998 log all': + tripleo::firewall::rule{ '998 log all': proto => 'all', jump => 'LOG', } diff --git a/manifests/firewall/rule.pp b/manifests/firewall/rule.pp index 688144e..f1ea0c9 100644 --- a/manifests/firewall/rule.pp +++ b/manifests/firewall/rule.pp @@ -39,6 +39,10 @@ # (optional) The action policy associated to the rule. # Defaults to 'accept' # +# [*jump*] +# (optional) The chain to jump to. +# If present, overrides action +# # [*state*] # (optional) Array of states associated to the rule.. # Defaults to ['NEW'] @@ -75,6 +79,7 @@ define tripleo::firewall::rule ( $chain = 'INPUT', $destination = undef, $extras = {}, + $jump = undef, ) { if $port == 'all' { @@ -85,16 +90,25 @@ define tripleo::firewall::rule ( $port_real = $port } + if $jump != undef { + $jump_real = $jump + $action_real = undef + } else { + $jump_real = undef + $action_real = $action + } + $basic = { 'port' => $port_real, 'dport' => $dport, 'sport' => $sport, 'proto' => $proto, - 'action' => $action, + 'action' => $action_real, 'source' => $source, 'iniface' => $iniface, 'chain' => $chain, 'destination' => $destination, + 'jump' => $jump_real, } if $proto == 'icmp' { $ipv6 = { diff --git a/manifests/haproxy.pp b/manifests/haproxy.pp index a6bd1eb..a449a49 100644 --- a/manifests/haproxy.pp +++ b/manifests/haproxy.pp @@ -49,6 +49,10 @@ # The IPv4, IPv6 or filesystem socket path of the syslog server. # Defaults to '/dev/log' # +# [*haproxy_daemon*] +# Should haproxy run in daemon mode or not +# Defaults to true +# # [*controller_hosts*] # IPs of host or group of hosts to load-balance the services # Can be a string or an array. @@ -539,6 +543,7 @@ class tripleo::haproxy ( $haproxy_listen_bind_param = [ 'transparent' ], $haproxy_member_options = [ 'check', 'inter 2000', 'rise 2', 'fall 5' ], $haproxy_log_address = '/dev/log', + $haproxy_daemon = true, $haproxy_stats_user = 'admin', $haproxy_stats_password = undef, $controller_hosts = hiera('controller_node_ips'), @@ -718,6 +723,9 @@ class tripleo::haproxy ( if $enable_internal_tls { $internal_tls_member_options = ['ssl', 'verify required', "ca-file ${ca_bundle}"] + Haproxy::Balancermember { + verifyhost => true + } } else { $internal_tls_member_options = [] } @@ -797,22 +805,30 @@ class tripleo::haproxy ( "${redis_vip}:6379" => $haproxy_listen_bind_param, } + $haproxy_global_options = { + 'log' => "${haproxy_log_address} local0", + 'pidfile' => '/var/run/haproxy.pid', + 'user' => 'haproxy', + 'group' => 'haproxy', + 'maxconn' => $haproxy_global_maxconn, + 'ssl-default-bind-ciphers' => $ssl_cipher_suite, + 'ssl-default-bind-options' => $ssl_options, + 'stats' => [ + 'socket /var/lib/haproxy/stats mode 600 level user', + 'timeout 2m' + ], + } + if $haproxy_daemon == true { + $haproxy_daemonize = { + 'daemon' => '', + } + } else { + $haproxy_daemonize = {} + } + class { '::haproxy': service_manage => $haproxy_service_manage, - global_options => { - 'log' => "${haproxy_log_address} local0", - 'pidfile' => '/var/run/haproxy.pid', - 'user' => 'haproxy', - 'group' => 'haproxy', - 'daemon' => '', - 'maxconn' => $haproxy_global_maxconn, - 'ssl-default-bind-ciphers' => $ssl_cipher_suite, - 'ssl-default-bind-options' => $ssl_options, - 'stats' => [ - 'socket /var/lib/haproxy/stats mode 600 level user', - 'timeout 2m' - ], - }, + global_options => merge($haproxy_global_options, $haproxy_daemonize), defaults_options => { 'mode' => 'tcp', 'log' => 'global', @@ -1357,6 +1373,7 @@ class tripleo::haproxy ( ip_addresses => hiera('etcd_node_ips', $controller_hosts_real), server_names => hiera('etcd_node_names', $controller_hosts_names_real), service_network => $etcd_network, + member_options => union($haproxy_member_options, $internal_tls_member_options), listen_options => { 'balance' => 'source', } diff --git a/manifests/pacemaker/haproxy_with_vip.pp b/manifests/pacemaker/haproxy_with_vip.pp index a27b94b..606ac26 100644 --- a/manifests/pacemaker/haproxy_with_vip.pp +++ b/manifests/pacemaker/haproxy_with_vip.pp @@ -57,21 +57,36 @@ define tripleo::pacemaker::haproxy_with_vip( $ensure = true) { if($ensure) { + # NB: Until the IPaddr2 RA has a fix for https://bugzilla.redhat.com/show_bug.cgi?id=1445628 + # we need to specify the nic when creating the ipv6 vip. if is_ipv6_address($ip_address) { - $netmask = '64' + $netmask = '128' + $nic = interface_for_ip($ip_address) + $ipv6_addrlabel = '99' } else { - $netmask = '32' + $netmask = '32' + $nic = '' + $ipv6_addrlabel = '' + } + + $haproxy_in_container = hiera('haproxy_docker', false) + $constraint_target_name = $haproxy_in_container ? { + true => 'haproxy-bundle', + default => 'haproxy-clone' } pacemaker::resource::ip { "${vip_name}_vip": - ip_address => $ip_address, - cidr_netmask => $netmask, - location_rule => $location_rule, - tries => $pcs_tries, + ip_address => $ip_address, + cidr_netmask => $netmask, + nic => $nic, + ipv6_addrlabel => $ipv6_addrlabel, + location_rule => $location_rule, + tries => $pcs_tries, } + pacemaker::constraint::order { "${vip_name}_vip-then-haproxy": first_resource => "ip-${ip_address}", - second_resource => 'haproxy-clone', + second_resource => $constraint_target_name, first_action => 'start', second_action => 'start', constraint_params => 'kind=Optional', @@ -79,13 +94,18 @@ define tripleo::pacemaker::haproxy_with_vip( } pacemaker::constraint::colocation { "${vip_name}_vip-with-haproxy": source => "ip-${ip_address}", - target => 'haproxy-clone', + target => $constraint_target_name, score => 'INFINITY', tries => $pcs_tries, } + $service_resource = $haproxy_in_container ? { + true => Pacemaker::Resource::Bundle['haproxy-bundle'], + default => Pacemaker::Resource::Service['haproxy'] + } + Pacemaker::Resource::Ip["${vip_name}_vip"] -> - Pacemaker::Resource::Service['haproxy'] -> + $service_resource -> Pacemaker::Constraint::Order["${vip_name}_vip-then-haproxy"] -> Pacemaker::Constraint::Colocation["${vip_name}_vip-with-haproxy"] } diff --git a/manifests/profile/base/aodh/api.pp b/manifests/profile/base/aodh/api.pp index 22fc000..5c539fc 100644 --- a/manifests/profile/base/aodh/api.pp +++ b/manifests/profile/base/aodh/api.pp @@ -68,6 +68,7 @@ class tripleo::profile::base::aodh::api ( if $step >= 3 { include ::aodh::api + include ::apache::mod::ssl class { '::aodh::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/barbican/api.pp b/manifests/profile/base/barbican/api.pp index 71e4ea1..211e442 100644 --- a/manifests/profile/base/barbican/api.pp +++ b/manifests/profile/base/barbican/api.pp @@ -158,6 +158,7 @@ class tripleo::profile::base::barbican::api ( include ::barbican::api::logging include ::barbican::keystone::notification include ::barbican::quota + include ::apache::mod::ssl class { '::barbican::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/ceilometer.pp b/manifests/profile/base/ceilometer.pp index 2855bd2..a85be5d 100644 --- a/manifests/profile/base/ceilometer.pp +++ b/manifests/profile/base/ceilometer.pp @@ -104,5 +104,4 @@ class tripleo::profile::base::ceilometer ( } include ::ceilometer::config } - } diff --git a/manifests/profile/base/ceilometer/agent/notification.pp b/manifests/profile/base/ceilometer/agent/notification.pp index 7fe8e81..3fa139a 100644 --- a/manifests/profile/base/ceilometer/agent/notification.pp +++ b/manifests/profile/base/ceilometer/agent/notification.pp @@ -27,6 +27,7 @@ class tripleo::profile::base::ceilometer::agent::notification ( $step = hiera('step'), ) { include ::tripleo::profile::base::ceilometer + include ::tripleo::profile::base::ceilometer::upgrade if $step >= 4 { include ::ceilometer::agent::auth diff --git a/manifests/profile/base/ceilometer/agent/polling.pp b/manifests/profile/base/ceilometer/agent/polling.pp index 3706c2e..fedf035 100644 --- a/manifests/profile/base/ceilometer/agent/polling.pp +++ b/manifests/profile/base/ceilometer/agent/polling.pp @@ -51,6 +51,10 @@ class tripleo::profile::base::ceilometer::agent::polling ( ) { include ::tripleo::profile::base::ceilometer + if $central_namespace { + include ::tripleo::profile::base::ceilometer::upgrade + } + if $step >= 4 { include ::ceilometer::agent::auth class { '::ceilometer::agent::polling': @@ -60,5 +64,4 @@ class tripleo::profile::base::ceilometer::agent::polling ( coordination_url => join(['redis://:', $ceilometer_redis_password, '@', normalize_ip_for_uri($redis_vip), ':6379/']), } } - } diff --git a/manifests/profile/base/ceilometer/api.pp b/manifests/profile/base/ceilometer/api.pp index 1080355..0176380 100644 --- a/manifests/profile/base/ceilometer/api.pp +++ b/manifests/profile/base/ceilometer/api.pp @@ -65,6 +65,7 @@ class tripleo::profile::base::ceilometer::api ( if $step >= 3 { include ::ceilometer::api + include ::apache::mod::ssl class { '::ceilometer::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/ceilometer/collector.pp b/manifests/profile/base/ceilometer/collector.pp index 6b58286..a2c1e29 100644 --- a/manifests/profile/base/ceilometer/collector.pp +++ b/manifests/profile/base/ceilometer/collector.pp @@ -84,13 +84,4 @@ class tripleo::profile::base::ceilometer::collector ( include ::ceilometer::collector include ::ceilometer::dispatcher::gnocchi } - - # Re-run ceilometer-upgrade again in step 5 so gnocchi resource types - # are created safely. - if $step >= 5 and $sync_db { - exec {'ceilometer-db-upgrade': - command => 'ceilometer-upgrade --skip-metering-database', - path => ['/usr/bin', '/usr/sbin'], - } - } } diff --git a/manifests/profile/base/ceilometer/upgrade.pp b/manifests/profile/base/ceilometer/upgrade.pp new file mode 100644 index 0000000..d0fc9be --- /dev/null +++ b/manifests/profile/base/ceilometer/upgrade.pp @@ -0,0 +1,49 @@ +# Copyright 2016 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::profile::base::ceilometer::upgrade +# +# Ceilometer upgrade profile for tripleo +# +# === Parameters +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('bootstrap_nodeid') +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# + +class tripleo::profile::base::ceilometer::upgrade ( + $bootstrap_node = hiera('bootstrap_nodeid', undef), + $step = hiera('step'), +) { + if $::hostname == downcase($bootstrap_node) { + $sync_db = true + } else { + $sync_db = false + } + + # Run ceilometer-upgrade in step 5 so gnocchi resource types + # are created safely. + if $step >= 5 and $sync_db { + exec {'ceilometer-db-upgrade': + command => 'ceilometer-upgrade --skip-metering-database', + path => ['/usr/bin', '/usr/sbin'], + } + } +} diff --git a/manifests/profile/base/certmonger_user.pp b/manifests/profile/base/certmonger_user.pp index 4d91ac9..4ba51ec 100644 --- a/manifests/profile/base/certmonger_user.pp +++ b/manifests/profile/base/certmonger_user.pp @@ -48,6 +48,11 @@ # it will create. # Defaults to hiera('libvirt_certificates_specs', {}). # +# [*mongodb_certificate_specs*] +# (Optional) The specifications to give to certmonger for the certificate(s) +# it will create. +# Defaults to hiera('mongodb_certificate_specs',{}) +# # [*mysql_certificate_specs*] # (Optional) The specifications to give to certmonger for the certificate(s) # it will create. @@ -58,12 +63,19 @@ # it will create. # Defaults to hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}). # +# [*etcd_certificate_specs*] +# (Optional) The specifications to give to certmonger for the certificate(s) +# it will create. +# Defaults to hiera('tripleo::profile::base::etcd::certificate_specs', {}). +# class tripleo::profile::base::certmonger_user ( $apache_certificates_specs = hiera('apache_certificates_specs', {}), $haproxy_certificates_specs = hiera('tripleo::profile::base::haproxy::certificates_specs', {}), $libvirt_certificates_specs = hiera('libvirt_certificates_specs', {}), + $mongodb_certificate_specs = hiera('mongodb_certificate_specs',{}), $mysql_certificate_specs = hiera('tripleo::profile::base::database::mysql::certificate_specs', {}), $rabbitmq_certificate_specs = hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}), + $etcd_certificate_specs = hiera('tripleo::profile::base::etcd::certificate_specs', {}), ) { include ::tripleo::certmonger::ca::libvirt @@ -81,10 +93,16 @@ class tripleo::profile::base::certmonger_user ( # existing and need to be refreshed if it changed. Tripleo::Certmonger::Haproxy<||> ~> Haproxy::Listen<||> } + unless empty($mongodb_certificate_specs) { + ensure_resource('class', 'tripleo::certmonger::mongodb', $mongodb_certificate_specs) + } unless empty($mysql_certificate_specs) { ensure_resource('class', 'tripleo::certmonger::mysql', $mysql_certificate_specs) } unless empty($rabbitmq_certificate_specs) { ensure_resource('class', 'tripleo::certmonger::rabbitmq', $rabbitmq_certificate_specs) } + unless empty($etcd_certificate_specs) { + ensure_resource('class', 'tripleo::certmonger::etcd', $etcd_certificate_specs) + } } diff --git a/manifests/profile/base/cinder/api.pp b/manifests/profile/base/cinder/api.pp index c432fd6..2fd9a65 100644 --- a/manifests/profile/base/cinder/api.pp +++ b/manifests/profile/base/cinder/api.pp @@ -76,6 +76,7 @@ class tripleo::profile::base::cinder::api ( if $step >= 4 or ($step >= 3 and $sync_db) { include ::cinder::api + include ::apache::mod::ssl class { '::cinder::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/cinder/volume/dellsc.pp b/manifests/profile/base/cinder/volume/dellsc.pp index ab6bbeb..a60eadf 100644 --- a/manifests/profile/base/cinder/volume/dellsc.pp +++ b/manifests/profile/base/cinder/volume/dellsc.pp @@ -35,16 +35,20 @@ class tripleo::profile::base::cinder::volume::dellsc ( if $step >= 4 { cinder::backend::dellsc_iscsi { $backend_name : - san_ip => hiera('cinder::backend::dellsc_iscsi::san_ip', undef), - san_login => hiera('cinder::backend::dellsc_iscsi::san_login', undef), - san_password => hiera('cinder::backend::dellsc_iscsi::san_password', undef), - dell_sc_ssn => hiera('cinder::backend::dellsc_iscsi::dell_sc_ssn', undef), - iscsi_ip_address => hiera('cinder::backend::dellsc_iscsi::iscsi_ip_address', undef), - iscsi_port => hiera('cinder::backend::dellsc_iscsi::iscsi_port', undef), - dell_sc_api_port => hiera('cinder::backend::dellsc_iscsi::dell_sc_api_port', undef), - dell_sc_server_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_server_folder', undef), - dell_sc_volume_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_volume_folder', undef), - excluded_domain_ip => hiera('cinder::backend::dellsc_iscsi::excluded_domain_ip', undef), + san_ip => hiera('cinder::backend::dellsc_iscsi::san_ip', undef), + san_login => hiera('cinder::backend::dellsc_iscsi::san_login', undef), + san_password => hiera('cinder::backend::dellsc_iscsi::san_password', undef), + dell_sc_ssn => hiera('cinder::backend::dellsc_iscsi::dell_sc_ssn', undef), + iscsi_ip_address => hiera('cinder::backend::dellsc_iscsi::iscsi_ip_address', undef), + iscsi_port => hiera('cinder::backend::dellsc_iscsi::iscsi_port', undef), + dell_sc_api_port => hiera('cinder::backend::dellsc_iscsi::dell_sc_api_port', undef), + dell_sc_server_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_server_folder', undef), + dell_sc_volume_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_volume_folder', undef), + excluded_domain_ip => hiera('cinder::backend::dellsc_iscsi::excluded_domain_ip', undef), + secondary_san_ip => hiera('cinder::backend::dellsc_iscsi::secondary_san_ip', undef), + secondary_san_login => hiera('cinder::backend::dellsc_iscsi::secondary_san_login', undef), + secondary_san_password => hiera('cinder::backend::dellsc_iscsi::secondary_san_password', undef), + secondary_sc_api_port => hiera('cinder::backend::dellsc_iscsi::secondary_sc_api_port', undef), } } diff --git a/manifests/profile/base/cinder/volume/netapp.pp b/manifests/profile/base/cinder/volume/netapp.pp index fc652c9..43978da 100644 --- a/manifests/profile/base/cinder/volume/netapp.pp +++ b/manifests/profile/base/cinder/volume/netapp.pp @@ -59,6 +59,8 @@ class tripleo::profile::base::cinder::volume::netapp ( netapp_storage_pools => hiera('cinder::backend::netapp::netapp_storage_pools', undef), netapp_eseries_host_type => hiera('cinder::backend::netapp::netapp_eseries_host_type', undef), netapp_webservice_path => hiera('cinder::backend::netapp::netapp_webservice_path', undef), + nas_secure_file_operations => hiera('cinder::backend::netapp::nas_secure_file_operations', undef), + nas_secure_file_permissions => hiera('cinder::backend::netapp::nas_secure_file_permissions', undef), } } diff --git a/manifests/profile/base/cinder/volume/nfs.pp b/manifests/profile/base/cinder/volume/nfs.pp index 7b1f1b9..e384a79 100644 --- a/manifests/profile/base/cinder/volume/nfs.pp +++ b/manifests/profile/base/cinder/volume/nfs.pp @@ -29,6 +29,23 @@ # (Optional) List of mount options for the NFS share # Defaults to '' # +# [*cinder_nas_secure_file_operations*] +# (Optional) Allow network-attached storage systems to operate in a secure +# environment where root level access is not permitted. If set to False, +# access is as the root user and insecure. If set to True, access is not as +# root. If set to auto, a check is done to determine if this is a new +# installation: True is used if so, otherwise False. Default is auto. +# Defaults to $::os_service_default +# +# [*cinder_nas_secure_file_permissions*] +# (Optional) Set more secure file permissions on network-attached storage +# volume files to restrict broad other/world access. If set to False, +# volumes are created with open permissions. If set to True, volumes are +# created with permissions for the cinder user and group (660). If set to +# auto, a check is done to determine if this is a new installation: True is +# used if so, otherwise False. Default is auto. +# Defaults to $::os_service_default +# # [*step*] # (Optional) The current step in deployment. See tripleo-heat-templates # for more details. @@ -36,9 +53,11 @@ # class tripleo::profile::base::cinder::volume::nfs ( $cinder_nfs_servers, - $backend_name = hiera('cinder::backend::nfs::volume_backend_name', 'tripleo_nfs'), - $cinder_nfs_mount_options = '', - $step = hiera('step'), + $backend_name = hiera('cinder::backend::nfs::volume_backend_name', 'tripleo_nfs'), + $cinder_nfs_mount_options = '', + $cinder_nas_secure_file_operations = $::os_service_default, + $cinder_nas_secure_file_permissions = $::os_service_default, + $step = hiera('step'), ) { include ::tripleo::profile::base::cinder::volume @@ -52,9 +71,11 @@ class tripleo::profile::base::cinder::volume::nfs ( package {'nfs-utils': } -> cinder::backend::nfs { $backend_name : - nfs_servers => $cinder_nfs_servers, - nfs_mount_options => $cinder_nfs_mount_options, - nfs_shares_config => '/etc/cinder/shares-nfs.conf', + nfs_servers => $cinder_nfs_servers, + nfs_mount_options => $cinder_nfs_mount_options, + nfs_shares_config => '/etc/cinder/shares-nfs.conf', + nas_secure_file_operations => $cinder_nas_secure_file_operations, + nas_secure_file_permissions => $cinder_nas_secure_file_permissions, } } diff --git a/manifests/profile/base/database/mysql.pp b/manifests/profile/base/database/mysql.pp index b4ac8ac..2dac028 100644 --- a/manifests/profile/base/database/mysql.pp +++ b/manifests/profile/base/database/mysql.pp @@ -199,6 +199,9 @@ class tripleo::profile::base::database::mysql ( if hiera('nova_placement_enabled', false) { include ::nova::db::mysql_placement } + if hiera('octavia_api_enabled', false) { + include ::octavia::db::mysql + } if hiera('sahara_api_enabled', false) { include ::sahara::db::mysql } diff --git a/manifests/profile/base/database/mysql/client.pp b/manifests/profile/base/database/mysql/client.pp index 014ef35..3de1e97 100644 --- a/manifests/profile/base/database/mysql/client.pp +++ b/manifests/profile/base/database/mysql/client.pp @@ -35,6 +35,10 @@ # (Optional) Client IP address of the host that will be written in the mysql_read_default_file # Defaults to undef # +# [*ssl_ca*] +# (Optional) The SSL CA file to use to verify the MySQL server's certificate. +# Defaults to '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt' +# # [*step*] # (Optional) The current step in deployment. See tripleo-heat-templates # for more details. @@ -45,6 +49,7 @@ class tripleo::profile::base::database::mysql::client ( $mysql_read_default_file = '/etc/my.cnf.d/tripleo.cnf', $mysql_read_default_group = 'tripleo', $mysql_client_bind_address = undef, + $ssl_ca = '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', $step = hiera('step'), ) { if $step >= 1 { @@ -68,7 +73,7 @@ class tripleo::profile::base::database::mysql::client ( if $enable_ssl { $changes_ssl = [ "set ${mysql_read_default_group}/ssl '1'", - "set ${mysql_read_default_group}/ssl-ca '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt'" + "set ${mysql_read_default_group}/ssl-ca '${ssl_ca}'" ] } else { $changes_ssl = [ diff --git a/manifests/profile/base/docker.pp b/manifests/profile/base/docker.pp index 4797d86..29f8b75 100644 --- a/manifests/profile/base/docker.pp +++ b/manifests/profile/base/docker.pp @@ -32,6 +32,18 @@ # Configure a registry-mirror in the /etc/docker/daemon.json file. # (defaults to false) # +# [*docker_options*] +# OPTIONS that are used to startup the docker service. NOTE: +# --selinux-enabled is dropped due to recommendations here: +# https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/7.2_Release_Notes/technology-preview-file_systems.html +# Defaults to '--log-driver=journald --signature-verification=false' +# +# [*configure_storage*] +# Boolean. Whether to configure a docker storage backend. Defaults to true. +# +# [*storage_options*] +# Storage options to configure. Defaults to '-s overlay2' +# # [*step*] # step defaults to hiera('step') # @@ -39,6 +51,9 @@ class tripleo::profile::base::docker ( $docker_namespace = undef, $insecure_registry = false, $registry_mirror = false, + $docker_options = '--log-driver=journald --signature-verification=false', + $configure_storage = true, + $storage_options = '-s overlay2', $step = hiera('step'), ) { if $step >= 1 { @@ -57,9 +72,11 @@ class tripleo::profile::base::docker ( fail('You must provide a $docker_namespace in order to configure insecure registry') } $namespace = strip($docker_namespace.split('/')[0]) - $changes = [ "set INSECURE_REGISTRY '\"--insecure-registry ${namespace}\"'", ] + $changes = [ "set INSECURE_REGISTRY '\"--insecure-registry ${namespace}\"'", + "set OPTIONS '\"${docker_options}\"'" ] } else { - $changes = [ 'rm INSECURE_REGISTRY', ] + $changes = [ 'rm INSECURE_REGISTRY', + "set OPTIONS '\"${docker_options}\"'" ] } augeas { 'docker-sysconfig': @@ -79,12 +96,37 @@ class tripleo::profile::base::docker ( $mirror_changes = [ 'rm dict/entry[. = "registry-mirrors"]', ] } + file { '/etc/docker/daemon.json': + ensure => 'present', + content => '{}', + mode => '0644', + replace => false, + require => Package['docker'] + } + augeas { 'docker-daemon.json': lens => 'Json.lns', incl => '/etc/docker/daemon.json', changes => $mirror_changes, subscribe => Package['docker'], notify => Service['docker'], + require => File['/etc/docker/daemon.json'], + } + if $configure_storage { + if $storage_options == undef { + fail('You must provide a $storage_options in order to configure storage') + } + $storage_changes = [ "set DOCKER_STORAGE_OPTIONS '\" ${storage_options}\"'", ] + } else { + $storage_changes = [ 'rm DOCKER_STORAGE_OPTIONS', ] + } + + augeas { 'docker-sysconfig-storage': + lens => 'Shellvars.lns', + incl => '/etc/sysconfig/docker-storage', + changes => $storage_changes, + notify => Service['docker'], + require => Package['docker'], } } diff --git a/manifests/profile/base/etcd.pp b/manifests/profile/base/etcd.pp index c29c937..9f5d180 100644 --- a/manifests/profile/base/etcd.pp +++ b/manifests/profile/base/etcd.pp @@ -34,26 +34,63 @@ # (Optional) Array of host(s) for etcd nodes. # Defaults to hiera('etcd_node_ips', []). # +# [*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) +# # [*step*] # (Optional) The current step in deployment. See tripleo-heat-templates # for more details. # Defaults to hiera('step') # class tripleo::profile::base::etcd ( - $bind_ip = '127.0.0.1', - $client_port = '2379', - $peer_port = '2380', - $nodes = hiera('etcd_node_names', []), - $step = hiera('step'), + $bind_ip = '127.0.0.1', + $client_port = '2379', + $peer_port = '2380', + $nodes = hiera('etcd_node_names', []), + $certificate_specs = {}, + $enable_internal_tls = hiera('enable_internal_tls', false), + $step = hiera('step'), ) { + + validate_hash($certificate_specs) + + if $enable_internal_tls { + $tls_certfile = $certificate_specs['service_certificate'] + $tls_keyfile = $certificate_specs['service_key'] + $protocol = 'https' + } else { + $tls_certfile = undef + $tls_keyfile = undef + $protocol = 'http' + } + if $step >= 2 { class {'::etcd': - listen_client_urls => "http://${bind_ip}:${client_port}", - advertise_client_urls => "http://${bind_ip}:${client_port}", - listen_peer_urls => "http://${bind_ip}:${peer_port}", - initial_advertise_peer_urls => "http://${bind_ip}:${peer_port}", - initial_cluster => regsubst($nodes, '.+', "\\0=http://\\0:${peer_port}"), + listen_client_urls => "${protocol}://${bind_ip}:${client_port}", + advertise_client_urls => "${protocol}://${bind_ip}:${client_port}", + listen_peer_urls => "${protocol}://${bind_ip}:${peer_port}", + initial_advertise_peer_urls => "${protocol}://${bind_ip}:${peer_port}", + initial_cluster => regsubst($nodes, '.+', "\\0=${protocol}://\\0:${peer_port}"), proxy => 'off', + cert_file => $tls_certfile, + key_file => $tls_keyfile, + client_cert_auth => $enable_internal_tls, + peer_cert_file => $tls_certfile, + peer_key_file => $tls_keyfile, + peer_client_cert_auth => $enable_internal_tls, } } } diff --git a/manifests/profile/base/gnocchi/api.pp b/manifests/profile/base/gnocchi/api.pp index ce04abf..a4e9a30 100644 --- a/manifests/profile/base/gnocchi/api.pp +++ b/manifests/profile/base/gnocchi/api.pp @@ -47,6 +47,14 @@ # This is set by t-h-t. # Defaults to hiera('gnocchi_api_network', undef) # +# [*gnocchi_redis_password*] +# (Required) Password for the gnocchi redis user for the coordination url +# Defaults to hiera('gnocchi_redis_password') +# +# [*redis_vip*] +# (Required) Redis ip address for the coordination url +# Defaults to hiera('redis_vip') +# # [*step*] # (Optional) The current step in deployment. See tripleo-heat-templates # for more details. @@ -58,6 +66,8 @@ class tripleo::profile::base::gnocchi::api ( $enable_internal_tls = hiera('enable_internal_tls', false), $gnocchi_backend = downcase(hiera('gnocchi_backend', 'swift')), $gnocchi_network = hiera('gnocchi_api_network', undef), + $gnocchi_redis_password = hiera('gnocchi_redis_password'), + $redis_vip = hiera('redis_vip'), $step = hiera('step'), ) { if $::hostname == downcase($bootstrap_node) { @@ -85,6 +95,7 @@ class tripleo::profile::base::gnocchi::api ( if $step >= 3 { include ::gnocchi::api + include ::apache::mod::ssl class { '::gnocchi::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, @@ -93,7 +104,7 @@ class tripleo::profile::base::gnocchi::api ( if $step >= 4 { class { '::gnocchi::storage': - coordination_url => join(['redis://:', hiera('gnocchi_redis_password'), '@', normalize_ip_for_uri(hiera('redis_vip')), ':6379/']), + coordination_url => join(['redis://:', $gnocchi_redis_password, '@', normalize_ip_for_uri($redis_vip), ':6379/']), } case $gnocchi_backend { 'swift': { include ::gnocchi::storage::swift } diff --git a/manifests/profile/base/heat/api.pp b/manifests/profile/base/heat/api.pp index 8e2da7e..79eb77e 100644 --- a/manifests/profile/base/heat/api.pp +++ b/manifests/profile/base/heat/api.pp @@ -65,6 +65,7 @@ class tripleo::profile::base::heat::api ( if $step >= 3 { include ::heat::api + include ::apache::mod::ssl class { '::heat::wsgi::apache_api': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/heat/api_cfn.pp b/manifests/profile/base/heat/api_cfn.pp index 02eb82a..dad7b76 100644 --- a/manifests/profile/base/heat/api_cfn.pp +++ b/manifests/profile/base/heat/api_cfn.pp @@ -66,6 +66,7 @@ class tripleo::profile::base::heat::api_cfn ( if $step >= 3 { include ::heat::api_cfn + include ::apache::mod::ssl class { '::heat::wsgi::apache_api_cfn': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/heat/api_cloudwatch.pp b/manifests/profile/base/heat/api_cloudwatch.pp index 558d247..428bcf2 100644 --- a/manifests/profile/base/heat/api_cloudwatch.pp +++ b/manifests/profile/base/heat/api_cloudwatch.pp @@ -66,6 +66,7 @@ class tripleo::profile::base::heat::api_cloudwatch ( if $step >= 3 { include ::heat::api_cloudwatch + include ::apache::mod::ssl class { '::heat::wsgi::apache_api_cloudwatch': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/ironic/conductor.pp b/manifests/profile/base/ironic/conductor.pp index 941c0bd..5ebf167 100644 --- a/manifests/profile/base/ironic/conductor.pp +++ b/manifests/profile/base/ironic/conductor.pp @@ -44,6 +44,7 @@ class tripleo::profile::base::ironic::conductor ( include ::ironic::drivers::drac include ::ironic::drivers::ilo include ::ironic::drivers::ipmi + include ::ironic::drivers::redfish # TODO: deprecated code cleanup, remove in Queens ironic_config { 'ssh/libvirt_uri': ensure => absent; diff --git a/manifests/profile/base/keystone.pp b/manifests/profile/base/keystone.pp index 290abee..c7eea14 100644 --- a/manifests/profile/base/keystone.pp +++ b/manifests/profile/base/keystone.pp @@ -211,6 +211,7 @@ class tripleo::profile::base::keystone ( } include ::keystone::config + include ::apache::mod::ssl class { '::keystone::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, @@ -221,6 +222,12 @@ class tripleo::profile::base::keystone ( if $ldap_backend_enable { validate_hash($ldap_backends_config) + if !str2bool($::selinux) { + selboolean { 'authlogin_nsswitch_use_ldap': + value => on, + persistent => true, + } + } create_resources('::keystone::ldap_backend', $ldap_backends_config, { create_domain_entry => $manage_domain, }) @@ -337,5 +344,8 @@ class tripleo::profile::base::keystone ( if hiera('ec2_api_enabled', false) { include ::ec2api::keystone::auth } + if hiera('novajoin_enabled', false) { + include ::nova::metadata::novajoin::auth + } } } diff --git a/manifests/profile/base/mistral/api.pp b/manifests/profile/base/mistral/api.pp index 50708f1..4f81725 100644 --- a/manifests/profile/base/mistral/api.pp +++ b/manifests/profile/base/mistral/api.pp @@ -18,6 +18,27 @@ # # === Parameters # +# [*certificates_specs*] +# (Optional) The specifications to give to certmonger for the certificate(s) +# it will create. +# Example with hiera: +# apache_certificates_specs: +# httpd-internal_api: +# hostname: <overcloud controller fqdn> +# service_certificate: <service certificate path> +# service_key: <service key path> +# principal: "haproxy/<overcloud controller fqdn>" +# Defaults to hiera('apache_certificate_specs', {}). +# +# [*enable_internal_tls*] +# (Optional) Whether TLS in the internal network is enabled or not. +# Defaults to hiera('enable_internal_tls', false) +# +# [*mistral_api_network*] +# (Optional) The network name where the mistral API endpoint is listening on. +# This is set by t-h-t. +# Defaults to hiera('mistral_api_network', undef) +# # [*bootstrap_node*] # (Optional) The hostname of the node responsible for bootstrapping tasks # Defaults to hiera('bootstrap_nodeid') @@ -28,8 +49,11 @@ # Defaults to hiera('step') # class tripleo::profile::base::mistral::api ( - $bootstrap_node = hiera('bootstrap_nodeid', undef), - $step = hiera('step'), + $bootstrap_node = hiera('bootstrap_nodeid', undef), + $certificates_specs = hiera('apache_certificates_specs', {}), + $enable_internal_tls = hiera('enable_internal_tls', false), + $mistral_api_network = hiera('mistral_api_network', undef), + $step = hiera('step'), ) { if $::hostname == downcase($bootstrap_node) { $sync_db = true @@ -39,8 +63,24 @@ class tripleo::profile::base::mistral::api ( include ::tripleo::profile::base::mistral - if $step >= 4 or ($step >= 3 and $sync_db) { + if $enable_internal_tls { + if !$mistral_api_network { + fail('mistral_api_network is not set in the hieradata.') + } + $tls_certfile = $certificates_specs["httpd-${mistral_api_network}"]['service_certificate'] + $tls_keyfile = $certificates_specs["httpd-${mistral_api_network}"]['service_key'] + } else { + $tls_certfile = undef + $tls_keyfile = undef + } + + if $step >= 3 { include ::mistral::api + include ::apache::mod::ssl + class { '::mistral::wsgi::apache': + ssl_cert => $tls_certfile, + ssl_key => $tls_keyfile, + } } } diff --git a/manifests/profile/base/neutron/agents/bigswitch.pp b/manifests/profile/base/neutron/agents/bigswitch.pp new file mode 100644 index 0000000..137dec0 --- /dev/null +++ b/manifests/profile/base/neutron/agents/bigswitch.pp @@ -0,0 +1,31 @@ +# 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::profile::base::neutron::agents::bigswitch +# +# Bigswitch Neutron agent profile +# +# === Parameters +# +# [*step*] +# (Optional) The current step of the deployment +# Defaults to hiera('step') +# +class tripleo::profile::base::neutron::agents::bigswitch( + $step = hiera('step'), +) { + if $step >= 4 { + include ::neutron::agents::bigswitch + } +} diff --git a/manifests/profile/base/neutron/lbaas.pp b/manifests/profile/base/neutron/lbaas.pp new file mode 100644 index 0000000..a6e42ee --- /dev/null +++ b/manifests/profile/base/neutron/lbaas.pp @@ -0,0 +1,44 @@ +# Copyright 2016 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::profile::base::neutron::lbaas +# +# Neutron LBaaS Agent profile for tripleo +# +# === Parameters +# +# [*manage_haproxy_package*] +# (Optional) Whether to manage the haproxy package. +# Defaults to hiera('manage_haproxy_package', false) +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +class tripleo::profile::base::neutron::lbaas( + $manage_haproxy_package = hiera('manage_haproxy_package', false), + $step = hiera('step'), +) { + + include ::tripleo::profile::base::neutron + + #LBaaS Driver needs to be run @ $step>=5 as the neutron service needs to already be active which is run @ $step==4 + if $step >= 5 { + include ::neutron::services::lbaas + class {'::neutron::agents::lbaas': + manage_haproxy_package => $manage_haproxy_package + } + } +} diff --git a/manifests/profile/base/neutron/linuxbridge.pp b/manifests/profile/base/neutron/linuxbridge.pp new file mode 100644 index 0000000..9f4899a --- /dev/null +++ b/manifests/profile/base/neutron/linuxbridge.pp @@ -0,0 +1,20 @@ +# == Class: tripleo::profile::base::neutron::linuxbridge +# +# Neutron linuxbridge agent profile for tripleo +# +# === Parameters +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templatee +# for more details. +# Defaults to hiera('step') +# +class tripleo::profile::base::neutron::linuxbridge( + $step = hiera('step'), +) { + include ::tripleo::profile::base::neutron + + if $step >= 5 { + include ::neutron::agents::ml2::linuxbridge + } +} diff --git a/manifests/profile/base/neutron/ovs.pp b/manifests/profile/base/neutron/ovs.pp index bec7e96..97eb8e9 100644 --- a/manifests/profile/base/neutron/ovs.pp +++ b/manifests/profile/base/neutron/ovs.pp @@ -23,12 +23,27 @@ # for more details. # Defaults to hiera('step') # +# [*vhostuser_socket_dir*] +# (Optional) vhostuser socket dir, The directory where $vhostuser_socket_dir +# will be created with correct permissions, inorder to support vhostuser +# client mode. + class tripleo::profile::base::neutron::ovs( - $step = hiera('step'), + $step = hiera('step'), + $vhostuser_socket_dir = hiera('neutron::agents::ml2::ovs::vhostuser_socket_dir', undef) ) { include ::tripleo::profile::base::neutron if $step >= 5 { + if $vhostuser_socket_dir { + file { $vhostuser_socket_dir: + ensure => directory, + owner => 'qemu', + group => 'qemu', + mode => '0775', + } + } + include ::neutron::agents::ml2::ovs # Optional since manage_service may be false and neutron server may not be colocated. diff --git a/manifests/profile/base/neutron/plugins/ml2/bagpipe.pp b/manifests/profile/base/neutron/plugins/ml2/bagpipe.pp new file mode 100644 index 0000000..161cd75 --- /dev/null +++ b/manifests/profile/base/neutron/plugins/ml2/bagpipe.pp @@ -0,0 +1,37 @@ +# +# Copyright (C) 2017 Red Hat Inc. +# +# Author: Ricardo Noriega <rnoriega@redhat.com> +# +# 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::profile::base::neutron::plugins::ml2::bagpipe +# +# Neutron Bagpipe ML2 profile for TripleO +# +# === Parameters +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +class tripleo::profile::base::neutron::plugins::ml2::bagpipe ( + $step = hiera('step'), +) { + include ::tripleo::profile::base::neutron + + if $step >= 4 { + include ::neutron::plugins::ml2::bagpipe + } +} diff --git a/manifests/profile/base/neutron/plugins/nsx_v3.pp b/manifests/profile/base/neutron/plugins/nsx_v3.pp new file mode 100644 index 0000000..33fa0cf --- /dev/null +++ b/manifests/profile/base/neutron/plugins/nsx_v3.pp @@ -0,0 +1,45 @@ +# Copyright 2017 VMware, 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::profile::base::neutron::plugins::nsx_v3 +# +# VMware NSXv3 Neutron profile for tripleo +# +# === Parameters +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('bootstrap_nodeid') +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +class tripleo::profile::base::neutron::plugins::nsx_v3 ( + $bootstrap_node = hiera('bootstrap_nodeid', undef), + $step = hiera('step'), +) { + if $::hostname == downcase($bootstrap_node) { + $sync_db = true + } else { + $sync_db = false + } + + include ::tripleo::profile::base::neutron + + if $step >= 4 or ( $step >= 3 and $sync_db ) { + include ::neutron::plugins::nsx_v3 + } +} diff --git a/manifests/profile/base/nova.pp b/manifests/profile/base/nova.pp index ab9b615..d786940 100644 --- a/manifests/profile/base/nova.pp +++ b/manifests/profile/base/nova.pp @@ -87,29 +87,35 @@ # Expects a hash with keys 'private_key' and 'public_key'. # Defaults to {} # +# [*migration_ssh_localaddrs*] +# (Optional) Restrict ssh migration to clients connecting via this list of +# IPs. +# Defaults to [] (no restriction) +# # [*libvirt_tls*] # (Optional) Whether or not libvird TLS service is enabled. # Defaults to false class tripleo::profile::base::nova ( - $bootstrap_node = hiera('bootstrap_nodeid', undef), - $libvirt_enabled = false, - $manage_migration = false, - $oslomsg_rpc_proto = hiera('messaging_rpc_service_name', 'rabbit'), - $oslomsg_rpc_hosts = any2array(hiera('rabbitmq_node_names', undef)), - $oslomsg_rpc_password = hiera('nova::rabbit_password'), - $oslomsg_rpc_port = hiera('nova::rabbit_port', '5672'), - $oslomsg_rpc_username = hiera('nova::rabbit_userid', 'guest'), - $oslomsg_notify_proto = hiera('messaging_notify_service_name', 'rabbit'), - $oslomsg_notify_hosts = any2array(hiera('rabbitmq_node_names', undef)), - $oslomsg_notify_password = hiera('nova::rabbit_password'), - $oslomsg_notify_port = hiera('nova::rabbit_port', '5672'), - $oslomsg_notify_username = hiera('nova::rabbit_userid', 'guest'), - $oslomsg_use_ssl = hiera('nova::rabbit_use_ssl', '0'), - $nova_compute_enabled = false, - $step = hiera('step'), - $migration_ssh_key = {}, - $libvirt_tls = false + $bootstrap_node = hiera('bootstrap_nodeid', undef), + $libvirt_enabled = false, + $manage_migration = false, + $oslomsg_rpc_proto = hiera('messaging_rpc_service_name', 'rabbit'), + $oslomsg_rpc_hosts = any2array(hiera('rabbitmq_node_names', undef)), + $oslomsg_rpc_password = hiera('nova::rabbit_password'), + $oslomsg_rpc_port = hiera('nova::rabbit_port', '5672'), + $oslomsg_rpc_username = hiera('nova::rabbit_userid', 'guest'), + $oslomsg_notify_proto = hiera('messaging_notify_service_name', 'rabbit'), + $oslomsg_notify_hosts = any2array(hiera('rabbitmq_node_names', undef)), + $oslomsg_notify_password = hiera('nova::rabbit_password'), + $oslomsg_notify_port = hiera('nova::rabbit_port', '5672'), + $oslomsg_notify_username = hiera('nova::rabbit_userid', 'guest'), + $oslomsg_use_ssl = hiera('nova::rabbit_use_ssl', '0'), + $nova_compute_enabled = false, + $step = hiera('step'), + $migration_ssh_key = {}, + $migration_ssh_localaddrs = [], + $libvirt_tls = false ) { if $::hostname == downcase($bootstrap_node) { $sync_db = true @@ -123,6 +129,10 @@ class tripleo::profile::base::nova ( $memcache_servers = suffix(hiera('memcached_node_ips'), ':11211') } + validate_array($migration_ssh_localaddrs) + $migration_ssh_localaddrs.each |$x| { validate_ip_address($x) } + $migration_ssh_localaddrs_real = unique($migration_ssh_localaddrs) + if $step >= 4 or ($step >= 3 and $sync_db) { $oslomsg_use_ssl_real = sprintf('%s', bool2num(str2bool($oslomsg_use_ssl))) include ::nova::config @@ -131,10 +141,29 @@ class tripleo::profile::base::nova ( backend => 'oslo_cache.memcache_pool', memcache_servers => $memcache_servers, } + class { '::nova': + default_transport_url => os_transport_url({ + 'transport' => $oslomsg_rpc_proto, + 'hosts' => $oslomsg_rpc_hosts, + 'port' => $oslomsg_rpc_port, + 'username' => $oslomsg_rpc_username, + 'password' => $oslomsg_rpc_password, + 'ssl' => $oslomsg_use_ssl_real, + }), + notification_transport_url => os_transport_url({ + 'transport' => $oslomsg_notify_proto, + 'hosts' => $oslomsg_notify_hosts, + 'port' => $oslomsg_notify_port, + 'username' => $oslomsg_notify_username, + 'password' => $oslomsg_notify_password, + 'ssl' => $oslomsg_use_ssl_real, + }), + } include ::nova::placement + } - if $step >= 4 and $manage_migration { - + if $step >= 4 { + if $manage_migration { # Libvirt setup (live-migration) if $libvirt_tls { class { '::nova::migration::libvirt': @@ -148,57 +177,86 @@ class tripleo::profile::base::nova ( transport => 'ssh', configure_libvirt => $libvirt_enabled, configure_nova => $nova_compute_enabled, - client_user => 'nova', - client_extraparams => {'keyfile' => '/var/lib/nova/.ssh/id_rsa'} + client_user => 'nova_migration', + client_extraparams => {'keyfile' => '/etc/nova/migration/identity'} } } - if $migration_ssh_key != {} { + $services_enabled = hiera('service_names', []) + if !empty($migration_ssh_key) and 'sshd' in $services_enabled { # Nova SSH tunnel setup (cold-migration) - #TODO: Remove me when https://review.rdoproject.org/r/#/c/4008 lands - user { 'nova': - ensure => present, - shell => '/bin/bash', - } + # Server side + if !empty($migration_ssh_localaddrs_real) { + $allow_type = sprintf('LocalAddress %s User', join($migration_ssh_localaddrs_real,',')) + $deny_type = 'LocalAddress' + $deny_name = sprintf('!%s', join($migration_ssh_localaddrs_real,',!')) - $private_key_parts = split($migration_ssh_key['public_key'], ' ') - $nova_public_key = { - type => $private_key_parts[0], - key => $private_key_parts[1] + ssh::server::match_block { 'nova_migration deny': + name => $deny_name, + type => $deny_type, + order => 2, + options => { + 'DenyUsers' => 'nova_migration' + }, + notify => Service['sshd'] + } } - $nova_private_key = { - type => $private_key_parts[0], - key => $migration_ssh_key['private_key'] + else { + $allow_type = 'User' } - } else { - $nova_public_key = undef - $nova_private_key = undef + $allow_name = 'nova_migration' + + ssh::server::match_block { 'nova_migration allow': + name => $allow_name, + type => $allow_type, + order => 1, + options => { + 'ForceCommand' => '/bin/nova-migration-wrapper', + 'PasswordAuthentication' => 'no', + 'AllowTcpForwarding' => 'no', + 'X11Forwarding' => 'no', + 'AuthorizedKeysFile' => '/etc/nova/migration/authorized_keys' + }, + notify => Service['sshd'] + } + + $migration_authorized_keys = $migration_ssh_key['public_key'] + $migration_identity = $migration_ssh_key['private_key'] + $migration_user_shell = '/bin/bash' + } + else { + # Remove the keys and prevent login when migration over SSH is not enabled + $migration_authorized_keys = '# Migration over SSH disabled by TripleO' + $migration_identity = '# Migration over SSH disabled by TripleO' + $migration_user_shell = '/sbin/nologin' } - } else { - $nova_public_key = undef - $nova_private_key = undef - } - class { '::nova': - default_transport_url => os_transport_url({ - 'transport' => $oslomsg_rpc_proto, - 'hosts' => $oslomsg_rpc_hosts, - 'port' => $oslomsg_rpc_port, - 'username' => $oslomsg_rpc_username, - 'password' => $oslomsg_rpc_password, - 'ssl' => $oslomsg_use_ssl_real, - }), - notification_transport_url => os_transport_url({ - 'transport' => $oslomsg_notify_proto, - 'hosts' => $oslomsg_notify_hosts, - 'port' => $oslomsg_notify_port, - 'username' => $oslomsg_notify_username, - 'password' => $oslomsg_notify_password, - 'ssl' => $oslomsg_use_ssl_real, - }), - nova_public_key => $nova_public_key, - nova_private_key => $nova_private_key, + package { 'openstack-nova-migration': + ensure => present, + tag => ['openstack', 'nova-package'], + } + + file { '/etc/nova/migration/authorized_keys': + content => $migration_authorized_keys, + mode => '0640', + owner => 'root', + group => 'nova_migration', + require => Package['openstack-nova-migration'] + } + + file { '/etc/nova/migration/identity': + content => $migration_identity, + mode => '0600', + owner => 'nova', + group => 'nova', + require => Package['openstack-nova-migration'] + } + + user {'nova_migration': + shell => $migration_user_shell, + require => Package['openstack-nova-migration'] + } } } } diff --git a/manifests/profile/base/nova/api.pp b/manifests/profile/base/nova/api.pp index 95a1721..bdb3007 100644 --- a/manifests/profile/base/nova/api.pp +++ b/manifests/profile/base/nova/api.pp @@ -94,6 +94,7 @@ class tripleo::profile::base::nova::api ( $tls_keyfile = undef } if $step >= 4 or ($step >= 3 and $sync_db) { + include ::apache::mod::ssl class { '::nova::wsgi::apache_api': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/nova/placement.pp b/manifests/profile/base/nova/placement.pp index 16bfe17..c78b3c2 100644 --- a/manifests/profile/base/nova/placement.pp +++ b/manifests/profile/base/nova/placement.pp @@ -74,6 +74,7 @@ class tripleo::profile::base::nova::placement ( } if $step >= 3 { + include ::apache::mod::ssl class { '::nova::wsgi::apache_placement': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/pacemaker.pp b/manifests/profile/base/pacemaker.pp index c1d745a..811b911 100644 --- a/manifests/profile/base/pacemaker.pp +++ b/manifests/profile/base/pacemaker.pp @@ -136,6 +136,7 @@ class tripleo::profile::base::pacemaker ( remote_address => $remotes_hash[$title], reconnect_interval => $remote_reconnect_interval, op_params => "monitor interval=${remote_monitor_interval}", + verify_on_create => true, tries => $remote_tries, try_sleep => $remote_try_sleep, } diff --git a/manifests/profile/base/pacemaker_remote.pp b/manifests/profile/base/pacemaker_remote.pp index e0fff63..dfe0a3e 100644 --- a/manifests/profile/base/pacemaker_remote.pp +++ b/manifests/profile/base/pacemaker_remote.pp @@ -22,6 +22,14 @@ # Authkey for pacemaker remote nodes # Defaults to unset # +# [*pcs_tries*] +# (Optional) The number of times pcs commands should be retried. +# Defaults to hiera('pcs_tries', 20) +# +# [*enable_fencing*] +# (Optional) Whether or not to manage stonith devices for nodes +# Defaults to hiera('enable_fencing', false) +# # [*step*] # (Optional) The current step in deployment. See tripleo-heat-templates # for more details. @@ -29,9 +37,28 @@ # class tripleo::profile::base::pacemaker_remote ( $remote_authkey, + $pcs_tries = hiera('pcs_tries', 20), + $enable_fencing = hiera('enable_fencing', false), $step = hiera('step'), ) { class { '::pacemaker::remote': remote_authkey => $remote_authkey, } + $enable_fencing_real = str2bool($enable_fencing) and $step >= 5 + + class { '::pacemaker::stonith': + disable => !$enable_fencing_real, + tries => $pcs_tries, + } + + if $enable_fencing_real { + include ::tripleo::fencing + + # enable stonith after all Pacemaker resources have been created + Pcmk_resource<||> -> Class['tripleo::fencing'] + Pcmk_constraint<||> -> Class['tripleo::fencing'] + Exec <| tag == 'pacemaker_constraint' |> -> Class['tripleo::fencing'] + # enable stonith after all fencing devices have been created + Class['tripleo::fencing'] -> Class['pacemaker::stonith'] + } } diff --git a/manifests/profile/base/panko/api.pp b/manifests/profile/base/panko/api.pp index 90e80a2..165969f 100644 --- a/manifests/profile/base/panko/api.pp +++ b/manifests/profile/base/panko/api.pp @@ -79,6 +79,7 @@ class tripleo::profile::base::panko::api ( class { '::panko::api': sync_db => $sync_db, } + include ::apache::mod::ssl class { '::panko::wsgi::apache': ssl_cert => $tls_certfile, ssl_key => $tls_keyfile, diff --git a/manifests/profile/base/snmp.pp b/manifests/profile/base/snmp.pp index 301ac9a..d12e34d 100644 --- a/manifests/profile/base/snmp.pp +++ b/manifests/profile/base/snmp.pp @@ -42,7 +42,6 @@ class tripleo::profile::base::snmp ( authpass => $snmpd_password, } class { '::snmp': - agentaddress => ['udp:161','udp6:[::1]:161'], snmpd_config => [ join(['createUser ', $snmpd_user, ' MD5 "', $snmpd_password, '"']), join(['rouser ', $snmpd_user]), 'proc cron', diff --git a/manifests/profile/base/sshd.pp b/manifests/profile/base/sshd.pp index 2b86032..3f0245d 100644 --- a/manifests/profile/base/sshd.pp +++ b/manifests/profile/base/sshd.pp @@ -27,14 +27,19 @@ # The text used within SSH Banner # Defaults to hiera('MOTD') # +# [*options*] +# Hash of SSHD options to set. See the puppet-ssh module documentation for +# details. +# Defaults to {} + class tripleo::profile::base::sshd ( $bannertext = hiera('BannerText', undef), $motd = hiera('MOTD', undef), + $options = {} ) { - include ::ssh::server - - if $bannertext { + if $bannertext and $bannertext != '' { + $sshd_options_banner = {'Banner' => '/etc/issue.net'} $filelist = [ '/etc/issue', '/etc/issue.net', ] file { $filelist: ensure => file, @@ -44,9 +49,12 @@ class tripleo::profile::base::sshd ( group => 'root', mode => '0644' } + } else { + $sshd_options_banner = {} } - if $motd { + if $motd and $motd != '' { + $sshd_options_motd = {'PrintMotd' => 'yes'} file { '/etc/motd': ensure => file, backup => false, @@ -55,5 +63,23 @@ class tripleo::profile::base::sshd ( group => 'root', mode => '0644' } + } else { + $sshd_options_motd = {} + } + + $sshd_options = merge( + $options, + $sshd_options_banner, + $sshd_options_motd + ) + + # NB (owalsh) in puppet-ssh hiera takes precedence over the class param + # we need to control this, so error if it's set in hiera + if hiera('ssh:server::options', undef) { + err('ssh:server::options must not be set, use tripleo::profile::base::sshd::options') + } + class { '::ssh::server': + storeconfigs_enabled => false, + options => $sshd_options } } diff --git a/manifests/profile/base/swift/proxy.pp b/manifests/profile/base/swift/proxy.pp index e80c8c9..4e0e568 100644 --- a/manifests/profile/base/swift/proxy.pp +++ b/manifests/profile/base/swift/proxy.pp @@ -127,7 +127,7 @@ class tripleo::profile::base::swift::proxy ( port => $tls_proxy_port, tls_cert => $tls_certfile, tls_key => $tls_keyfile, - notify => Class['::neutron::server'], + notify => Class['::swift::proxy'], } } $swift_memcache_servers = suffix(any2array(normalize_ip_for_uri($memcache_servers)), ":${memcache_port}") diff --git a/manifests/profile/base/zaqar.pp b/manifests/profile/base/zaqar.pp index 89a03ad..243dcc7 100644 --- a/manifests/profile/base/zaqar.pp +++ b/manifests/profile/base/zaqar.pp @@ -50,11 +50,15 @@ class tripleo::profile::base::zaqar ( uri => $database_connection, } include ::zaqar::transport::websocket + include ::apache::mod::ssl include ::zaqar::transport::wsgi # TODO (bcrochet): At some point, the transports should be split out to - # seperate services. - include ::zaqar::server + # separate services. + class { '::zaqar::server': + service_name => 'httpd', # TODO cleanup when passed by t-h-t. + } + include ::zaqar::wsgi::apache zaqar::server_instance{ '1': transport => 'websocket' } diff --git a/manifests/profile/pacemaker/database/mysql_bundle.pp b/manifests/profile/pacemaker/database/mysql_bundle.pp new file mode 100644 index 0000000..451d7f7 --- /dev/null +++ b/manifests/profile/pacemaker/database/mysql_bundle.pp @@ -0,0 +1,302 @@ +# 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::profile::pacemaker::mysql_bundle +# +# Containerized Mysql Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*mysql_docker_image*] +# (Optional) The docker image to use for creating the pacemaker bundle +# Defaults to hiera('tripleo::profile::pacemaker::database::redis_bundle::mysql_docker_image', undef) +# +# [*control_port*] +# (Optional) The bundle's pacemaker_remote control port on the host +# Defaults to hiera('tripleo::profile::pacemaker::database::redis_bundle::control_port', '3123') +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('mysql_short_bootstrap_node_name') +# +# [*bind_address*] +# (Optional) The address that the local mysql instance should bind to. +# Defaults to $::hostname +# +# [*gmcast_listen_addr*] +# (Optional) This variable defines the address on which the node listens to +# connections from other nodes in the cluster. +# Defaults to hiera('mysql_bind_host') +# +# [*pcs_tries*] +# (Optional) The number of times pcs commands should be retried. +# Defaults to hiera('pcs_tries', 20) +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# +class tripleo::profile::pacemaker::database::mysql_bundle ( + $mysql_docker_image = hiera('tripleo::profile::pacemaker::database::mysql_bundle::mysql_docker_image', undef), + $control_port = hiera('tripleo::profile::pacemaker::database::mysql_bundle::control_port', '3123'), + $bootstrap_node = hiera('mysql_short_bootstrap_node_name'), + $bind_address = $::hostname, + $gmcast_listen_addr = hiera('mysql_bind_host'), + $pcs_tries = hiera('pcs_tries', 20), + $step = hiera('step'), +) { + if $::hostname == downcase($bootstrap_node) { + $pacemaker_master = true + } else { + $pacemaker_master = false + } + + # use only mysql_node_names when we land a patch in t-h-t that + # switches to autogenerating these values from composable services + # The galera node names need to match the pacemaker node names... so if we + # want to use FQDNs for this, the cluster will not finish bootstrapping, + # since all the nodes will be marked as slaves. For now, we'll stick to the + # short name which is already registered in pacemaker until we get around + # this issue. + $galera_node_names_lookup = hiera('mysql_short_node_names', hiera('mysql_node_names', $::hostname)) + if is_array($galera_node_names_lookup) { + $galera_nodes = downcase(join($galera_node_names_lookup, ',')) + } else { + $galera_nodes = downcase($galera_node_names_lookup) + } + $galera_nodes_array = split($galera_nodes, ',') + $galera_nodes_count = count($galera_nodes_array) + + # construct a galera-pacemaker name mapping for the resource agent + # [galera-bundle-0:galera_node[0], galera-bundle-1:galera_node[1], ... ,galera-bundle-n:galera_node[n]] + $host_map_array = $galera_nodes_array.map |$i, $host| { + "galera-bundle-${i}:${host}" + } + $cluster_host_map_string = join($host_map_array, ';') + + $mysqld_options = { + 'mysqld' => { + 'pid-file' => '/var/lib/mysql/mariadb.pid', + 'skip-name-resolve' => '1', + 'binlog_format' => 'ROW', + 'default-storage-engine' => 'innodb', + 'innodb_autoinc_lock_mode' => '2', + 'innodb_locks_unsafe_for_binlog'=> '1', + 'innodb_file_per_table' => 'ON', + 'query_cache_size' => '0', + 'query_cache_type' => '0', + 'bind-address' => $bind_address, + 'max_connections' => hiera('mysql_max_connections'), + 'open_files_limit' => '-1', + 'wsrep_on' => 'ON', + 'wsrep_provider' => '/usr/lib64/galera/libgalera_smm.so', + 'wsrep_cluster_name' => 'galera_cluster', + 'wsrep_cluster_address' => "gcomm://${galera_nodes}", + 'wsrep_slave_threads' => '1', + 'wsrep_certify_nonPK' => '1', + 'wsrep_max_ws_rows' => '131072', + 'wsrep_max_ws_size' => '1073741824', + 'wsrep_debug' => '0', + 'wsrep_convert_LOCK_to_trx' => '0', + 'wsrep_retry_autocommit' => '1', + 'wsrep_auto_increment_control' => '1', + 'wsrep_drupal_282555_workaround'=> '0', + 'wsrep_causal_reads' => '0', + 'wsrep_sst_method' => 'rsync', + 'wsrep_provider_options' => "gmcast.listen_addr=tcp://${gmcast_listen_addr}:4567;", + }, + 'mysqld_safe' => { + 'pid-file' => '/var/lib/mysql/mariadb.pid', + } + } + + # remove_default_accounts parameter will execute some mysql commands + # to remove the default accounts created by MySQL package. + # We need MySQL running to run the commands successfully, so better to + # wait step 2 before trying to run the commands. + if $step >= 2 and $pacemaker_master { + $remove_default_accounts = true + } else { + $remove_default_accounts = false + } + + if $step >= 1 and $pacemaker_master and hiera('stack_action') == 'UPDATE' { + tripleo::pacemaker::resource_restart_flag { 'galera-master': + subscribe => File['mysql-config-file'], + } + } + + $mysql_root_password = hiera('mysql::server::root_password') + + if $step >= 1 { + # Kolla sets the root password, expose it to the MySQL package + # so that it can initialize the database (e.g. create users) + file { '/root/.my.cnf' : + ensure => file, + mode => '0600', + owner => 'root', + group => 'root', + content => "[client] +user=root +password=\"${mysql_root_password}\" + +[mysql] +user=root +password=\"${mysql_root_password}\"", + } + + # Resource agent uses those credentials to poll galera state + file { '/etc/sysconfig/clustercheck' : + ensure => file, + mode => '0600', + owner => 'root', + group => 'root', + content => "MYSQL_USERNAME=root\n +MYSQL_PASSWORD='${mysql_root_password}'\n +MYSQL_HOST=localhost\n", + } + } + + if $step >= 2 { + # need that class to create all openstack credentials + # we don't include it in step 1 because the kolla bootstrap + # happens after step 1 baremetal + class { '::tripleo::profile::base::database::mysql': + bootstrap_node => $bootstrap_node, + manage_resources => false, + remove_default_accounts => $remove_default_accounts, + mysql_server_options => $mysqld_options, + } + + if $pacemaker_master { + $mysql_short_node_names = hiera('mysql_short_node_names') + $mysql_short_node_names.each |String $node_name| { + # lint:ignore:puppet-lint-2.0.1 does not work with multiline strings + # and blocks (remove this when we move to 2.2.0 where this works) + pacemaker::property { "galera-role-${node_name}": + property => 'galera-role', + value => true, + tries => $pcs_tries, + node => $node_name, + before => Pacemaker::Resource::Bundle['galera-bundle'], + } + # lint:endignore + } + pacemaker::resource::bundle { 'galera-bundle': + image => $mysql_docker_image, + replicas => $galera_nodes_count, + masters => $galera_nodes_count, + container_options => 'network=host', + options => '--user=root --log-driver=journald -e KOLLA_CONFIG_STRATEGY=COPY_ALWAYS', + run_command => '/bin/bash /usr/local/bin/kolla_start', + network => "control-port=${control_port}", + storage_maps => { + 'mysql-cfg-files' => { + 'source-dir' => '/var/lib/kolla/config_files/mysql.json', + 'target-dir' => '/var/lib/kolla/config_files/config.json', + 'options' => 'ro', + }, + 'mysql-cfg-data' => { + 'source-dir' => '/var/lib/config-data/mysql', + 'target-dir' => '/var/lib/kolla/config_files/src', + 'options' => 'ro', + }, + 'mysql-hosts' => { + 'source-dir' => '/etc/hosts', + 'target-dir' => '/etc/hosts', + 'options' => 'ro', + }, + 'mysql-localtime' => { + 'source-dir' => '/etc/localtime', + 'target-dir' => '/etc/localtime', + 'options' => 'ro', + }, + 'mysql-lib' => { + 'source-dir' => '/var/lib/mysql', + 'target-dir' => '/var/lib/mysql', + 'options' => 'rw', + }, + 'mysql-log-mariadb' => { + 'source-dir' => '/var/log/mariadb', + 'target-dir' => '/var/log/mariadb', + 'options' => 'rw', + }, + 'mysql-pki-extracted' => { + 'source-dir' => '/etc/pki/ca-trust/extracted', + 'target-dir' => '/etc/pki/ca-trust/extracted', + 'options' => 'ro', + }, + 'mysql-pki-ca-bundle-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'options' => 'ro', + }, + 'mysql-pki-ca-bundle-trust-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'options' => 'ro', + }, + 'mysql-pki-cert' => { + 'source-dir' => '/etc/pki/tls/cert.pem', + 'target-dir' => '/etc/pki/tls/cert.pem', + 'options' => 'ro', + }, + 'mysql-dev-log' => { + 'source-dir' => '/dev/log', + 'target-dir' => '/dev/log', + 'options' => 'rw', + }, + }, + } + + pacemaker::resource::ocf { 'galera': + ocf_agent_name => 'heartbeat:galera', + master_params => '', + meta_params => "master-max=${galera_nodes_count} ordered=true", + op_params => 'promote timeout=300s on-fail=block', + resource_params => "additional_parameters='--open-files-limit=16384' enable_creation=true wsrep_cluster_address='gcomm://${galera_nodes}' cluster_host_map='${cluster_host_map_string}'", + tries => $pcs_tries, + location_rule => { + resource_discovery => 'exclusive', + score => 0, + expression => ['galera-role eq true'], + }, + bundle => 'galera-bundle', + require => [Class['::mysql::server'], + Pacemaker::Resource::Bundle['galera-bundle']], + before => Exec['galera-ready'], + } + + exec { 'galera-ready' : + command => '/usr/bin/clustercheck >/dev/null', + timeout => 30, + tries => 180, + try_sleep => 10, + environment => ['AVAILABLE_WHEN_READONLY=0'], + tag => 'galera_ready' + } + + # We create databases and users for services at step 2 as well. This ensures + # Galera is up and ready before those get created + File['/root/.my.cnf'] -> Mysql_database<||> + File['/root/.my.cnf'] -> Mysql_user<||> + File['/etc/sysconfig/clustercheck'] -> Mysql_database<||> + File['/etc/sysconfig/clustercheck'] -> Mysql_user<||> + Exec['galera-ready'] -> Mysql_database<||> + Exec['galera-ready'] -> Mysql_user<||> + } + } +} diff --git a/manifests/profile/pacemaker/database/redis.pp b/manifests/profile/pacemaker/database/redis.pp index 3ef6815..4f5a861 100644 --- a/manifests/profile/pacemaker/database/redis.pp +++ b/manifests/profile/pacemaker/database/redis.pp @@ -32,9 +32,12 @@ # Defaults to hiera('step') # # [*redis_file_limit*] -# (Optional) The file limit to put in /etc/security/limits.d/redis.conf +# (Deprecated) The file limit to put in /etc/security/limits.d/redis.conf # for when redis is managed by pacemaker. Defaults to hiera('redis_file_limit') -# or 10240 (default in redis systemd limits) +# or 10240 (default in redis systemd limits). Note this option is deprecated +# since puppet-redis grew support for ulimits in cluster configurations. +# https://github.com/arioch/puppet-redis/pull/192. Set redis::ulimit via hiera +# to control this limit. # # [*pcs_tries*] # (Optional) The number of times pcs commands should be retried. @@ -44,7 +47,7 @@ class tripleo::profile::pacemaker::database::redis ( $bootstrap_node = hiera('redis_short_bootstrap_node_name'), $enable_load_balancer = hiera('enable_load_balancer', true), $step = hiera('step'), - $redis_file_limit = hiera('redis_file_limit', 10240), + $redis_file_limit = undef, $pcs_tries = hiera('pcs_tries', 20), ) { if $::hostname == downcase($bootstrap_node) { @@ -54,19 +57,17 @@ class tripleo::profile::pacemaker::database::redis ( } if $step >= 1 { - include ::redis - # Until puppet-redis grows support for /etc/security/limits.conf/redis.conf - # https://github.com/arioch/puppet-redis/issues/130 - # we best explicitely set the file limit only in the pacemaker profile - # (the base profile does not need it as it is using systemd which has - # the limits set there) - file { '/etc/security/limits.d/redis.conf': - content => inline_template("redis soft nofile <%= @redis_file_limit %>\nredis hard nofile <%= @redis_file_limit %>\n"), - owner => '0', - group => '0', - mode => '0644', + # If the old hiera key exists we use that to set the ulimit in order not to break + # operators which set it. We might remove this in a later release (post pike anyway) + $old_redis_file_limit = hiera('redis_file_limit', undef) + if $old_redis_file_limit != undef { + warning('redis_file_limit parameter is deprecated, use redis::ulimit in hiera.') + class { '::redis': + ulimit => $old_redis_file_limit, + } + } else { + include ::redis } - if $pacemaker_master and hiera('stack_action') == 'UPDATE' { tripleo::pacemaker::resource_restart_flag { 'redis-master': # ouch, but trying to stay close how notification works in diff --git a/manifests/profile/pacemaker/database/redis_bundle.pp b/manifests/profile/pacemaker/database/redis_bundle.pp new file mode 100644 index 0000000..167e54a --- /dev/null +++ b/manifests/profile/pacemaker/database/redis_bundle.pp @@ -0,0 +1,178 @@ +# 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::profile::pacemaker::database::redis_bundle +# +# Containerized Redis Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*redis_docker_image*] +# (Optional) The docker image to use for creating the pacemaker bundle +# Defaults to hiera('tripleo::profile::pacemaker::redis_bundle::redis_docker_image', undef) +# +# [*redis_docker_control_port*] +# (Optional) The bundle's pacemaker_remote control port on the host +# Defaults to hiera('tripleo::profile::pacemaker::redis_bundle::control_port', '3121') +# +# [*pcs_tries*] +# (Optional) The number of times pcs commands should be retried. +# Defaults to hiera('pcs_tries', 20) +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('redis_short_bootstrap_node_name') +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# +class tripleo::profile::pacemaker::database::redis_bundle ( + $bootstrap_node = hiera('redis_short_bootstrap_node_name'), + $redis_docker_image = hiera('tripleo::profile::pacemaker::database::redis_bundle::redis_docker_image', undef), + $redis_docker_control_port = hiera('tripleo::profile::pacemaker::database::redis_bundle::control_port', '3124'), + $pcs_tries = hiera('pcs_tries', 20), + $step = hiera('step'), +) { + if $::hostname == downcase($bootstrap_node) { + $pacemaker_master = true + } else { + $pacemaker_master = false + } + + include ::tripleo::profile::base::database::redis + + if $step >= 2 { + if $pacemaker_master { + $redis_short_node_names = hiera('redis_short_node_names') + $redis_nodes_count = count($redis_short_node_names) + $redis_short_node_names.each |String $node_name| { + pacemaker::property { "redis-role-${node_name}": + property => 'redis-role', + value => true, + tries => $pcs_tries, + node => $node_name, + before => Pacemaker::Resource::Bundle['redis-bundle'], + } + } + + pacemaker::resource::bundle { 'redis-bundle': + image => $redis_docker_image, + replicas => $redis_nodes_count, + masters => 1, + container_options => 'network=host', + options => '--user=root --log-driver=journald -e KOLLA_CONFIG_STRATEGY=COPY_ALWAYS', + run_command => '/bin/bash /usr/local/bin/kolla_start', + network => "control-port=${redis_docker_control_port}", + storage_maps => { + 'redis-cfg-files' => { + 'source-dir' => '/var/lib/kolla/config_files/redis.json', + 'target-dir' => '/var/lib/kolla/config_files/config.json', + 'options' => 'ro', + }, + 'redis-cfg-data-redis' => { + 'source-dir' => '/var/lib/config-data/redis/etc/redis', + 'target-dir' => '/etc/redis', + 'options' => 'ro', + }, + 'redis-cfg-data-redis-conf' => { + 'source-dir' => '/var/lib/config-data/redis/etc/redis.conf', + 'target-dir' => '/etc/redis.conf', + 'options' => 'ro', + }, + 'redis-cfg-data-redis-conf-puppet' => { + 'source-dir' => '/var/lib/config-data/redis/etc/redis.conf.puppet', + 'target-dir' => '/etc/redis.conf.puppet', + 'options' => 'ro', + }, + 'redis-cfg-data-redis-sentinel' => { + 'source-dir' => '/var/lib/config-data/redis/etc/redis-sentinel.conf', + 'target-dir' => '/etc/redis-sentinel.conf', + 'options' => 'ro', + }, + 'redis-hosts' => { + 'source-dir' => '/etc/hosts', + 'target-dir' => '/etc/hosts', + 'options' => 'ro', + }, + 'redis-localtime' => { + 'source-dir' => '/etc/localtime', + 'target-dir' => '/etc/localtime', + 'options' => 'ro', + }, + 'redis-lib' => { + 'source-dir' => '/var/lib/redis', + 'target-dir' => '/var/lib/redis', + 'options' => 'rw', + }, + 'redis-log' => { + 'source-dir' => '/var/log/redis', + 'target-dir' => '/var/log/redis', + 'options' => 'rw', + }, + 'redis-run' => { + 'source-dir' => '/var/run/redis', + 'target-dir' => '/var/run/redis', + 'options' => 'rw', + }, + 'redis-pki-extracted' => { + 'source-dir' => '/etc/pki/ca-trust/extracted', + 'target-dir' => '/etc/pki/ca-trust/extracted', + 'options' => 'ro', + }, + 'redis-pki-ca-bundle-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'options' => 'ro', + }, + 'redis-pki-ca-bundle-trust-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'options' => 'ro', + }, + 'redis-pki-cert' => { + 'source-dir' => '/etc/pki/tls/cert.pem', + 'target-dir' => '/etc/pki/tls/cert.pem', + 'options' => 'ro', + }, + 'redis-dev-log' => { + 'source-dir' => '/dev/log', + 'target-dir' => '/dev/log', + 'options' => 'rw', + }, + }, + } + + pacemaker::resource::ocf { 'redis': + ocf_agent_name => 'heartbeat:redis', + resource_params => 'wait_last_known_master=true', + master_params => '', + meta_params => 'notify=true ordered=true interleave=true', + op_params => 'start timeout=200s stop timeout=200s', + tries => $pcs_tries, + location_rule => { + resource_discovery => 'exclusive', + score => 0, + expression => ['redis-role eq true'], + }, + bundle => 'redis-bundle', + require => [Class['::redis'], + Pacemaker::Resource::Bundle['redis-bundle']], + } + + } + } +} diff --git a/manifests/profile/pacemaker/haproxy_bundle.pp b/manifests/profile/pacemaker/haproxy_bundle.pp new file mode 100644 index 0000000..3e7b7dd --- /dev/null +++ b/manifests/profile/pacemaker/haproxy_bundle.pp @@ -0,0 +1,196 @@ +# Copyright 2016 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::profile::pacemaker::haproxy +# +# HAproxy with Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*haproxy_docker_image*] +# (Optional) The docker image to use for creating the pacemaker bundle +# Defaults to hiera('tripleo::profile::pacemaker::haproxy::haproxy_docker_image', undef) +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('haproxy_short_bootstrap_node_name') +# +# [*enable_load_balancer*] +# (Optional) Whether load balancing is enabled for this cluster +# Defaults to hiera('enable_load_balancer', true) +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# [*pcs_tries*] +# (Optional) The number of times pcs commands should be retried. +# Defaults to hiera('pcs_tries', 20) +# +class tripleo::profile::pacemaker::haproxy_bundle ( + $haproxy_docker_image = hiera('tripleo::profile::pacemaker::haproxy::haproxy_docker_image', undef), + $bootstrap_node = hiera('haproxy_short_bootstrap_node_name'), + $enable_load_balancer = hiera('enable_load_balancer', true), + $step = hiera('step'), + $pcs_tries = hiera('pcs_tries', 20), +) { + include ::tripleo::profile::base::haproxy + + if $::hostname == downcase($bootstrap_node) { + $pacemaker_master = true + } else { + $pacemaker_master = false + } + + if $step >= 1 and $pacemaker_master and hiera('stack_action') == 'UPDATE' and $enable_load_balancer { + tripleo::pacemaker::resource_restart_flag { 'haproxy-clone': + subscribe => Concat['/etc/haproxy/haproxy.cfg'], + } + } + + if $step >= 2 and $enable_load_balancer { + if $pacemaker_master { + $haproxy_short_node_names = hiera('haproxy_short_node_names') + $haproxy_short_node_names.each |String $node_name| { + pacemaker::property { "haproxy-role-${node_name}": + property => 'haproxy-role', + value => true, + tries => $pcs_tries, + node => $node_name, + before => Pacemaker::Resource::Bundle['haproxy-bundle'], + } + } + $haproxy_location_rule = { + resource_discovery => 'exclusive', + score => 0, + expression => ['haproxy-role eq true'], + } + # FIXME: we should not have to access tripleo::haproxy class + # parameters here to configure pacemaker VIPs. The configuration + # of pacemaker VIPs could move into puppet-tripleo or we should + # make use of less specific hiera parameters here for the settings. + $haproxy_nodes = hiera('haproxy_short_node_names') + $haproxy_nodes_count = count($haproxy_nodes) + + pacemaker::resource::bundle { 'haproxy-bundle': + image => $haproxy_docker_image, + replicas => $haproxy_nodes_count, + container_options => 'network=host', + options => '--user=root --log-driver=journald -e KOLLA_CONFIG_STRATEGY=COPY_ALWAYS', + run_command => '/bin/bash /usr/local/bin/kolla_start', + storage_maps => { + 'haproxy-cfg-files' => { + 'source-dir' => '/var/lib/kolla/config_files/haproxy.json', + 'target-dir' => '/var/lib/kolla/config_files/config.json', + 'options' => 'ro', + }, + 'haproxy-cfg-data' => { + 'source-dir' => '/var/lib/config-data/haproxy/etc', + 'target-dir' => '/etc', + 'options' => 'ro', + }, + 'haproxy-hosts' => { + 'source-dir' => '/etc/hosts', + 'target-dir' => '/etc/hosts', + 'options' => 'ro', + }, + 'haproxy-localtime' => { + 'source-dir' => '/etc/localtime', + 'target-dir' => '/etc/localtime', + 'options' => 'ro', + }, + 'haproxy-pki-extracted' => { + 'source-dir' => '/etc/pki/ca-trust/extracted', + 'target-dir' => '/etc/pki/ca-trust/extracted', + 'options' => 'ro', + }, + 'haproxy-pki-ca-bundle-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'options' => 'ro', + }, + 'haproxy-pki-ca-bundle-trust-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'options' => 'ro', + }, + 'haproxy-pki-cert' => { + 'source-dir' => '/etc/pki/tls/cert.pem', + 'target-dir' => '/etc/pki/tls/cert.pem', + 'options' => 'ro', + }, + 'haproxy-dev-log' => { + 'source-dir' => '/dev/log', + 'target-dir' => '/dev/log', + 'options' => 'rw', + }, + }, + } + $control_vip = hiera('controller_virtual_ip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_control_vip': + vip_name => 'control', + ip_address => $control_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + + $public_vip = hiera('public_virtual_ip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_public_vip': + ensure => $public_vip and $public_vip != $control_vip, + vip_name => 'public', + ip_address => $public_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + + $redis_vip = hiera('redis_vip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_redis_vip': + ensure => $redis_vip and $redis_vip != $control_vip, + vip_name => 'redis', + ip_address => $redis_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + + $internal_api_vip = hiera('internal_api_virtual_ip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_internal_api_vip': + ensure => $internal_api_vip and $internal_api_vip != $control_vip, + vip_name => 'internal_api', + ip_address => $internal_api_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + + $storage_vip = hiera('storage_virtual_ip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_storage_vip': + ensure => $storage_vip and $storage_vip != $control_vip, + vip_name => 'storage', + ip_address => $storage_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + + $storage_mgmt_vip = hiera('storage_mgmt_virtual_ip') + tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_storage_mgmt_vip': + ensure => $storage_mgmt_vip and $storage_mgmt_vip != $control_vip, + vip_name => 'storage_mgmt', + ip_address => $storage_mgmt_vip, + location_rule => $haproxy_location_rule, + pcs_tries => $pcs_tries, + } + } + } + +} diff --git a/manifests/profile/pacemaker/neutron/lbaas.pp b/manifests/profile/pacemaker/neutron/lbaas.pp new file mode 100644 index 0000000..96712d4 --- /dev/null +++ b/manifests/profile/pacemaker/neutron/lbaas.pp @@ -0,0 +1,44 @@ +# Copyright 2016 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::profile::pacemaker::neutron::lbaas +# +# Neutron LBaaS Agent Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# [*pacemaker_master*] +# (Optional) The hostname of the pacemaker master +# Defaults to hiera('bootstrap_nodeid') +# +class tripleo::profile::pacemaker::neutron::lbaas ( + $step = hiera('step'), + $pacemaker_master = hiera('bootstrap_nodeid'), +) { + + include ::neutron::params + include ::tripleo::profile::pacemaker::neutron + include ::tripleo::profile::base::neutron::lbaas + + if $step >= 5 and downcase($::hostname) == $pacemaker_master { + pacemaker::resource::service { $::neutron::params::lbaasv2_agent_service: + clone_params => 'interleave=true', + } + } +} diff --git a/manifests/profile/pacemaker/rabbitmq.pp b/manifests/profile/pacemaker/rabbitmq.pp index f4b679a..bf6a38d 100644 --- a/manifests/profile/pacemaker/rabbitmq.pp +++ b/manifests/profile/pacemaker/rabbitmq.pp @@ -30,7 +30,7 @@ # (Optional) The number of HA queues in to be configured in rabbitmq # Defaults to hiera('rabbitmq::nr_ha_queues'), which is usually 0 meaning # that the queues number will be CEIL(N/2) where N is the number of rabbitmq -# nodes. +# nodes. The special value of -1 represents the mode 'ha-mode: all' # # [*rabbit_nodes*] # (Optional) The list of rabbitmq nodes names @@ -90,12 +90,16 @@ class tripleo::profile::pacemaker::rabbitmq ( if $user_ha_queues == 0 { $nr_rabbit_nodes = size($rabbit_nodes) $nr_ha_queues = $nr_rabbit_nodes / 2 + ($nr_rabbit_nodes % 2) + $params = "set_policy='ha-all ^(?!amq\\.).* {\"ha-mode\":\"exactly\",\"ha-params\":${nr_ha_queues}}'" + } elsif $user_ha_queues == -1 { + $params = 'set_policy=\'ha-all ^(?!amq\.).* {"ha-mode":"all"}\'' } else { $nr_ha_queues = $user_ha_queues + $params = "set_policy='ha-all ^(?!amq\\.).* {\"ha-mode\":\"exactly\",\"ha-params\":${nr_ha_queues}}'" } pacemaker::resource::ocf { 'rabbitmq': ocf_agent_name => 'heartbeat:rabbitmq-cluster', - resource_params => "set_policy='ha-all ^(?!amq\\.).* {\"ha-mode\":\"exactly\",\"ha-params\":${nr_ha_queues}}'", + resource_params => $params, clone_params => 'ordered=true interleave=true', meta_params => 'notify=true', op_params => 'start timeout=200s stop timeout=200s', diff --git a/manifests/profile/pacemaker/rabbitmq_bundle.pp b/manifests/profile/pacemaker/rabbitmq_bundle.pp new file mode 100644 index 0000000..b05b0b1 --- /dev/null +++ b/manifests/profile/pacemaker/rabbitmq_bundle.pp @@ -0,0 +1,194 @@ +# 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::profile::pacemaker::rabbitmq_bundle +# +# Containerized RabbitMQ Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*rabbitmq_docker_image*] +# (Optional) The docker image to use for creating the pacemaker bundle +# Defaults to hiera('tripleo::profile::pacemaker::rabbitmq_bundle::rabbitmq_docker_image', undef) +# +# [*rabbitmq_docker_control_port*] +# (Optional) The bundle's pacemaker_remote control port on the host +# Defaults to hiera('tripleo::profile::pacemaker::rabbitmq_bundle::control_port', '3121') +# +# [*bootstrap_node*] +# (Optional) The hostname of the node responsible for bootstrapping tasks +# Defaults to hiera('rabbitmq_short_bootstrap_node_name') +# +# [*erlang_cookie*] +# (Optional) Content of erlang cookie. +# Defaults to hiera('rabbitmq::erlang_cookie'). +# +# [*user_ha_queues*] +# (Optional) The number of HA queues in to be configured in rabbitmq +# Defaults to hiera('rabbitmq::nr_ha_queues'), which is usually 0 meaning +# that the queues number will be CEIL(N/2) where N is the number of rabbitmq +# nodes. +# +# [*rabbit_nodes*] +# (Optional) The list of rabbitmq nodes names +# Defaults to hiera('rabbitmq_node_names') +# +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# [*pcs_tries*] +# (Optional) The number of times pcs commands should be retried. +# Defaults to hiera('pcs_tries', 20) +# +class tripleo::profile::pacemaker::rabbitmq_bundle ( + $rabbitmq_docker_image = hiera('tripleo::profile::pacemaker::rabbitmq_bundle::rabbitmq_docker_image', undef), + $rabbitmq_docker_control_port = hiera('tripleo::profile::pacemaker::rabbitmq_bundle::control_port', '3121'), + $bootstrap_node = hiera('rabbitmq_short_bootstrap_node_name'), + $erlang_cookie = hiera('rabbitmq::erlang_cookie'), + $user_ha_queues = hiera('rabbitmq::nr_ha_queues', 0), + $rabbit_nodes = hiera('rabbitmq_node_names'), + $pcs_tries = hiera('pcs_tries', 20), + $step = hiera('step'), +) { + if $::hostname == downcase($bootstrap_node) { + $pacemaker_master = true + } else { + $pacemaker_master = false + } + + include ::tripleo::profile::base::rabbitmq + + file { '/var/lib/rabbitmq/.erlang.cookie': + ensure => file, + owner => 'rabbitmq', + group => 'rabbitmq', + mode => '0400', + content => $erlang_cookie, + replace => true, + require => Class['::rabbitmq'], + } + + if $step >= 1 and $pacemaker_master and hiera('stack_action') == 'UPDATE' { + tripleo::pacemaker::resource_restart_flag { 'rabbitmq-clone': + subscribe => Class['rabbitmq::service'], + } + } + + + if $step >= 2 { + if $pacemaker_master { + $rabbitmq_short_node_names = hiera('rabbitmq_short_node_names') + $rabbitmq_nodes_count = count($rabbitmq_short_node_names) + $rabbitmq_short_node_names.each |String $node_name| { + pacemaker::property { "rabbitmq-role-${node_name}": + property => 'rabbitmq-role', + value => true, + tries => $pcs_tries, + node => $node_name, + before => Pacemaker::Resource::Bundle['rabbitmq-bundle'], + } + } + + pacemaker::resource::bundle { 'rabbitmq-bundle': + image => $rabbitmq_docker_image, + replicas => $rabbitmq_nodes_count, + container_options => 'network=host', + options => '--user=root --log-driver=journald -e KOLLA_CONFIG_STRATEGY=COPY_ALWAYS', + run_command => '/bin/bash /usr/local/bin/kolla_start', + network => "control-port=${rabbitmq_docker_control_port}", + storage_maps => { + 'rabbitmq-cfg-files' => { + 'source-dir' => '/var/lib/kolla/config_files/rabbitmq.json', + 'target-dir' => '/var/lib/kolla/config_files/config.json', + 'options' => 'ro', + }, + 'rabbitmq-cfg-data' => { + 'source-dir' => '/var/lib/config-data/rabbitmq/etc/rabbitmq', + 'target-dir' => '/etc/rabbitmq', + 'options' => 'ro', + }, + 'rabbitmq-hosts' => { + 'source-dir' => '/etc/hosts', + 'target-dir' => '/etc/hosts', + 'options' => 'ro', + }, + 'rabbitmq-localtime' => { + 'source-dir' => '/etc/localtime', + 'target-dir' => '/etc/localtime', + 'options' => 'ro', + }, + 'rabbitmq-lib' => { + 'source-dir' => '/var/lib/rabbitmq', + 'target-dir' => '/var/lib/rabbitmq', + 'options' => 'rw', + }, + 'rabbitmq-pki-extracted' => { + 'source-dir' => '/etc/pki/ca-trust/extracted', + 'target-dir' => '/etc/pki/ca-trust/extracted', + 'options' => 'ro', + }, + 'rabbitmq-pki-ca-bundle-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.crt', + 'options' => 'ro', + }, + 'rabbitmq-pki-ca-bundle-trust-crt' => { + 'source-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'target-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt', + 'options' => 'ro', + }, + 'rabbitmq-pki-cert' => { + 'source-dir' => '/etc/pki/tls/cert.pem', + 'target-dir' => '/etc/pki/tls/cert.pem', + 'options' => 'ro', + }, + 'rabbitmq-dev-log' => { + 'source-dir' => '/dev/log', + 'target-dir' => '/dev/log', + 'options' => 'rw', + }, + }, + } + + # The default nr of ha queues is ceiling(N/2) + if $user_ha_queues == 0 { + $nr_rabbit_nodes = size($rabbit_nodes) + $nr_ha_queues = $nr_rabbit_nodes / 2 + ($nr_rabbit_nodes % 2) + $params = "set_policy='ha-all ^(?!amq\\.).* {\"ha-mode\":\"exactly\",\"ha-params\":${nr_ha_queues}}'" + } elsif $user_ha_queues == -1 { + $params = 'set_policy=\'ha-all ^(?!amq\.).* {"ha-mode":"all"}\'' + } else { + $nr_ha_queues = $user_ha_queues + $params = "set_policy='ha-all ^(?!amq\\.).* {\"ha-mode\":\"exactly\",\"ha-params\":${nr_ha_queues}}'" + } + pacemaker::resource::ocf { 'rabbitmq': + ocf_agent_name => 'heartbeat:rabbitmq-cluster', + resource_params => $params, + meta_params => 'notify=true', + op_params => 'start timeout=200s stop timeout=200s', + tries => $pcs_tries, + location_rule => { + resource_discovery => 'exclusive', + score => 0, + expression => ['rabbitmq-role eq true'], + }, + bundle => 'rabbitmq-bundle', + require => [Class['::rabbitmq'], + Pacemaker::Resource::Bundle['rabbitmq-bundle']], + } + } + } +} diff --git a/manifests/tls_proxy.pp b/manifests/tls_proxy.pp index 36d6b6d..607e20f 100644 --- a/manifests/tls_proxy.pp +++ b/manifests/tls_proxy.pp @@ -40,6 +40,7 @@ define tripleo::tls_proxy( $tls_cert, $tls_key, ) { + include ::apache ::apache::vhost { "${title}-proxy": ensure => 'present', docroot => undef, # This is required by the manifest diff --git a/manifests/ui.pp b/manifests/ui.pp index b2ed178..1745535 100644 --- a/manifests/ui.pp +++ b/manifests/ui.pp @@ -39,6 +39,7 @@ # 'de' => 'German', # 'en' => 'English', # 'es' => 'Spanish', +# 'id' => 'Indonesian', # 'ja' => 'Japanese', # 'ko-KR' => 'Korean', # 'zh-CN' => 'Simplified Chinese' @@ -106,6 +107,7 @@ class tripleo::ui ( 'de' => 'German', 'en' => 'English', 'es' => 'Spanish', + 'id' => 'Indonesian', 'ja' => 'Japanese', 'ko-KR' => 'Korean', 'zh-CN' => 'Simplified Chinese' diff --git a/releasenotes/notes/Composable_role_for_neutron_lbaas-acdf08f1a9dfd3fe.yaml b/releasenotes/notes/Composable_role_for_neutron_lbaas-acdf08f1a9dfd3fe.yaml new file mode 100644 index 0000000..20e5994 --- /dev/null +++ b/releasenotes/notes/Composable_role_for_neutron_lbaas-acdf08f1a9dfd3fe.yaml @@ -0,0 +1,3 @@ +--- +features: + - Adds composable service interface for Neutron LBaaSv2 service. diff --git a/releasenotes/notes/add-bagpipe-driver-9163f5b22096fde0.yaml b/releasenotes/notes/add-bagpipe-driver-9163f5b22096fde0.yaml index df6b232..3b9f189 100644 --- a/releasenotes/notes/add-bagpipe-driver-9163f5b22096fde0.yaml +++ b/releasenotes/notes/add-bagpipe-driver-9163f5b22096fde0.yaml @@ -1,3 +1,4 @@ --- features: - Add support for Bagpipe Neutron driver as backend in BGPVPN scenarios + - Add ML2 plugin configuration for Bagpipe BGPVPN extension diff --git a/releasenotes/notes/calculate-dhcp-agents-per-network-3089c5e7b15f8b7b.yaml b/releasenotes/notes/calculate-dhcp-agents-per-network-3089c5e7b15f8b7b.yaml index 800cedc..1e6c327 100644 --- a/releasenotes/notes/calculate-dhcp-agents-per-network-3089c5e7b15f8b7b.yaml +++ b/releasenotes/notes/calculate-dhcp-agents-per-network-3089c5e7b15f8b7b.yaml @@ -1,5 +1,6 @@ --- -features: | - - Unless a non-default value is provided, the dhcp_agents_per_network +features: + - | + Unless a non-default value is provided, the dhcp_agents_per_network neutron configuration variable is set to the number of deployed neutron dhcp agents. diff --git a/releasenotes/notes/cold_migration_security-1543136408c76459.yaml b/releasenotes/notes/cold_migration_security-1543136408c76459.yaml new file mode 100644 index 0000000..aaea57e --- /dev/null +++ b/releasenotes/notes/cold_migration_security-1543136408c76459.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Restrict nova migration ssh tunnel + * The ssh authorized_keys file is only writeable by root. + * Creates a new user for migration instead of using root/nova. + * Disables SSH forwarding for this user. + * Restricts the networks that this user can connect from. + * Uses an ssh wrapper command to whitelist the commands that this user can run over ssh. + Adds new parameter "tripleo::profile::base::nova::migration_ssh_localaddrs" to specify which incoming IPs are allow for SSH tunnel connections. diff --git a/releasenotes/notes/deprecate-redis-file-limit-4a60fa0fde4667ef.yaml b/releasenotes/notes/deprecate-redis-file-limit-4a60fa0fde4667ef.yaml new file mode 100644 index 0000000..a362abc --- /dev/null +++ b/releasenotes/notes/deprecate-redis-file-limit-4a60fa0fde4667ef.yaml @@ -0,0 +1,5 @@ +--- +deprecations: + - | + The redis_file_limit hiera parameter is now deprecated. Use the + redis::ulimit parameter instead. diff --git a/releasenotes/notes/ensure-ssl-conf-2f32c6ead6f3bb0e.yaml b/releasenotes/notes/ensure-ssl-conf-2f32c6ead6f3bb0e.yaml new file mode 100644 index 0000000..92f2360 --- /dev/null +++ b/releasenotes/notes/ensure-ssl-conf-2f32c6ead6f3bb0e.yaml @@ -0,0 +1,10 @@ +--- +fixes: + - | + With having package mod_ssl by default installed in images we introduced + issue with mod_ssl package update. In case of SSL not being used or + provided by HAproxy the puppet-apache module by default purges the + ssl.conf file. The package update then recreates the file with default + Listen 443 option. This causes conflict on 443 port during httpd restart. + If we include ::apache::mod::ssl the ssl.conf file will be configured and + the Listen option will be used only if there is vhost set to use SSL. diff --git a/releasenotes/notes/etcd-tls-bb8605c91ff8a94c.yaml b/releasenotes/notes/etcd-tls-bb8605c91ff8a94c.yaml new file mode 100644 index 0000000..d041267 --- /dev/null +++ b/releasenotes/notes/etcd-tls-bb8605c91ff8a94c.yaml @@ -0,0 +1,3 @@ +--- +features: + - Enable internal network TLS for etcd diff --git a/releasenotes/notes/mistral-mod-wsgi-1a1d3eb279daa7fd.yaml b/releasenotes/notes/mistral-mod-wsgi-1a1d3eb279daa7fd.yaml new file mode 100644 index 0000000..ae6401f --- /dev/null +++ b/releasenotes/notes/mistral-mod-wsgi-1a1d3eb279daa7fd.yaml @@ -0,0 +1,7 @@ +--- +features: + - Move Mistral API to use mod_wsgi under Apache. +upgrade: + - Mistral API systemd service will be stopped and + disabled. + diff --git a/releasenotes/notes/move-ceilo-upgrade-out-3318df875de5cd00.yaml b/releasenotes/notes/move-ceilo-upgrade-out-3318df875de5cd00.yaml new file mode 100644 index 0000000..1899db9 --- /dev/null +++ b/releasenotes/notes/move-ceilo-upgrade-out-3318df875de5cd00.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - Since collector is deprecated, move the ceilo upgrade in step5 + out of collector profile and into cielometer base. This way + ceilo upgrade can run even when collector is disabled which is + the default in pike. diff --git a/releasenotes/notes/neutron-bigswitch-agent-profile-1250bb1518199a67.yaml b/releasenotes/notes/neutron-bigswitch-agent-profile-1250bb1518199a67.yaml new file mode 100644 index 0000000..daaf6f4 --- /dev/null +++ b/releasenotes/notes/neutron-bigswitch-agent-profile-1250bb1518199a67.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Moves bigswitch neutron agent configuration to a new tripleo profile + tripleo::profile::base::neutron::agents::bigswitch diff --git a/releasenotes/notes/redfish-9203af1f7bf02bc5.yaml b/releasenotes/notes/redfish-9203af1f7bf02bc5.yaml new file mode 100644 index 0000000..d34c3d9 --- /dev/null +++ b/releasenotes/notes/redfish-9203af1f7bf02bc5.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Support for Redfish hardware is enabled by default for overcloud Ironic + via the ``redfish`` hardware type. diff --git a/releasenotes/notes/zaqar-httpd-93db7feb60622687.yaml b/releasenotes/notes/zaqar-httpd-93db7feb60622687.yaml new file mode 100644 index 0000000..cff9d65 --- /dev/null +++ b/releasenotes/notes/zaqar-httpd-93db7feb60622687.yaml @@ -0,0 +1,3 @@ +--- +features: + - Run the Zaqar WSGI service over httpd. diff --git a/releasenotes/source/ocata.rst b/releasenotes/source/ocata.rst index ebe62f4..53fb86e 100644 --- a/releasenotes/source/ocata.rst +++ b/releasenotes/source/ocata.rst @@ -3,4 +3,4 @@ =================================== .. release-notes:: - :branch: origin/stable/ocata + :branch: stable/ocata diff --git a/spec/classes/tripleo_certmonger_etcd.rb b/spec/classes/tripleo_certmonger_etcd.rb new file mode 100644 index 0000000..fc0aad3 --- /dev/null +++ b/spec/classes/tripleo_certmonger_etcd.rb @@ -0,0 +1,60 @@ +# +# 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::etcd' do + + shared_examples_for 'tripleo::certmonger::etcd' 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('etcd').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') + is_expected.to contain_file('/etc/pki/key.pem') + end + end + + on_supported_os.each do |os, facts| + context "on #{os}" do + let(:facts) do + facts.merge({}) + end + + it_behaves_like 'tripleo::certmonger::etcd' + end + end +end diff --git a/spec/classes/tripleo_profile_base_ceilometer_collector_spec.rb b/spec/classes/tripleo_profile_base_ceilometer_collector_spec.rb index 0f9aad7..23b198a 100644 --- a/spec/classes/tripleo_profile_base_ceilometer_collector_spec.rb +++ b/spec/classes/tripleo_profile_base_ceilometer_collector_spec.rb @@ -128,32 +128,6 @@ describe 'tripleo::profile::base::ceilometer::collector' do is_expected.to contain_class('ceilometer::dispatcher::gnocchi') end end - - context 'with step 5 on bootstrap node' do - let(:params) { { - :step => 5, - :bootstrap_node => 'node.example.com', - :mongodb_node_ips => ['127.0.0.1',], - :mongodb_replset => 'replicaset' - } } - - it 'should trigger complete configuration' do - is_expected.to contain_exec('ceilometer-db-upgrade') - end - end - - context 'with step 5 not on bootstrap node' do - let(:params) { { - :step => 5, - :bootstrap_node => 'somethingelse.example.com', - :mongodb_node_ips => ['127.0.0.1',], - :mongodb_replset => 'replicaset' - } } - - it 'should trigger complete configuration' do - is_expected.to_not contain_exec('ceilometer-db-upgrade') - end - end end diff --git a/spec/classes/tripleo_profile_base_ceilometer_spec.rb b/spec/classes/tripleo_profile_base_ceilometer_spec.rb index 9173203..bc4ffac 100644 --- a/spec/classes/tripleo_profile_base_ceilometer_spec.rb +++ b/spec/classes/tripleo_profile_base_ceilometer_spec.rb @@ -42,6 +42,7 @@ describe 'tripleo::profile::base::ceilometer' do is_expected.to contain_class('ceilometer::config') end end + end diff --git a/spec/classes/tripleo_profile_base_docker_spec.rb b/spec/classes/tripleo_profile_base_docker_spec.rb index b52fe24..0b988f6 100644 --- a/spec/classes/tripleo_profile_base_docker_spec.rb +++ b/spec/classes/tripleo_profile_base_docker_spec.rb @@ -27,7 +27,10 @@ describe 'tripleo::profile::base::docker' do it { is_expected.to contain_package('docker') } it { is_expected.to contain_service('docker') } it { - is_expected.to contain_augeas('docker-sysconfig').with_changes(['rm INSECURE_REGISTRY']) + is_expected.to contain_augeas('docker-sysconfig').with_changes([ + 'rm INSECURE_REGISTRY', + "set OPTIONS '\"--log-driver=journald --signature-verification=false\"'", + ]) } end @@ -42,7 +45,10 @@ describe 'tripleo::profile::base::docker' do it { is_expected.to contain_package('docker') } it { is_expected.to contain_service('docker') } it { - is_expected.to contain_augeas('docker-sysconfig').with_changes(["set INSECURE_REGISTRY '\"--insecure-registry foo:8787\"'"]) + is_expected.to contain_augeas('docker-sysconfig').with_changes([ + "set INSECURE_REGISTRY '\"--insecure-registry foo:8787\"'", + "set OPTIONS '\"--log-driver=journald --signature-verification=false\"'", + ]) } end @@ -69,6 +75,55 @@ describe 'tripleo::profile::base::docker' do } end + context 'with step 1 and docker_options configured' do + let(:params) { { + :docker_options => '--log-driver=syslog', + :step => 1, + } } + + it { is_expected.to contain_class('tripleo::profile::base::docker') } + it { is_expected.to contain_package('docker') } + it { is_expected.to contain_service('docker') } + it { + is_expected.to contain_augeas('docker-sysconfig').with_changes([ + "rm INSECURE_REGISTRY", + "set OPTIONS '\"--log-driver=syslog\"'", + ]) + } + end + + context 'with step 1 and storage_options configured' do + let(:params) { { + :step => 1, + :storage_options => '-s devicemapper', + } } + + it { is_expected.to contain_class('tripleo::profile::base::docker') } + it { is_expected.to contain_package('docker') } + it { is_expected.to contain_service('docker') } + it { + is_expected.to contain_augeas('docker-sysconfig-storage').with_changes([ + "set DOCKER_STORAGE_OPTIONS '\" #{params[:storage_options]}\"'", + ]) + } + end + + context 'with step 1 and configure_storage disabled' do + let(:params) { { + :step => 1, + :configure_storage => false, + } } + + it { is_expected.to contain_class('tripleo::profile::base::docker') } + it { is_expected.to contain_package('docker') } + it { is_expected.to contain_service('docker') } + it { + is_expected.to contain_augeas('docker-sysconfig-storage').with_changes([ + "rm DOCKER_STORAGE_OPTIONS", + ]) + } + end + end on_supported_os.each do |os, facts| diff --git a/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb b/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb index 805a28e..6c04e9d 100644 --- a/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb +++ b/spec/classes/tripleo_profile_base_gnocchi_api_spec.rb @@ -23,7 +23,11 @@ describe 'tripleo::profile::base::gnocchi::api' do end context 'with step less than 3' do - let(:params) { { :step => 2 } } + let(:params) { { + :step => 2, + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' + } } it { is_expected.to contain_class('tripleo::profile::base::gnocchi::api') @@ -36,6 +40,8 @@ describe 'tripleo::profile::base::gnocchi::api' do let(:params) { { :step => 3, :bootstrap_node => 'node.example.com', + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' } } it { @@ -48,6 +54,8 @@ describe 'tripleo::profile::base::gnocchi::api' do context 'with step 3' do let(:params) { { :step => 3, + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' } } it { @@ -57,35 +65,76 @@ describe 'tripleo::profile::base::gnocchi::api' do } end - # TODO(aschultz): fix profile class to not include hiera look ups in the - # step 4 so we can properly test it - #context 'with step 4' do - # let(:params) { { - # :step => 4, - # } } - # - # it { - # is_expected.to contain_class('gnocchi::api') - # is_expected.to contain_class('gnocchi::wsgi::apache') - # is_expected.to contain_class('gnocchi::storage') - # } - #end - # - #context 'with step 5 on bootstrap' do - # let(:params) { { - # :step => 5, - # :bootstrap_node => 'node.example.com' - # } } - # - # it { - # is_expected.to contain_class('gnocchi::api') - # is_expected.to contain_class('gnocchi::wsgi::apache') - # is_expected.to contain_exec('run gnocchi upgrade with storage').with( - # :command => 'gnocchi-upgrade --config-file=/etc/gnocchi/gnocchi.conf', - # :path => ['/usr/bin', '/usr/sbin'] - # ) - # } - #end + context 'with step 4' do + let(:params) { { + :step => 4, + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' + } } + + it { + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + is_expected.to contain_class('gnocchi::storage').with( + :coordination_url => 'redis://:gnocchi@127.0.0.1:6379/' + ) + is_expected.to contain_class('gnocchi::storage::swift') + } + end + + context 'with step 4 with file backend' do + let(:params) { { + :step => 4, + :gnocchi_backend => 'file', + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' + } } + + it { + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + is_expected.to contain_class('gnocchi::storage').with( + :coordination_url => 'redis://:gnocchi@127.0.0.1:6379/' + ) + is_expected.to contain_class('gnocchi::storage::file') + } + end + + context 'with step 4 with ceph backend' do + let(:params) { { + :step => 4, + :gnocchi_backend => 'rbd', + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' + } } + + it { + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + is_expected.to contain_class('gnocchi::storage').with( + :coordination_url => 'redis://:gnocchi@127.0.0.1:6379/' + ) + is_expected.to contain_class('gnocchi::storage::ceph') + } + end + + context 'with step 5 on bootstrap' do + let(:params) { { + :step => 5, + :bootstrap_node => 'node.example.com', + :gnocchi_redis_password => 'gnocchi', + :redis_vip => '127.0.0.1' + } } + + it { + is_expected.to contain_class('gnocchi::api') + is_expected.to contain_class('gnocchi::wsgi::apache') + is_expected.to contain_exec('run gnocchi upgrade with storage').with( + :command => 'gnocchi-upgrade --config-file=/etc/gnocchi/gnocchi.conf', + :path => ['/usr/bin', '/usr/sbin'] + ) + } + end end diff --git a/spec/classes/tripleo_profile_base_neutron_agents_bigswitch_spec.rb b/spec/classes/tripleo_profile_base_neutron_agents_bigswitch_spec.rb new file mode 100644 index 0000000..228b2f8 --- /dev/null +++ b/spec/classes/tripleo_profile_base_neutron_agents_bigswitch_spec.rb @@ -0,0 +1,48 @@ +# +# 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. +# + +require 'spec_helper' + +describe 'tripleo::profile::base::neutron::agents::bigswitch' do + + shared_examples_for 'tripleo::profile::base::neutron::agents::bigswitch' do + + context 'when step less than 4' do + let(:params) { { :step => 3 } } + it { + is_expected.to_not contain_class('neutron::agents::bigswitch') + } + end + + context 'when step 4' do + let(:params) { { :step => 4 } } + it { + is_expected.to contain_class('neutron::agents::bigswitch') + } + 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::agents::bigswitch' + end + end +end diff --git a/spec/classes/tripleo_profile_base_neutron_ovs_spec.rb b/spec/classes/tripleo_profile_base_neutron_ovs_spec.rb new file mode 100644 index 0000000..14de7e1 --- /dev/null +++ b/spec/classes/tripleo_profile_base_neutron_ovs_spec.rb @@ -0,0 +1,73 @@ +# +# 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. +# + +require 'spec_helper' + +describe 'tripleo::profile::base::neutron::ovs' do + + shared_examples_for 'tripleo::profile::base::neutron::ovs with default params' do + + before :each do + facts.merge!({ :step => params[:step] }) + end + + context 'with defaults for all parameters' do + let(:params) { { :step => 5 } } + + it 'should do nothing' do + is_expected.to contain_class('tripleo::profile::base::neutron') + is_expected.to contain_class('neutron::agents::ml2::ovs') + is_expected.not_to contain_file('/var/lib/vhostuser_sockets') + end + end + end + + shared_examples_for 'tripleo::profile::base::neutron::ovs with vhostuser_socketdir' do + + before :each do + facts.merge!({ :step => params[:step], :vhostuser_socket_dir => params[:vhostuser_socket_dir] }) + end + + context 'with vhostuser_socketdir configured' do + let :params do + { + :step => 5, + :vhostuser_socket_dir => '/var/lib/vhostuser_sockets' + } + end + + it { is_expected.to contain_class('tripleo::profile::base::neutron') } + it { is_expected.to contain_class('neutron::agents::ml2::ovs') } + it { is_expected.to contain_file('/var/lib/vhostuser_sockets').with( + :ensure => 'directory', + :owner => 'qemu', + :group => 'qemu', + :mode => '0775', + ) } + 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::ovs with default params' + it_behaves_like 'tripleo::profile::base::neutron::ovs with vhostuser_socketdir' + end + end +end diff --git a/spec/classes/tripleo_profile_base_nova_spec.rb b/spec/classes/tripleo_profile_base_nova_spec.rb index 8f7bfdc..a7f1cce 100644 --- a/spec/classes/tripleo_profile_base_nova_spec.rb +++ b/spec/classes/tripleo_profile_base_nova_spec.rb @@ -95,6 +95,8 @@ describe 'tripleo::profile::base::nova' do is_expected.to contain_class('nova::cache') is_expected.to contain_class('nova::placement') is_expected.to_not contain_class('nova::migration::libvirt') + is_expected.to_not contain_file('/etc/nova/migration/authorized_keys') + is_expected.to_not contain_file('/etc/nova/migration/identity') } end @@ -128,6 +130,24 @@ describe 'tripleo::profile::base::nova' do :configure_libvirt => params[:libvirt_enabled], :configure_nova => params[:nova_compute_enabled] ) + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => '# Migration over SSH disabled by TripleO', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => '# Migration over SSH disabled by TripleO', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/sbin/nologin' + ) } end @@ -162,13 +182,37 @@ describe 'tripleo::profile::base::nova' do :configure_libvirt => params[:libvirt_enabled], :configure_nova => params[:nova_compute_enabled], ) + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => '# Migration over SSH disabled by TripleO', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => '# Migration over SSH disabled by TripleO', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/sbin/nologin' + ) } end context 'with step 4 with libvirt and migration ssh key' do - let(:pre_condition) { - 'include ::nova::compute::libvirt::services' - } + let(:pre_condition) do + <<-eof + include ::nova::compute::libvirt::services + class { '::ssh::server': + storeconfigs_enabled => false, + options => {} + } + eof + end let(:params) { { :step => 4, :libvirt_enabled => true, @@ -185,8 +229,8 @@ describe 'tripleo::profile::base::nova' do is_expected.to contain_class('nova').with( :default_transport_url => /.+/, :notification_transport_url => /.+/, - :nova_public_key => {'key' => 'bar', 'type' => 'ssh-rsa'}, - :nova_private_key => {'key' => 'foo', 'type' => 'ssh-rsa'} + :nova_public_key => nil, + :nova_private_key => nil, ) is_expected.to contain_class('nova::config') is_expected.to contain_class('nova::placement') @@ -196,13 +240,228 @@ describe 'tripleo::profile::base::nova' do :configure_libvirt => params[:libvirt_enabled], :configure_nova => params[:nova_compute_enabled] ) + is_expected.to contain_ssh__server__match_block('nova_migration allow').with( + :type => 'User', + :name => 'nova_migration', + :options => { + 'ForceCommand' => '/bin/nova-migration-wrapper', + 'PasswordAuthentication' => 'no', + 'AllowTcpForwarding' => 'no', + 'X11Forwarding' => 'no', + 'AuthorizedKeysFile' => '/etc/nova/migration/authorized_keys' + } + ) + is_expected.to_not contain_ssh__server__match_block('nova_migration deny') + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => 'ssh-rsa bar', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => 'foo', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/bin/bash' + ) } end - context 'with step 4 with libvirt TLS and migration ssh key' do - let(:pre_condition) { - 'include ::nova::compute::libvirt::services' + context 'with step 4 with libvirt and migration ssh key and migration_ssh_localaddrs' do + let(:pre_condition) do + <<-eof + include ::nova::compute::libvirt::services + class { '::ssh::server': + storeconfigs_enabled => false, + options => {} + } + eof + end + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :oslomsg_rpc_hosts => [ 'localhost' ], + :oslomsg_rpc_password => 'foo', + :migration_ssh_key => { 'private_key' => 'foo', 'public_key' => 'ssh-rsa bar'}, + :migration_ssh_localaddrs => ['127.0.0.1', '127.0.0.2'] + } } + + it { + is_expected.to contain_class('tripleo::profile::base::nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => nil, + :nova_private_key => nil, + ) + is_expected.to contain_class('nova::config') + is_expected.to contain_class('nova::placement') + is_expected.to contain_class('nova::cache') + is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'ssh', + :configure_libvirt => params[:libvirt_enabled], + :configure_nova => params[:nova_compute_enabled] + ) + is_expected.to contain_ssh__server__match_block('nova_migration allow').with( + :type => 'LocalAddress 127.0.0.1,127.0.0.2 User', + :name => 'nova_migration', + :options => { + 'ForceCommand' => '/bin/nova-migration-wrapper', + 'PasswordAuthentication' => 'no', + 'AllowTcpForwarding' => 'no', + 'X11Forwarding' => 'no', + 'AuthorizedKeysFile' => '/etc/nova/migration/authorized_keys' + } + ) + is_expected.to contain_ssh__server__match_block('nova_migration deny').with( + :type => 'LocalAddress', + :name => '!127.0.0.1,!127.0.0.2', + :options => { + 'DenyUsers' => 'nova_migration' + } + ) + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => 'ssh-rsa bar', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => 'foo', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/bin/bash' + ) } + end + + context 'with step 4 with libvirt and migration ssh key and invalid migration_ssh_localaddrs' do + let(:pre_condition) do + <<-eof + include ::nova::compute::libvirt::services + class { '::ssh::server': + storeconfigs_enabled => false, + options => {} + } + eof + end + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :oslomsg_rpc_hosts => [ 'localhost' ], + :oslomsg_rpc_password => 'foo', + :migration_ssh_key => { 'private_key' => 'foo', 'public_key' => 'ssh-rsa bar'}, + :migration_ssh_localaddrs => ['127.0.0.1', ''] + } } + + it { is_expected.to_not compile } + end + + context 'with step 4 with libvirt and migration ssh key and duplicate migration_ssh_localaddrs' do + let(:pre_condition) do + <<-eof + include ::nova::compute::libvirt::services + class { '::ssh::server': + storeconfigs_enabled => false, + options => {} + } + eof + end + let(:params) { { + :step => 4, + :libvirt_enabled => true, + :manage_migration => true, + :nova_compute_enabled => true, + :bootstrap_node => 'node.example.com', + :oslomsg_rpc_hosts => [ 'localhost' ], + :oslomsg_rpc_password => 'foo', + :migration_ssh_key => { 'private_key' => 'foo', 'public_key' => 'ssh-rsa bar'}, + :migration_ssh_localaddrs => ['127.0.0.1', '127.0.0.1'] + } } + + it { + is_expected.to contain_class('tripleo::profile::base::nova') + is_expected.to contain_class('nova').with( + :default_transport_url => /.+/, + :notification_transport_url => /.+/, + :nova_public_key => nil, + :nova_private_key => nil, + ) + is_expected.to contain_class('nova::config') + is_expected.to contain_class('nova::placement') + is_expected.to contain_class('nova::cache') + is_expected.to contain_class('nova::migration::libvirt').with( + :transport => 'ssh', + :configure_libvirt => params[:libvirt_enabled], + :configure_nova => params[:nova_compute_enabled] + ) + is_expected.to contain_ssh__server__match_block('nova_migration allow').with( + :type => 'LocalAddress 127.0.0.1 User', + :name => 'nova_migration', + :options => { + 'ForceCommand' => '/bin/nova-migration-wrapper', + 'PasswordAuthentication' => 'no', + 'AllowTcpForwarding' => 'no', + 'X11Forwarding' => 'no', + 'AuthorizedKeysFile' => '/etc/nova/migration/authorized_keys' + } + ) + is_expected.to contain_ssh__server__match_block('nova_migration deny').with( + :type => 'LocalAddress', + :name => '!127.0.0.1', + :options => { + 'DenyUsers' => 'nova_migration' + } + ) + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => 'ssh-rsa bar', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => 'foo', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/bin/bash' + ) + } + end + + context 'with step 4 with libvirt TLS and migration ssh key' do + let(:pre_condition) do + <<-eof + include ::nova::compute::libvirt::services + class { '::ssh::server': + storeconfigs_enabled => false, + options => {} + } + eof + end let(:params) { { :step => 4, :libvirt_enabled => true, @@ -220,8 +479,8 @@ describe 'tripleo::profile::base::nova' do is_expected.to contain_class('nova').with( :default_transport_url => /.+/, :notification_transport_url => /.+/, - :nova_public_key => {'key' => 'bar', 'type' => 'ssh-rsa'}, - :nova_private_key => {'key' => 'foo', 'type' => 'ssh-rsa'} + :nova_public_key => nil, + :nova_private_key => nil, ) is_expected.to contain_class('nova::config') is_expected.to contain_class('nova::placement') @@ -231,6 +490,36 @@ describe 'tripleo::profile::base::nova' do :configure_libvirt => params[:libvirt_enabled], :configure_nova => params[:nova_compute_enabled] ) + is_expected.to contain_ssh__server__match_block('nova_migration allow').with( + :type => 'User', + :name => 'nova_migration', + :options => { + 'ForceCommand' => '/bin/nova-migration-wrapper', + 'PasswordAuthentication' => 'no', + 'AllowTcpForwarding' => 'no', + 'X11Forwarding' => 'no', + 'AuthorizedKeysFile' => '/etc/nova/migration/authorized_keys' + } + ) + is_expected.to_not contain_ssh__server__match_block('nova_migration deny') + is_expected.to contain_package('openstack-nova-migration').with( + :ensure => 'present' + ) + is_expected.to contain_file('/etc/nova/migration/authorized_keys').with( + :content => 'ssh-rsa bar', + :mode => '0640', + :owner => 'root', + :group => 'nova_migration', + ) + is_expected.to contain_file('/etc/nova/migration/identity').with( + :content => 'foo', + :mode => '0600', + :owner => 'nova', + :group => 'nova', + ) + is_expected.to contain_user('nova_migration').with( + :shell => '/bin/bash' + ) } end diff --git a/spec/classes/tripleo_profile_base_sshd_spec.rb b/spec/classes/tripleo_profile_base_sshd_spec.rb index e84a1f5..58b271f 100644 --- a/spec/classes/tripleo_profile_base_sshd_spec.rb +++ b/spec/classes/tripleo_profile_base_sshd_spec.rb @@ -24,7 +24,23 @@ describe 'tripleo::profile::base::sshd' do context 'it should do nothing' do it do - is_expected.to contain_class('ssh::server') + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => {} + }) + is_expected.to_not contain_file('/etc/issue') + is_expected.to_not contain_file('/etc/issue.net') + is_expected.to_not contain_file('/etc/motd') + end + end + + context 'it should do nothing with empty strings' do + let(:params) {{ :bannertext => '', :motd => '' }} + it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => {} + }) is_expected.to_not contain_file('/etc/issue') is_expected.to_not contain_file('/etc/issue.net') is_expected.to_not contain_file('/etc/motd') @@ -34,6 +50,12 @@ describe 'tripleo::profile::base::sshd' do context 'with issue and issue.net configured' do let(:params) {{ :bannertext => 'foo' }} it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => { + 'Banner' => '/etc/issue.net' + } + }) is_expected.to contain_file('/etc/issue').with({ 'content' => 'foo', 'owner' => 'root', @@ -53,6 +75,12 @@ describe 'tripleo::profile::base::sshd' do context 'with motd configured' do let(:params) {{ :motd => 'foo' }} it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => { + 'PrintMotd' => 'yes' + } + }) is_expected.to contain_file('/etc/motd').with({ 'content' => 'foo', 'owner' => 'root', @@ -63,6 +91,94 @@ describe 'tripleo::profile::base::sshd' do is_expected.to_not contain_file('/etc/issue.net') end end + + context 'with options configured' do + let(:params) {{ :options => {'X11Forwarding' => 'no'} }} + it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => { + 'X11Forwarding' => 'no' + } + }) + is_expected.to_not contain_file('/etc/motd') + is_expected.to_not contain_file('/etc/issue') + is_expected.to_not contain_file('/etc/issue.net') + end + end + + context 'with motd and issue configured' do + let(:params) {{ + :bannertext => 'foo', + :motd => 'foo' + }} + it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => { + 'Banner' => '/etc/issue.net', + 'PrintMotd' => 'yes' + } + }) + is_expected.to contain_file('/etc/motd').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + is_expected.to contain_file('/etc/issue').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + is_expected.to contain_file('/etc/issue.net').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + end + end + + context 'with motd and issue and options configured' do + let(:params) {{ + :bannertext => 'foo', + :motd => 'foo', + :options => { + 'PrintMotd' => 'no', # this should be overridden + 'X11Forwarding' => 'no' + } + }} + it do + is_expected.to contain_class('ssh::server').with({ + 'storeconfigs_enabled' => false, + 'options' => { + 'Banner' => '/etc/issue.net', + 'PrintMotd' => 'yes', + 'X11Forwarding' => 'no' + } + }) + is_expected.to contain_file('/etc/motd').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + is_expected.to contain_file('/etc/issue').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + is_expected.to contain_file('/etc/issue.net').with({ + 'content' => 'foo', + 'owner' => 'root', + 'group' => 'root', + 'mode' => '0644', + }) + end + end end on_supported_os.each do |os, facts| diff --git a/spec/fixtures/hieradata/default.yaml b/spec/fixtures/hieradata/default.yaml index 16f39a5..ad2da39 100644 --- a/spec/fixtures/hieradata/default.yaml +++ b/spec/fixtures/hieradata/default.yaml @@ -30,6 +30,8 @@ cinder::rabbit_password: 'password' cinder::keystone::authtoken::password: 'password' # gnocchi related items gnocchi::keystone::authtoken::password: 'password' +gnocchi::storage::ceph::ceph_username: 'gnocchi' +gnocchi::storage::ceph::ceph_secret: 'password' # nova related items nova::rabbit_password: 'password' nova::keystone::authtoken::password: 'password' @@ -42,3 +44,6 @@ memcached_node_ips: # octavia related items octavia::rabbit_password: 'password' horizon::secret_key: 'secrete' +service_names: ['sshd'] +#Neutron related +neutron::rabbit_password: 'password' diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 429e807..9196bc9 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,56 +1 @@ -require 'beaker-rspec' -require 'beaker/puppet_install_helper' - -run_puppet_install_helper - -RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - modname = JSON.parse(open('metadata.json').read)['name'].split('-')[1] - - # Readable test descriptions - c.formatter = :documentation - - # Configure all nodes in nodeset - c.before :suite do - # Install module and dependencies - hosts.each do |host| - - # install git - install_package host, 'git' - - zuul_ref = ENV['ZUUL_REF'] - zuul_branch = ENV['ZUUL_BRANCH'] - zuul_url = ENV['ZUUL_URL'] - - repo = 'openstack/puppet-openstack-integration' - - # Start out with clean moduledir, don't trust r10k to purge it - on host, "rm -rf /etc/puppet/modules/*" - # Install dependent modules via git or zuul - r = on host, "test -e /usr/zuul-env/bin/zuul-cloner", { :acceptable_exit_codes => [0,1] } - if r.exit_code == 0 - zuul_clone_cmd = '/usr/zuul-env/bin/zuul-cloner ' - zuul_clone_cmd += '--cache-dir /opt/git ' - zuul_clone_cmd += "--zuul-ref #{zuul_ref} " - zuul_clone_cmd += "--zuul-branch #{zuul_branch} " - zuul_clone_cmd += "--zuul-url #{zuul_url} " - zuul_clone_cmd += "git://git.openstack.org #{repo}" - on host, zuul_clone_cmd - else - on host, "git clone https://git.openstack.org/#{repo} #{repo}" - end - - on host, "ZUUL_REF=#{zuul_ref} ZUUL_BRANCH=#{zuul_branch} ZUUL_URL=#{zuul_url} bash #{repo}/install_modules.sh" - - # Install the module being tested - on host, "rm -fr /etc/puppet/modules/#{modname}" - puppet_module_install(:source => proj_root, :module_name => modname) - - on host, "rm -fr #{repo}" - - # List modules installed to help with debugging - on host, puppet('module','list'), { :acceptable_exit_codes => 0 } - end - end -end +require 'puppet-openstack_spec_helper/beaker_spec_helper' diff --git a/test-requirements.txt b/test-requirements.txt index bedd666..1ea50a8 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,7 @@ -# this is required for the docs build jobs -sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 -oslosphinx>=2.5.0 # Apache-2.0 -reno>=0.1.1 # Apache-2.0 +# This is required for the docs build jobs +sphinx>=1.5.1 # BSD +oslosphinx>=4.7.0 # Apache-2.0 + +# This is required for the releasenotes build jobs +# FIXME: reno is manually pinned to !=2.0.0 because of bug #1651995 +reno>=1.8.0,!=2.0.0 # Apache-2.0 @@ -3,6 +3,9 @@ minversion = 1.6 skipsdist = True envlist = releasenotes +[testenv] +install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} + [testenv:releasenotes] deps = -rtest-requirements.txt commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html |