diff options
Diffstat (limited to 'manifests')
23 files changed, 1666 insertions, 28 deletions
diff --git a/manifests/certmonger/ca/crl.pp b/manifests/certmonger/ca/crl.pp new file mode 100644 index 0000000..59a3681 --- /dev/null +++ b/manifests/certmonger/ca/crl.pp @@ -0,0 +1,149 @@ +# 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::ca::crl +# +# Class that downloads the appropriate CRL file from the CA. This can +# furtherly be used by services in order for proper certificate revocation to +# come into effect. The class also sets up a cron job that will refresh the CRL +# once a week. Also, processing of the CRL file might be needed. e.g. most CAs +# use DER format to distribute the CRLs, while services such as HAProxy expect +# the CRL to be in PEM format. +# +# === Parameters +# +# [*crl_dest*] +# (Optional) The file where the CRL file will be stored. +# Defaults to '/etc/pki/CA/crl/overcloud-crl.pem' +# +# [*crl_source*] +# (Optional) The URI where the CRL file will be fetched from. +# Defaults to undef +# +# [*process*] +# (Optional) Whether the CRL needs processing before being used. This means +# transforming from DER to PEM format or viceversa. This is because most CRLs +# by default come in DER format, so most likely it needs to be transformed. +# Defaults to true +# +# [*crl_preprocessed*] +# (Optional) The pre-processed CRL file which will be transformed. +# Defaults to '/etc/pki/CA/crl/overcloud-crl.bin' +# +# [*crl_preprocessed_format*] +# (Optional) The pre-processed CRL file's format which will be transformed. +# Defaults to 'DER' +# +# [*minute*] +# (optional) Defaults to '0'. +# +# [*hour*] +# (optional) Defaults to '1'. +# +# [*monthday*] +# (optional) Defaults to '*'. +# +# [*month*] +# (optional) Defaults to '*'. +# +# [*weekday*] +# (optional) Defaults to '6'. +# +# [*maxdelay*] +# (optional) Seconds. Defaults to 0. Should be a positive integer. +# Induces a random delay before running the cronjob to avoid running all +# cron jobs at the same time on all hosts this job is configured. +# +# [*reload_cmds*] +# (Optional) list of commands to be executed after fetching the CRL list in +# the cron job. This will usually be a list of reload commands issued to +# services that use the CRL. +# Defaults to [] +# +class tripleo::certmonger::ca::crl ( + $crl_dest = '/etc/pki/CA/crl/overcloud-crl.pem', + $crl_source = undef, + $process = true, + $crl_preprocessed = '/etc/pki/CA/crl/overcloud-crl.bin', + $crl_preprocessed_format = 'DER', + $minute = '0', + $hour = '1', + $monthday = '*', + $month = '*', + $weekday = '6', + $maxdelay = 0, + $reload_cmds = [], +) { + if $crl_source { + $ensure = 'present' + } else { + $ensure = 'absent' + } + + if $maxdelay == 0 { + $sleep = '' + } else { + $sleep = "sleep `expr \${RANDOM} \\% ${maxdelay}`; " + } + + if $process { + $fetched_crl = $crl_preprocessed + } else { + $fetched_crl = $crl_dest + } + + file { 'tripleo-ca-crl' : + ensure => $ensure, + path => $fetched_crl, + source => $crl_source, + mode => '0644', + } + + if $process and $ensure == 'present' { + $crl_dest_format = $crl_preprocessed_format ? { + 'PEM' => 'DER', + 'DER' => 'PEM' + } + # transform CRL from DER to PEM or viceversa + $process_cmd = "openssl crl -in ${$crl_preprocessed} -inform ${crl_preprocessed_format} -outform ${crl_dest_format} -out ${crl_dest}" + exec { 'tripleo-ca-crl-process-command' : + command => $process_cmd, + path => '/usr/bin', + refreshonly => true, + subscribe => File['tripleo-ca-crl'] + } + } else { + $process_cmd = [] + } + + if $ensure == 'present' { + # Fetch CRL in cron job and notify needed services + $cmd_list = concat(["${sleep}curl -L -o ${fetched_crl} ${crl_source}"], $process_cmd, $reload_cmds) + $cron_cmd = join($cmd_list, ' && ') + } else { + $cron_cmd = absent + } + + cron { 'tripleo-refresh-crl-file': + ensure => $ensure, + command => $cron_cmd, + environment => 'PATH=/usr/bin SHELL=/bin/sh', + user => 'root', + minute => $minute, + hour => $hour, + monthday => $monthday, + month => $month, + weekday => $weekday, + } +} diff --git a/manifests/haproxy.pp b/manifests/haproxy.pp index a449a49..208f328 100644 --- a/manifests/haproxy.pp +++ b/manifests/haproxy.pp @@ -146,6 +146,10 @@ # the servers it balances # Defaults to '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt' # +# [*crl_file*] +# Path to the CRL file to be used for checking revoked certificates. +# Defaults to undef +# # [*haproxy_stats_certificate*] # Filename of an HAProxy-compatible certificate and key file # When set, enables SSL on the haproxy stats endpoint using the specified file. @@ -324,6 +328,11 @@ # (optional) Enable or not OVN northd binding # Defaults to hiera('ovn_dbs_enabled', false) # +# [*ovn_dbs_manage_lb*] +# (optional) Whether or not haproxy should configure OVN dbs for load balancing +# if ovn_dbs is enabled. +# Defaults to false +# # [*zaqar_ws*] # (optional) Enable or not Zaqar Websockets binding # Defaults to false @@ -560,6 +569,7 @@ class tripleo::haproxy ( $ssl_cipher_suite = '!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES', $ssl_options = 'no-sslv3', $ca_bundle = '/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt', + $crl_file = undef, $haproxy_stats_certificate = undef, $keystone_admin = hiera('keystone_enabled', false), $keystone_public = hiera('keystone_enabled', false), @@ -603,6 +613,7 @@ class tripleo::haproxy ( $ceph_rgw = hiera('ceph_rgw_enabled', false), $opendaylight = hiera('opendaylight_api_enabled', false), $ovn_dbs = hiera('ovn_dbs_enabled', false), + $ovn_dbs_manage_lb = false, $zaqar_ws = hiera('zaqar_api_enabled', false), $ui = hiera('enable_ui', false), $aodh_network = hiera('aodh_api_network', undef), @@ -722,7 +733,13 @@ class tripleo::haproxy ( $ports = merge($default_service_ports, $service_ports) if $enable_internal_tls { - $internal_tls_member_options = ['ssl', 'verify required', "ca-file ${ca_bundle}"] + $base_internal_tls_member_options = ['ssl', 'verify required', "ca-file ${ca_bundle}"] + + if $crl_file { + $internal_tls_member_options = concat($base_internal_tls_member_options, "crl-file ${crl_file}") + } else { + $internal_tls_member_options = $base_internal_tls_member_options + } Haproxy::Balancermember { verifyhost => true } @@ -1489,9 +1506,12 @@ class tripleo::haproxy ( } - if $ovn_dbs { + if $ovn_dbs and $ovn_dbs_manage_lb { # FIXME: is this config enough to ensure we only hit the first node in # ovn_northd_node_ips ? + # We only configure ovn_dbs_vip in haproxy if HA for OVN DB servers is + # disabled. + # If HA is enabled, pacemaker configures the OVN DB servers accordingly. $ovn_db_listen_options = { 'option' => [ 'tcpka' ], 'timeout client' => '90m', diff --git a/manifests/pacemaker/haproxy_with_vip.pp b/manifests/pacemaker/haproxy_with_vip.pp index 1fc3ff7..606ac26 100644 --- a/manifests/pacemaker/haproxy_with_vip.pp +++ b/manifests/pacemaker/haproxy_with_vip.pp @@ -69,6 +69,12 @@ define tripleo::pacemaker::haproxy_with_vip( $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, @@ -77,9 +83,10 @@ define tripleo::pacemaker::haproxy_with_vip( 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', @@ -87,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/ceilometer.pp b/manifests/profile/base/ceilometer.pp index e6a2f11..a85be5d 100644 --- a/manifests/profile/base/ceilometer.pp +++ b/manifests/profile/base/ceilometer.pp @@ -18,10 +18,6 @@ # # === 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. @@ -72,7 +68,6 @@ # Defaults to hiera('ceilometer::rabbit_use_ssl', '0') class tripleo::profile::base::ceilometer ( - $bootstrap_node = hiera('bootstrap_nodeid', undef), $step = hiera('step'), $oslomsg_rpc_proto = hiera('messaging_rpc_service_name', 'rabbit'), $oslomsg_rpc_hosts = any2array(hiera('rabbitmq_node_names', undef)), @@ -86,11 +81,6 @@ class tripleo::profile::base::ceilometer ( $oslomsg_notify_username = hiera('ceilometer::rabbit_userid', 'guest'), $oslomsg_use_ssl = hiera('ceilometer::rabbit_use_ssl', '0'), ) { - if $::hostname == downcase($bootstrap_node) { - $sync_db = true - } else { - $sync_db = false - } if $step >= 3 { $oslomsg_use_ssl_real = sprintf('%s', bool2num(str2bool($oslomsg_use_ssl))) @@ -114,13 +104,4 @@ class tripleo::profile::base::ceilometer ( } include ::ceilometer::config } - - # 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/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/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 4ba51ec..7a6559e 100644 --- a/manifests/profile/base/certmonger_user.pp +++ b/manifests/profile/base/certmonger_user.pp @@ -77,6 +77,16 @@ class tripleo::profile::base::certmonger_user ( $rabbitmq_certificate_specs = hiera('tripleo::profile::base::rabbitmq::certificate_specs', {}), $etcd_certificate_specs = hiera('tripleo::profile::base::etcd::certificate_specs', {}), ) { + unless empty($haproxy_certificates_specs) { + $reload_haproxy = ['systemctl reload haproxy'] + Class['::tripleo::certmonger::ca::crl'] ~> Haproxy::Balancermember<||> + Class['::tripleo::certmonger::ca::crl'] ~> Class['::haproxy'] + } else { + $reload_haproxy = [] + } + class { '::tripleo::certmonger::ca::crl' : + reload_cmds => $reload_haproxy, + } include ::tripleo::certmonger::ca::libvirt unless empty($apache_certificates_specs) { 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/docker.pp b/manifests/profile/base/docker.pp index bc784b5..67fbd71 100644 --- a/manifests/profile/base/docker.pp +++ b/manifests/profile/base/docker.pp @@ -47,6 +47,18 @@ # [*step*] # step defaults to hiera('step') # +# [*configure_libvirt_polkit*] +# Configures libvirt polkit to grant the kolla nova user access to the libvirtd unix domain socket on the host. +# Defaults to true when nova_compute service is enabled, false when nova_compute is disabled +# +# [*docker_nova_uid*] +# When configure_libvirt_polkit = true, the uid/gid of the nova user within the docker container. +# Defaults to 42436 +# +# [*services_enabled*] +# List of TripleO services enabled on the role. +# Defaults to hiera('services_names') +# class tripleo::profile::base::docker ( $docker_namespace = undef, $insecure_registry = false, @@ -55,7 +67,17 @@ class tripleo::profile::base::docker ( $configure_storage = true, $storage_options = '-s overlay2', $step = hiera('step'), + $configure_libvirt_polkit = undef, + $docker_nova_uid = 42436, + $services_enabled = hiera('service_names', []) ) { + + if $configure_libvirt_polkit == undef { + $configure_libvirt_polkit_real = 'nova_compute' in $services_enabled + } else { + $configure_libvirt_polkit_real = $configure_libvirt_polkit + } + if $step >= 1 { package {'docker': ensure => installed, @@ -125,7 +147,46 @@ class tripleo::profile::base::docker ( lens => 'Shellvars.lns', incl => '/etc/sysconfig/docker-storage', changes => $storage_changes, + notify => Service['docker'], + require => Package['docker'], } } + if ($step >= 4 and $configure_libvirt_polkit_real) { + # Workaround for polkit authorization for libvirtd socket on host + # + # This creates a local user with the kolla nova uid, and sets the polkit rule to + # allow both it and the nova user from the nova rpms, should it exist (uid 162). + + group { 'docker_nova_group': + name => 'docker_nova', + gid => $docker_nova_uid + } -> + user { 'docker_nova_user': + name => 'docker_nova', + uid => $docker_nova_uid, + gid => $docker_nova_uid, + shell => '/sbin/nologin', + comment => 'OpenStack Nova Daemons', + groups => ['nobody'] + } + + # Similar to the polkit rule in the openstack-nova rpm spec + # but allow both the 'docker_nova' and 'nova' user + $docker_nova_polkit_rule = '// openstack-nova libvirt management permissions +polkit.addRule(function(action, subject) { + if (action.id == "org.libvirt.unix.manage" && + /^(docker_)?nova$/.test(subject.user)) { + return polkit.Result.YES; + } +}); +' + package {'polkit': + ensure => installed, + } -> + file {'/etc/polkit-1/rules.d/50-nova.rules': + content => $docker_nova_polkit_rule, + mode => '0644' + } + } } diff --git a/manifests/profile/base/keystone.pp b/manifests/profile/base/keystone.pp index 31f5c93..c7eea14 100644 --- a/manifests/profile/base/keystone.pp +++ b/manifests/profile/base/keystone.pp @@ -222,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, }) @@ -338,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/mistral/event_engine.pp b/manifests/profile/base/mistral/event_engine.pp new file mode 100644 index 0000000..4214429 --- /dev/null +++ b/manifests/profile/base/mistral/event_engine.pp @@ -0,0 +1,46 @@ +# 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::mistral::event_engine +# +# Mistral Event Engine 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::mistral::event_engine ( + $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::mistral + + if $step >= 4 or ($step >= 3 and $sync_db) { + include ::mistral::event_engine + } + +} 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/novajoin.pp b/manifests/profile/base/novajoin.pp new file mode 100644 index 0000000..f9c1ea9 --- /dev/null +++ b/manifests/profile/base/novajoin.pp @@ -0,0 +1,83 @@ +# 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::novajoin +# +# novajoin vendordata plugin profile for tripleo +# +# === Parameters +# +# [*service_password*] +# The password for the novajoin service. +# +# [*enable_ipa_client_install*] +# Enable FreeIPA client installation for the node this runs on. +# Defaults to false +# +# [*oslomsg_rpc_hosts*] +# list of the oslo messaging rpc host fqdns +# Defaults to hiera('rabbitmq_node_names') +# +# [*oslomsg_rpc_proto*] +# Protocol driver for the oslo messaging rpc service +# Defaults to hiera('messaging_rpc_service_name', rabbit) +# +# [*oslomsg_rpc_password*] +# Password for oslo messaging rpc service +# Defaults to undef +# +# [*oslomsg_rpc_port*] +# IP port for oslo messaging rpc service +# Defaults to '5672' +# +# [*oslomsg_rpc_username*] +# Username for oslo messaging rpc service +# Defaults to 'guest' +# +# [*oslomsg_use_ssl*] +# Enable ssl oslo messaging services +# Defaults to '0' +# +# [*step*] +# (Optional) The current step of the deployment +# Defaults to hiera('step') +# + +class tripleo::profile::base::novajoin ( + $service_password, + $enable_ipa_client_install = false, + $oslomsg_rpc_hosts = any2array(hiera('rabbitmq_node_names', undef)), + $oslomsg_rpc_proto = hiera('messaging_rpc_service_name', 'rabbit'), + $oslomsg_rpc_password = undef, + $oslomsg_rpc_port = '5672', + $oslomsg_rpc_username = 'guest', + $oslomsg_use_ssl = '0', + $step = hiera('step'), +) { + if $step >= 3 { + $oslomsg_use_ssl_real = sprintf('%s', bool2num(str2bool($oslomsg_use_ssl))) + class { '::nova::metadata::novajoin::api' : + service_password => $service_password, + enable_ipa_client_install => $enable_ipa_client_install, + transport_url => os_transport_url({ + 'transport' => $oslomsg_rpc_proto, + 'hosts' => $oslomsg_rpc_hosts, + 'port' => sprintf('%s', $oslomsg_rpc_port), + 'username' => $oslomsg_rpc_username, + 'password' => $oslomsg_rpc_password, + 'ssl' => $oslomsg_use_ssl_real, + }), + } + } +} 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/pacemaker/clustercheck.pp b/manifests/profile/pacemaker/clustercheck.pp new file mode 100644 index 0000000..fad30da --- /dev/null +++ b/manifests/profile/pacemaker/clustercheck.pp @@ -0,0 +1,65 @@ +# 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::clustercheck +# +# Clustercheck, galera health check profile for tripleo +# +# === Parameters +# [*step*] +# (Optional) The current step in deployment. See tripleo-heat-templates +# for more details. +# Defaults to hiera('step') +# +# [*bind_address*] +# (Optional) The address that the local mysql instance should bind to. +# Defaults to hiera('mysql_bind_host') +# +# [*clustercheck_password*] +# (Optional) The password for the clustercheck user. +# Defaults to hiera('mysql::server::root_password') +# +# +class tripleo::profile::pacemaker::clustercheck ( + $step = hiera('step'), + $clustercheck_password = hiera('mysql::server::root_password'), + $bind_address = hiera('mysql_bind_host'), +) { + + if $step >= 1 { + file { '/etc/sysconfig/clustercheck' : + ensure => file, + mode => '0600', + owner => 'mysql', + group => 'mysql', + content => "MYSQL_USERNAME=root\n +MYSQL_PASSWORD='${clustercheck_password}'\n +MYSQL_HOST=localhost\n", + } + + # the clustercheck service is run via xinet in the container + xinetd::service { 'galera-monitor' : + bind => $bind_address, + port => '9200', + server => '/usr/bin/clustercheck', + per_source => 'UNLIMITED', + log_on_success => '', + log_on_failure => 'HOST', + flags => 'REUSE', + service_type => 'UNLISTED', + user => 'mysql', + group => 'mysql', + } + } +} 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_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/ovn_northd.pp b/manifests/profile/pacemaker/ovn_northd.pp new file mode 100644 index 0000000..af946af --- /dev/null +++ b/manifests/profile/pacemaker/ovn_northd.pp @@ -0,0 +1,121 @@ +# 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::neutron::plugins::ml2::ovn +# +# Neutron ML2 driver Pacemaker HA profile for tripleo +# +# === Parameters +# +# [*pacemaker_master*] +# (Optional) The hostname of the pacemaker master +# Defaults to hiera('ovn_dbs_short_bootstrap_node_name') +# +# [*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) +# +# [*ovn_dbs_vip*] +# (Optional) The OVN database virtual IP to be managed by the pacemaker. +# Defaults to hiera('ovn_dbs_vip') +# +# [*nb_db_port*] +# The TCP port in which the OVN Northbound DB listens to. +# Defaults to 6641 +# +# [*sb_db_port*] +# The TCP port in which the OVN Southbound DB listens to. +# Defaults to 6642 +# + +class tripleo::profile::pacemaker::ovn_northd ( + $pacemaker_master = hiera('ovn_dbs_short_bootstrap_node_name'), + $step = hiera('step'), + $pcs_tries = hiera('pcs_tries', 20), + $ovn_dbs_vip = hiera('ovn_dbs_vip'), + $nb_db_port = 6641, + $sb_db_port = 6642 +) { + + if $step >= 2 { + pacemaker::property { 'ovndb-role-node-property': + property => 'ovndb-role', + value => true, + tries => $pcs_tries, + node => $::hostname, + } + } + + if $step >= 3 and downcase($::hostname) == $pacemaker_master { + $ovndb_servers_resource_name = 'ovndb_servers' + $ovndb_servers_ocf_name = 'ovn:ovndb-servers' + $ovndb_vip_resource_name = "ip-${ovn_dbs_vip}" + + if is_ipv6_address($ovn_dbs_vip) { + $netmask = '128' + $nic = interface_for_ip($ovn_dbs_vip) + } else { + $netmask = '32' + $nic = '' + } + + pacemaker::resource::ip { "${ovndb_vip_resource_name}": + ip_address => $ovn_dbs_vip, + cidr_netmask => $netmask, + nic => $nic, + tries => $pcs_tries, + } + + pacemaker::resource::ocf { "${ovndb_servers_resource_name}": + ocf_agent_name => "${ovndb_servers_ocf_name}", + master_params => '', + op_params => 'start timeout=200s stop timeout=200s', + resource_params => "master_ip=${ovn_dbs_vip} nb_master_port=${nb_db_port} sb_master_port=${sb_db_port} manage_northd=yes", + tries => $pcs_tries, + location_rule => { + resource_discovery => 'exclusive', + score => 0, + expression => ['ovndb-role eq true'], + }, + meta_params => 'notify=true' + } + + pacemaker::constraint::order { "${ovndb_vip_resource_name}-then-${ovndb_servers_resource_name}": + first_resource => "${ovndb_vip_resource_name}", + second_resource => "${ovndb_servers_resource_name}-master", + first_action => 'start', + second_action => 'start', + constraint_params => 'kind=Mandatory', + tries => $pcs_tries, + } + + pacemaker::constraint::colocation { "${ovndb_vip_resource_name}-with-${ovndb_servers_resource_name}": + source => "${ovndb_vip_resource_name}", + target => "${ovndb_servers_resource_name}-master", + master_slave => true, + score => 'INFINITY', + tries => $pcs_tries, + } + + Pacemaker::Resource::Ip["${ovndb_vip_resource_name}"] -> + Pacemaker::Resource::Ocf["${ovndb_servers_resource_name}"] -> + Pacemaker::Constraint::Order["${ovndb_vip_resource_name}-then-${ovndb_servers_resource_name}"] -> + Pacemaker::Constraint::Colocation["${ovndb_vip_resource_name}-with-${ovndb_servers_resource_name}"] + } +} 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']], + } + } + } +} |