diff options
author | Dan Prince <dprince@redhat.com> | 2015-05-06 22:22:39 -0400 |
---|---|---|
committer | Dan Prince <dprince@redhat.com> | 2015-05-11 08:23:34 -0400 |
commit | 607ea9c8d30d752b01881e2ac913c712f0243272 (patch) | |
tree | fb14aa7a7d61f2bf0a05e7149f51d436a4b0e0f5 /puppet/manifests/overcloud_controller_pacemaker.pp | |
parent | 92377361c76a612457cc147a0608d94db430a771 (diff) |
Puppet: Split out controller pacemaker manifest
This patch adds support for using the Heat resource registry
so that end users can enable pacemaker. Using this approach
allows us to isolate all of the pacemaker logic for the
controller in a single template rather than use conditionals
for every service that must support it.
Change-Id: Ibefb80d0d8f98404133e4c31cf078d729b64dac3
Diffstat (limited to 'puppet/manifests/overcloud_controller_pacemaker.pp')
-rw-r--r-- | puppet/manifests/overcloud_controller_pacemaker.pp | 492 |
1 files changed, 492 insertions, 0 deletions
diff --git a/puppet/manifests/overcloud_controller_pacemaker.pp b/puppet/manifests/overcloud_controller_pacemaker.pp new file mode 100644 index 00000000..ba5f80a6 --- /dev/null +++ b/puppet/manifests/overcloud_controller_pacemaker.pp @@ -0,0 +1,492 @@ +# Copyright 2015 Red Hat, Inc. +# All Rights Reserved. +# +# 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. + +if !str2bool(hiera('enable_package_install', 'false')) { + case $::osfamily { + 'RedHat': { + Package { provider => 'norpm' } # provided by tripleo-puppet + } + default: { + warning('enable_package_install option not supported.') + } + } +} + +if $::hostname == downcase(hiera('bootstrap_nodeid')) { + $pacemaker_master = true +} else { + $pacemaker_master = false +} + +if hiera('step') >= 1 { + + $controller_node_ips = split(hiera('controller_node_ips'), ',') + + class { '::tripleo::loadbalancer' : + controller_hosts => $controller_node_ips, + manage_vip => false, + } + + $pacemaker_cluster_members = regsubst(hiera('controller_node_ips'), ',', ' ', 'G') + user { 'hacluster': + ensure => present, + } -> + class { '::pacemaker': + hacluster_pwd => hiera('hacluster_pwd'), + } -> + class { '::pacemaker::corosync': + cluster_members => $pacemaker_cluster_members, + setup_cluster => $pacemaker_master, + } + class { '::pacemaker::stonith': + disable => true, + } + if $pacemaker_master { + $control_vip = hiera('tripleo::loadbalancer::controller_virtual_ip') + pacemaker::resource::ip { 'control_vip': + ip_address => $control_vip, + } + $public_vip = hiera('tripleo::loadbalancer::public_virtual_ip') + pacemaker::resource::ip { 'public_vip': + ip_address => $public_vip, + } + pacemaker::resource::systemd { 'haproxy': + clone => true, + } + } + + Class['::pacemaker::corosync'] -> Pacemaker::Resource::Systemd <| |> + +} + +if hiera('step') >= 2 { + + if count(hiera('ntp::servers')) > 0 { + include ::ntp + } + + # MongoDB + if downcase(hiera('ceilometer_backend')) == 'mongodb' { + include ::mongodb::globals + + class {'::mongodb::server' : + service_ensure => undef + } + $mongo_node_ips = split(hiera('mongo_node_ips'), ',') + $mongo_node_ips_with_port = suffix($mongo_node_ips, ':27017') + $mongo_node_string = join($mongo_node_ips_with_port, ',') + + $mongodb_replset = hiera('mongodb::server::replset') + $ceilometer_mongodb_conn_string = "mongodb://${mongo_node_string}/ceilometer?replicaSet=${mongodb_replset}" + if downcase(hiera('bootstrap_nodeid')) == $::hostname { + + pacemaker::resource::systemd { 'mongod' : + options => "op start timeout=120s", + clone => true, + before => Exec['mongodb-ready'], + } + # NOTE (spredzy) : The replset can only be run + # once all the nodes have joined the cluster. + $mongodb_cluster_ready_command = join(suffix(prefix($mongo_node_ips, '/bin/nc -w1 '), ' 27017 < /dev/null'), ' && ') + exec { 'mongodb-ready' : + command => $mongodb_cluster_ready_command, + timeout => 600, + tries => 60, + try_sleep => 10, + before => Mongodb_replset[$mongodb_replset], + } + + mongodb_replset { $mongodb_replset : + members => $mongo_node_ips_with_port, + } + } + } + + # Redis + $redis_node_ips = split(hiera('redis_node_ips'), ',') + $redis_master_hostname = downcase(hiera('bootstrap_nodeid')) + + if $redis_master_hostname == $::hostname { + $slaveof = undef + } else { + $slaveof = "${redis_master_hostname} 6379" + } + class {'::redis' : + slaveof => $slaveof, + } + + if count($redis_node_ips) > 1 { + Class['::tripleo::redis_notification'] -> Service['redis-sentinel'] + include ::redis::sentinel + class {'::tripleo::redis_notification' : + haproxy_monitor_ip => hiera('tripleo::loadbalancer::controller_virtual_ip'), + } + } + + if str2bool(hiera('enable_galera', 'true')) { + $mysql_config_file = '/etc/my.cnf.d/galera.cnf' + } else { + $mysql_config_file = '/etc/my.cnf.d/server.cnf' + } + # TODO Galara + class { 'mysql::server': + config_file => $mysql_config_file, + override_options => { + 'mysqld' => { + 'bind-address' => hiera('controller_host') + } + } + } + + # FIXME: this should only occur on the bootstrap host (ditto for db syncs) + # Create all the database schemas + # Example DSN format: mysql://user:password@host/dbname + $allowed_hosts = ['%',hiera('controller_host')] + $keystone_dsn = split(hiera('keystone::database_connection'), '[@:/?]') + class { 'keystone::db::mysql': + user => $keystone_dsn[3], + password => $keystone_dsn[4], + host => $keystone_dsn[5], + dbname => $keystone_dsn[6], + allowed_hosts => $allowed_hosts, + } + $glance_dsn = split(hiera('glance::api::database_connection'), '[@:/?]') + class { 'glance::db::mysql': + user => $glance_dsn[3], + password => $glance_dsn[4], + host => $glance_dsn[5], + dbname => $glance_dsn[6], + allowed_hosts => $allowed_hosts, + } + $nova_dsn = split(hiera('nova::database_connection'), '[@:/?]') + class { 'nova::db::mysql': + user => $nova_dsn[3], + password => $nova_dsn[4], + host => $nova_dsn[5], + dbname => $nova_dsn[6], + allowed_hosts => $allowed_hosts, + } + $neutron_dsn = split(hiera('neutron::server::database_connection'), '[@:/?]') + class { 'neutron::db::mysql': + user => $neutron_dsn[3], + password => $neutron_dsn[4], + host => $neutron_dsn[5], + dbname => $neutron_dsn[6], + allowed_hosts => $allowed_hosts, + } + $cinder_dsn = split(hiera('cinder::database_connection'), '[@:/?]') + class { 'cinder::db::mysql': + user => $cinder_dsn[3], + password => $cinder_dsn[4], + host => $cinder_dsn[5], + dbname => $cinder_dsn[6], + allowed_hosts => $allowed_hosts, + } + $heat_dsn = split(hiera('heat::database_connection'), '[@:/?]') + class { 'heat::db::mysql': + user => $heat_dsn[3], + password => $heat_dsn[4], + host => $heat_dsn[5], + dbname => $heat_dsn[6], + allowed_hosts => $allowed_hosts, + } + if downcase(hiera('ceilometer_backend')) == 'mysql' { + $ceilometer_dsn = split(hiera('ceilometer_mysql_conn_string'), '[@:/?]') + class { 'ceilometer::db::mysql': + user => $ceilometer_dsn[3], + password => $ceilometer_dsn[4], + host => $ceilometer_dsn[5], + dbname => $ceilometer_dsn[6], + allowed_hosts => $allowed_hosts, + } + } + + # the module ignores erlang_cookie if cluster_config is false + file { '/var/lib/rabbitmq/.erlang.cookie': + ensure => 'present', + owner => 'rabbitmq', + group => 'rabbitmq', + mode => '0400', + content => hiera('rabbitmq::erlang_cookie'), + replace => true, + } -> + class { '::rabbitmq': + service_manage => false, + environment_variables => { + 'RABBITMQ_NODENAME' => "rabbit@$::hostname", + }, + } + if $pacemaker_master { + pacemaker::resource::ocf { 'rabbitmq': + resource_name => 'heartbeat:rabbitmq-cluster', + options => 'set_policy=\'ha-all ^(?!amq\.).* {"ha-mode":"all"}\'', + clone => true, + require => Class['::rabbitmq'], + } + } + + # pre-install swift here so we can build rings + include ::swift + + $cinder_enable_rbd_backend = hiera('cinder_enable_rbd_backend', false) + $enable_ceph = $cinder_enable_rbd_backend + + if $enable_ceph { + class { 'ceph::profile::params': + mon_initial_members => downcase(hiera('ceph_mon_initial_members')) + } + include ::ceph::profile::mon + } + + if str2bool(hiera('enable_ceph_storage', 'false')) { + include ::ceph::profile::client + include ::ceph::profile::osd + } + +} #END STEP 2 + +if hiera('step') >= 3 { + + include ::keystone + + #TODO: need a cleanup-keystone-tokens.sh solution here + keystone_config { + 'ec2/driver': value => 'keystone.contrib.ec2.backends.sql.Ec2'; + } + file { [ '/etc/keystone/ssl', '/etc/keystone/ssl/certs', '/etc/keystone/ssl/private' ]: + ensure => 'directory', + owner => 'keystone', + group => 'keystone', + require => Package['keystone'], + } + file { '/etc/keystone/ssl/certs/signing_cert.pem': + content => hiera('keystone_signing_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + file { '/etc/keystone/ssl/private/signing_key.pem': + content => hiera('keystone_signing_key'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/private'], + } + file { '/etc/keystone/ssl/certs/ca.pem': + content => hiera('keystone_ca_certificate'), + owner => 'keystone', + group => 'keystone', + notify => Service['keystone'], + require => File['/etc/keystone/ssl/certs'], + } + + $glance_backend = downcase(hiera('glance_backend', 'swift')) + case $glance_backend { + swift: { $glance_store = 'glance.store.swift.Store' } + file: { $glance_store = 'glance.store.filesystem.Store' } + rbd: { $glance_store = 'glance.store.rbd.Store' } + default: { fail('Unrecognized glance_backend parameter.') } + } + + # TODO: notifications, scrubber, etc. + include ::glance + class { 'glance::api': + known_stores => [$glance_store] + } + include ::glance::registry + include join(['::glance::backend::', $glance_backend]) + + class { 'nova': + glance_api_servers => join([hiera('glance_protocol'), '://', hiera('controller_virtual_ip'), ':', hiera('glance_port')]), + } + + include ::nova::api + include ::nova::cert + include ::nova::conductor + include ::nova::consoleauth + include ::nova::network::neutron + include ::nova::vncproxy + include ::nova::scheduler + + include ::neutron + include ::neutron::server + include ::neutron::agents::dhcp + include ::neutron::agents::l3 + + file { '/etc/neutron/dnsmasq-neutron.conf': + content => hiera('neutron_dnsmasq_options'), + owner => 'neutron', + group => 'neutron', + notify => Service['neutron-dhcp-service'], + require => Package['neutron'], + } + + class { 'neutron::plugins::ml2': + flat_networks => split(hiera('neutron_flat_networks'), ','), + tenant_network_types => [hiera('neutron_tenant_network_type')], + type_drivers => [hiera('neutron_tenant_network_type')], + } + + class { 'neutron::agents::ml2::ovs': + bridge_mappings => split(hiera('neutron_bridge_mappings'), ','), + tunnel_types => split(hiera('neutron_tunnel_types'), ','), + } + + class { 'neutron::agents::metadata': + auth_url => join(['http://', hiera('controller_virtual_ip'), ':35357/v2.0']), + } + + Service['neutron-server'] -> Service['neutron-dhcp-service'] + Service['neutron-server'] -> Service['neutron-l3'] + Service['neutron-server'] -> Service['neutron-ovs-agent-service'] + Service['neutron-server'] -> Service['neutron-metadata'] + + include ::cinder + include ::cinder::api + include ::cinder::glance + include ::cinder::scheduler + include ::cinder::volume + class {'cinder::setup_test_volume': + size => join([hiera('cinder_lvm_loop_device_size'), 'M']), + } + + $cinder_enable_iscsi = hiera('cinder_enable_iscsi_backend', true) + if $cinder_enable_iscsi { + $cinder_iscsi_backend = 'tripleo_iscsi' + + cinder::backend::iscsi { $cinder_iscsi_backend : + iscsi_ip_address => hiera('cinder_iscsi_ip_address'), + iscsi_helper => hiera('cinder_iscsi_helper'), + } + } + + if $enable_ceph { + + Ceph_pool { + pg_num => hiera('ceph::profile::params::osd_pool_default_pg_num'), + pgp_num => hiera('ceph::profile::params::osd_pool_default_pgp_num'), + size => hiera('ceph::profile::params::osd_pool_default_size'), + } + + $ceph_pools = hiera('ceph_pools') + ceph::pool { $ceph_pools : } + } + + if $cinder_enable_rbd_backend { + $cinder_rbd_backend = 'tripleo_ceph' + + cinder_config { + "${cinder_rbd_backend}/host": value => 'hostgroup'; + } + + cinder::backend::rbd { $cinder_rbd_backend : + rbd_pool => 'volumes', + rbd_user => 'openstack', + rbd_secret_uuid => hiera('ceph::profile::params::fsid'), + require => Ceph::Pool['volumes'], + } + } + + $cinder_enabled_backends = delete_undef_values([$cinder_iscsi_backend, $cinder_rbd_backend]) + class { '::cinder::backends' : + enabled_backends => $cinder_enabled_backends, + } + + # swift proxy + include ::memcached + include ::swift::proxy + include ::swift::proxy::proxy_logging + include ::swift::proxy::healthcheck + include ::swift::proxy::cache + include ::swift::proxy::keystone + include ::swift::proxy::authtoken + include ::swift::proxy::staticweb + include ::swift::proxy::ceilometer + include ::swift::proxy::ratelimit + include ::swift::proxy::catch_errors + include ::swift::proxy::tempurl + include ::swift::proxy::formpost + + # swift storage + if str2bool(hiera('enable_swift_storage', 'true')) { + class {'swift::storage::all': + mount_check => str2bool(hiera('swift_mount_check')) + } + if(!defined(File['/srv/node'])) { + file { '/srv/node': + ensure => directory, + owner => 'swift', + group => 'swift', + require => Package['openstack-swift'], + } + } + $swift_components = ['account', 'container', 'object'] + swift::storage::filter::recon { $swift_components : } + swift::storage::filter::healthcheck { $swift_components : } + } + + # Ceilometer + $ceilometer_backend = downcase(hiera('ceilometer_backend')) + case $ceilometer_backend { + /mysql/ : { + $ceilometer_database_connection = hiera('ceilometer_mysql_conn_string') + } + default : { + $ceilometer_database_connection = $ceilometer_mongodb_conn_string + } + } + include ::ceilometer + include ::ceilometer::api + include ::ceilometer::agent::notification + include ::ceilometer::agent::central + include ::ceilometer::alarm::notifier + include ::ceilometer::alarm::evaluator + include ::ceilometer::expirer + include ::ceilometer::collector + class { '::ceilometer::db' : + database_connection => $ceilometer_database_connection, + } + class { 'ceilometer::agent::auth': + auth_url => join(['http://', hiera('controller_virtual_ip'), ':5000/v2.0']), + } + + Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" } + + # Heat + include ::heat + include ::heat::api + include ::heat::api_cfn + include ::heat::api_cloudwatch + include ::heat::engine + + # Horizon + $vhost_params = { add_listen => false } + class { 'horizon': + cache_server_ip => split(hiera('memcache_node_ips', '127.0.0.1'), ','), + vhost_extra_params => $vhost_params, + } + + $snmpd_user = hiera('snmpd_readonly_user_name') + snmp::snmpv3_user { $snmpd_user: + authtype => 'MD5', + authpass => hiera('snmpd_readonly_user_password'), + } + class { 'snmp': + agentaddress => ['udp:161','udp6:[::1]:161'], + snmpd_config => [ join(['rouser ', hiera('snmpd_readonly_user_name')]), 'proc cron', 'includeAllDisks 10%', 'master agentx', 'trapsink localhost public', 'iquerySecName internalUser', 'rouser internalUser', 'defaultMonitors yes', 'linkUpDownNotifications yes' ], + } + +} #END STEP 3 |