bbcf83d5e75593f8ddd185b6a1bdaa1ef4f41cc5
[apex-tripleo-heat-templates.git] / puppet / manifests / overcloud_controller_pacemaker.pp
1 # Copyright 2015 Red Hat, Inc.
2 # All Rights Reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); you may
5 # not use this file except in compliance with the License. You may obtain
6 # a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 # License for the specific language governing permissions and limitations
14 # under the License.
15
16 Pcmk_resource <| |> {
17   tries     => 10,
18   try_sleep => 3,
19 }
20
21 # TODO(jistr): use pcs resource provider instead of just no-ops
22 Service <|
23   tag == 'aodh-service' or
24   tag == 'cinder-service' or
25   tag == 'ceilometer-service' or
26   tag == 'gnocchi-service' or
27   tag == 'neutron-service' or
28   tag == 'nova-service' or
29   tag == 'sahara-service'
30 |> {
31   hasrestart => true,
32   restart    => '/bin/true',
33   start      => '/bin/true',
34   stop       => '/bin/true',
35 }
36
37 include ::tripleo::packages
38 include ::tripleo::firewall
39
40 if $::hostname == downcase(hiera('bootstrap_nodeid')) {
41   $pacemaker_master = true
42   $sync_db = true
43 } else {
44   $pacemaker_master = false
45   $sync_db = false
46 }
47
48 $enable_fencing = str2bool(hiera('enable_fencing', false)) and hiera('step') >= 5
49 $enable_load_balancer = hiera('enable_load_balancer', true)
50
51 # When to start and enable services which haven't been Pacemakerized
52 # FIXME: remove when we start all OpenStack services using Pacemaker
53 # (occurrences of this variable will be gradually replaced with false)
54 $non_pcmk_start = hiera('step') >= 5
55
56 if hiera('step') >= 1 {
57
58   create_resources(kmod::load, hiera('kernel_modules'), {})
59   create_resources(sysctl::value, hiera('sysctl_settings'), {})
60   Exec <| tag == 'kmod::load' |>  -> Sysctl <| |>
61
62   include ::timezone
63
64   if count(hiera('ntp::servers')) > 0 {
65     include ::ntp
66   }
67
68   $pacemaker_cluster_members = downcase(regsubst(hiera('controller_node_names'), ',', ' ', 'G'))
69   $corosync_ipv6 = str2bool(hiera('corosync_ipv6', false))
70   if $corosync_ipv6 {
71     $cluster_setup_extras = { '--token' => hiera('corosync_token_timeout', 1000), '--ipv6' => '' }
72   } else {
73     $cluster_setup_extras = { '--token' => hiera('corosync_token_timeout', 1000) }
74   }
75   class { '::pacemaker':
76     hacluster_pwd => hiera('hacluster_pwd'),
77   } ->
78   class { '::pacemaker::corosync':
79     cluster_members      => $pacemaker_cluster_members,
80     setup_cluster        => $pacemaker_master,
81     cluster_setup_extras => $cluster_setup_extras,
82   }
83   class { '::pacemaker::stonith':
84     disable => !$enable_fencing,
85   }
86   if $enable_fencing {
87     include ::tripleo::fencing
88
89     # enable stonith after all Pacemaker resources have been created
90     Pcmk_resource<||> -> Class['tripleo::fencing']
91     Pcmk_constraint<||> -> Class['tripleo::fencing']
92     Exec <| tag == 'pacemaker_constraint' |> -> Class['tripleo::fencing']
93     # enable stonith after all fencing devices have been created
94     Class['tripleo::fencing'] -> Class['pacemaker::stonith']
95   }
96
97   # FIXME(gfidente): sets 200secs as default start timeout op
98   # param; until we can use pcmk global defaults we'll still
99   # need to add it to every resource which redefines op params
100   Pacemaker::Resource::Service {
101     op_params => 'start timeout=200s stop timeout=200s',
102   }
103
104   if downcase(hiera('ceilometer_backend')) == 'mongodb' {
105     include ::mongodb::globals
106     include ::mongodb::client
107     class { '::mongodb::server' :
108       service_manage => false,
109     }
110   }
111
112   # Redis
113   class { '::redis' :
114     service_manage => false,
115     notify_service => false,
116   }
117
118   # Galera
119   if str2bool(hiera('enable_galera', true)) {
120     $mysql_config_file = '/etc/my.cnf.d/galera.cnf'
121   } else {
122     $mysql_config_file = '/etc/my.cnf.d/server.cnf'
123   }
124   $galera_nodes = downcase(hiera('galera_node_names', $::hostname))
125   $galera_nodes_count = count(split($galera_nodes, ','))
126
127   # FIXME: due to https://bugzilla.redhat.com/show_bug.cgi?id=1298671 we
128   # set bind-address to a hostname instead of an ip address; to move Mysql
129   # from internal_api on another network we'll have to customize both
130   # MysqlNetwork and ControllerHostnameResolveNetwork in ServiceNetMap
131   $mysql_bind_host = hiera('mysql_bind_host')
132   $mysqld_options = {
133     'mysqld' => {
134       'skip-name-resolve'             => '1',
135       'binlog_format'                 => 'ROW',
136       'default-storage-engine'        => 'innodb',
137       'innodb_autoinc_lock_mode'      => '2',
138       'innodb_locks_unsafe_for_binlog'=> '1',
139       'query_cache_size'              => '0',
140       'query_cache_type'              => '0',
141       'bind-address'                  => $::hostname,
142       'max_connections'               => hiera('mysql_max_connections'),
143       'open_files_limit'              => '-1',
144       'wsrep_on'                      => 'ON',
145       'wsrep_provider'                => '/usr/lib64/galera/libgalera_smm.so',
146       'wsrep_cluster_name'            => 'galera_cluster',
147       'wsrep_cluster_address'         => "gcomm://${galera_nodes}",
148       'wsrep_slave_threads'           => '1',
149       'wsrep_certify_nonPK'           => '1',
150       'wsrep_max_ws_rows'             => '131072',
151       'wsrep_max_ws_size'             => '1073741824',
152       'wsrep_debug'                   => '0',
153       'wsrep_convert_LOCK_to_trx'     => '0',
154       'wsrep_retry_autocommit'        => '1',
155       'wsrep_auto_increment_control'  => '1',
156       'wsrep_drupal_282555_workaround'=> '0',
157       'wsrep_causal_reads'            => '0',
158       'wsrep_sst_method'              => 'rsync',
159       'wsrep_provider_options'        => "gmcast.listen_addr=tcp://[${mysql_bind_host}]:4567;",
160     },
161   }
162
163   class { '::mysql::server':
164     create_root_user        => false,
165     create_root_my_cnf      => false,
166     config_file             => $mysql_config_file,
167     override_options        => $mysqld_options,
168     remove_default_accounts => $pacemaker_master,
169     service_manage          => false,
170     service_enabled         => false,
171   }
172
173 }
174
175 if hiera('step') >= 2 {
176
177   # NOTE(gfidente): the following vars are needed on all nodes so they
178   # need to stay out of pacemaker_master conditional.
179   # The addresses mangling will hopefully go away when we'll be able to
180   # configure the connection string via hostnames, until then, we need to pass
181   # the list of IPv6 addresses *with* port and without the brackets as 'members'
182   # argument for the 'mongodb_replset' resource.
183   if str2bool(hiera('mongodb::server::ipv6', false)) {
184     $mongo_node_ips_with_port_prefixed = prefix(hiera('mongo_node_ips'), '[')
185     $mongo_node_ips_with_port = suffix($mongo_node_ips_with_port_prefixed, ']:27017')
186     $mongo_node_ips_with_port_nobr = suffix(hiera('mongo_node_ips'), ':27017')
187   } else {
188     $mongo_node_ips_with_port = suffix(hiera('mongo_node_ips'), ':27017')
189     $mongo_node_ips_with_port_nobr = suffix(hiera('mongo_node_ips'), ':27017')
190   }
191   $mongodb_replset = hiera('mongodb::server::replset')
192
193   if $pacemaker_master {
194
195     include ::pacemaker::resource_defaults
196
197     # Create an openstack-core dummy resource. See RHBZ 1290121
198     pacemaker::resource::ocf { 'openstack-core':
199       ocf_agent_name => 'heartbeat:Dummy',
200       clone_params   => true,
201     }
202
203     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
204       pacemaker::resource::service { $::mongodb::params::service_name :
205         op_params    => 'start timeout=370s stop timeout=200s',
206         clone_params => true,
207         require      => Class['::mongodb::server'],
208       }
209       # NOTE (spredzy) : The replset can only be run
210       # once all the nodes have joined the cluster.
211       mongodb_conn_validator { $mongo_node_ips_with_port :
212         timeout => '600',
213         require => Pacemaker::Resource::Service[$::mongodb::params::service_name],
214         before  => Mongodb_replset[$mongodb_replset],
215       }
216       mongodb_replset { $mongodb_replset :
217         members => $mongo_node_ips_with_port_nobr,
218       }
219     }
220
221     pacemaker::resource::ocf { 'galera' :
222       ocf_agent_name  => 'heartbeat:galera',
223       op_params       => 'promote timeout=300s on-fail=block',
224       master_params   => '',
225       meta_params     => "master-max=${galera_nodes_count} ordered=true",
226       resource_params => "additional_parameters='--open-files-limit=16384' enable_creation=true wsrep_cluster_address='gcomm://${galera_nodes}'",
227       require         => Class['::mysql::server'],
228       before          => Exec['galera-ready'],
229     }
230
231     pacemaker::resource::ocf { 'redis':
232       ocf_agent_name  => 'heartbeat:redis',
233       master_params   => '',
234       meta_params     => 'notify=true ordered=true interleave=true',
235       resource_params => 'wait_last_known_master=true',
236       require         => Class['::redis'],
237     }
238
239   }
240   $mysql_root_password = hiera('mysql::server::root_password')
241   $mysql_clustercheck_password = hiera('mysql_clustercheck_password')
242   # This step is to create a sysconfig clustercheck file with the root user and empty password
243   # on the first install only (because later on the clustercheck db user will be used)
244   # We are using exec and not file in order to not have duplicate definition errors in puppet
245   # when we later set the the file to contain the clustercheck data
246   exec { 'create-root-sysconfig-clustercheck':
247     command => "/bin/echo 'MYSQL_USERNAME=root\nMYSQL_PASSWORD=\'\'\nMYSQL_HOST=localhost\n' > /etc/sysconfig/clustercheck",
248     unless  => '/bin/test -e /etc/sysconfig/clustercheck && grep -q clustercheck /etc/sysconfig/clustercheck',
249   }
250
251   exec { 'galera-ready' :
252     command     => '/usr/bin/clustercheck >/dev/null',
253     timeout     => 30,
254     tries       => 180,
255     try_sleep   => 10,
256     environment => ['AVAILABLE_WHEN_READONLY=0'],
257     require     => Exec['create-root-sysconfig-clustercheck'],
258   }
259
260   xinetd::service { 'galera-monitor' :
261     port           => '9200',
262     server         => '/usr/bin/clustercheck',
263     per_source     => 'UNLIMITED',
264     log_on_success => '',
265     log_on_failure => 'HOST',
266     flags          => 'REUSE',
267     service_type   => 'UNLISTED',
268     user           => 'root',
269     group          => 'root',
270     require        => Exec['create-root-sysconfig-clustercheck'],
271   }
272   # We add a clustercheck db user and we will switch /etc/sysconfig/clustercheck
273   # to it in a later step. We do this only on one node as it will replicate on
274   # the other members. We also make sure that the permissions are the minimum necessary
275   if $pacemaker_master {
276     mysql_user { 'clustercheck@localhost':
277       ensure        => 'present',
278       password_hash => mysql_password($mysql_clustercheck_password),
279       require       => Exec['galera-ready'],
280     }
281     mysql_grant { 'clustercheck@localhost/*.*':
282       ensure     => 'present',
283       options    => ['GRANT'],
284       privileges => ['PROCESS'],
285       table      => '*.*',
286       user       => 'clustercheck@localhost',
287     }
288   }
289
290   # Create all the database schemas
291   if $sync_db {
292     class { '::nova::db::mysql':
293       require => Exec['galera-ready'],
294     }
295     class { '::nova::db::mysql_api':
296       require => Exec['galera-ready'],
297     }
298     class { '::neutron::db::mysql':
299       require => Exec['galera-ready'],
300     }
301     class { '::cinder::db::mysql':
302       require => Exec['galera-ready'],
303     }
304
305     if downcase(hiera('ceilometer_backend')) == 'mysql' {
306       class { '::ceilometer::db::mysql':
307         require => Exec['galera-ready'],
308       }
309     }
310
311     if downcase(hiera('gnocchi_indexer_backend')) == 'mysql' {
312       class { '::gnocchi::db::mysql':
313         require => Exec['galera-ready'],
314       }
315     }
316     class { '::sahara::db::mysql':
317       require       => Exec['galera-ready'],
318     }
319   }
320
321   # pre-install swift here so we can build rings
322   include ::swift
323
324   # Ceph
325   $enable_ceph = hiera('ceph_storage_count', 0) > 0 or hiera('enable_ceph_storage', false)
326
327   if $enable_ceph {
328     $mon_initial_members = downcase(hiera('ceph_mon_initial_members'))
329     if str2bool(hiera('ceph_ipv6', false)) {
330       $mon_host = hiera('ceph_mon_host_v6')
331     } else {
332       $mon_host = hiera('ceph_mon_host')
333     }
334     class { '::ceph::profile::params':
335       mon_initial_members => $mon_initial_members,
336       mon_host            => $mon_host,
337     }
338     include ::ceph::conf
339     include ::ceph::profile::mon
340   }
341
342   if str2bool(hiera('enable_ceph_storage', false)) {
343     if str2bool(hiera('ceph_osd_selinux_permissive', true)) {
344       exec { 'set selinux to permissive on boot':
345         command => "sed -ie 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config",
346         onlyif  => "test -f /etc/selinux/config && ! grep '^SELINUX=permissive' /etc/selinux/config",
347         path    => ['/usr/bin', '/usr/sbin'],
348       }
349
350       exec { 'set selinux to permissive':
351         command => 'setenforce 0',
352         onlyif  => "which setenforce && getenforce | grep -i 'enforcing'",
353         path    => ['/usr/bin', '/usr/sbin'],
354       } -> Class['ceph::profile::osd']
355     }
356
357     include ::ceph::conf
358     include ::ceph::profile::osd
359   }
360
361   if str2bool(hiera('enable_external_ceph', false)) {
362     if str2bool(hiera('ceph_ipv6', false)) {
363       $mon_host = hiera('ceph_mon_host_v6')
364     } else {
365       $mon_host = hiera('ceph_mon_host')
366     }
367     class { '::ceph::profile::params':
368       mon_host            => $mon_host,
369     }
370     include ::ceph::conf
371     include ::ceph::profile::client
372   }
373
374
375 } #END STEP 2
376
377 if hiera('step') >= 4 or ( hiera('step') >= 3 and $sync_db ) {
378   # At this stage we are guaranteed that the clustercheck db user exists
379   # so we switch the resource agent to use it.
380   file { '/etc/sysconfig/clustercheck' :
381     ensure  => file,
382     mode    => '0600',
383     owner   => 'root',
384     group   => 'root',
385     content => "MYSQL_USERNAME=clustercheck\n
386 MYSQL_PASSWORD='${mysql_clustercheck_password}'\n
387 MYSQL_HOST=localhost\n",
388   }
389
390   $nova_ipv6 = hiera('nova::use_ipv6', false)
391   if $nova_ipv6 {
392     $memcached_servers = suffix(hiera('memcache_node_ips_v6'), ':11211')
393   } else {
394     $memcached_servers = suffix(hiera('memcache_node_ips'), ':11211')
395   }
396
397   class { '::nova' :
398     memcached_servers => $memcached_servers
399   }
400
401   include ::nova::config
402
403   class { '::nova::api' :
404     sync_db        => $sync_db,
405     sync_db_api    => $sync_db,
406     manage_service => false,
407     enabled        => false,
408   }
409   class { '::nova::cert' :
410     manage_service => false,
411     enabled        => false,
412   }
413   class { '::nova::conductor' :
414     manage_service => false,
415     enabled        => false,
416   }
417   class { '::nova::consoleauth' :
418     manage_service => false,
419     enabled        => false,
420   }
421   class { '::nova::vncproxy' :
422     manage_service => false,
423     enabled        => false,
424   }
425   include ::nova::scheduler::filter
426   class { '::nova::scheduler' :
427     manage_service => false,
428     enabled        => false,
429   }
430   include ::nova::network::neutron
431
432   if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
433
434     # TODO(devvesa) provide non-controller ips for these services
435     $zookeeper_node_ips = hiera('neutron_api_node_ips')
436     $cassandra_node_ips = hiera('neutron_api_node_ips')
437
438     # Run zookeeper in the controller if configured
439     if hiera('enable_zookeeper_on_controller') {
440       class {'::tripleo::cluster::zookeeper':
441         zookeeper_server_ips => $zookeeper_node_ips,
442         # TODO: create a 'bind' hiera key for zookeeper
443         zookeeper_client_ip  => hiera('neutron::bind_host'),
444         zookeeper_hostnames  => split(hiera('controller_node_names'), ',')
445       }
446     }
447
448     # Run cassandra in the controller if configured
449     if hiera('enable_cassandra_on_controller') {
450       class {'::tripleo::cluster::cassandra':
451         cassandra_servers => $cassandra_node_ips,
452         # TODO: create a 'bind' hiera key for cassandra
453         cassandra_ip      => hiera('neutron::bind_host'),
454       }
455     }
456
457     class {'::tripleo::network::midonet::agent':
458       zookeeper_servers => $zookeeper_node_ips,
459       cassandra_seeds   => $cassandra_node_ips
460     }
461
462     class {'::tripleo::network::midonet::api':
463       zookeeper_servers    => $zookeeper_node_ips,
464       vip                  => hiera('tripleo::loadbalancer::public_virtual_ip'),
465       keystone_ip          => hiera('tripleo::loadbalancer::public_virtual_ip'),
466       keystone_admin_token => hiera('keystone::admin_token'),
467       # TODO: create a 'bind' hiera key for api
468       bind_address         => hiera('neutron::bind_host'),
469       admin_password       => hiera('admin_password')
470     }
471
472     # Configure Neutron
473     class {'::neutron':
474       service_plugins => []
475     }
476
477   }
478   else {
479     # Neutron class definitions
480     include ::neutron
481   }
482
483   include ::neutron::config
484   class { '::neutron::server' :
485     sync_db        => $sync_db,
486     manage_service => false,
487     enabled        => false,
488   }
489   include ::neutron::server::notifications
490   if  hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
491     include ::neutron::plugins::nuage
492   }
493   if  hiera('neutron::core_plugin') == 'neutron_plugin_contrail.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCoreV2' {
494     include ::neutron::plugins::opencontrail
495   }
496   if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
497     class {'::neutron::plugins::midonet':
498       midonet_api_ip    => hiera('tripleo::loadbalancer::public_virtual_ip'),
499       keystone_tenant   => hiera('neutron::server::auth_tenant'),
500       keystone_password => hiera('neutron::server::auth_password')
501     }
502   }
503   if hiera('neutron::core_plugin') == 'networking_plumgrid.neutron.plugins.plugin.NeutronPluginPLUMgridV2' {
504     class { '::neutron::plugins::plumgrid' :
505       connection                   => hiera('neutron::server::database_connection'),
506       controller_priv_host         => hiera('keystone_admin_api_vip'),
507       admin_password               => hiera('admin_password'),
508       metadata_proxy_shared_secret => hiera('nova::api::neutron_metadata_proxy_shared_secret'),
509     }
510   }
511   include ::neutron::plugins::ml2
512   class { '::neutron::agents::ml2::ovs':
513     manage_service => false,
514     enabled        => false,
515   }
516
517   if 'cisco_ucsm' in hiera('neutron::plugins::ml2::mechanism_drivers') {
518     include ::neutron::plugins::ml2::cisco::ucsm
519   }
520   if 'cisco_nexus' in hiera('neutron::plugins::ml2::mechanism_drivers') {
521     include ::neutron::plugins::ml2::cisco::nexus
522     include ::neutron::plugins::ml2::cisco::type_nexus_vxlan
523   }
524   if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
525     include ::neutron::plugins::ml2::cisco::nexus1000v
526
527     class { '::neutron::agents::n1kv_vem':
528       n1kv_source  => hiera('n1kv_vem_source', undef),
529       n1kv_version => hiera('n1kv_vem_version', undef),
530     }
531
532     class { '::n1k_vsm':
533       n1kv_source  => hiera('n1kv_vsm_source', undef),
534       n1kv_version => hiera('n1kv_vsm_version', undef),
535     }
536   }
537
538   if 'bsn_ml2' in hiera('neutron::plugins::ml2::mechanism_drivers') {
539     include ::neutron::plugins::ml2::bigswitch::restproxy
540     include ::neutron::agents::bigswitch
541   }
542
543   include ::cinder
544   include ::cinder::config
545   include ::tripleo::ssl::cinder_config
546   class { '::cinder::api':
547     sync_db        => $sync_db,
548     manage_service => false,
549     enabled        => false,
550   }
551   class { '::cinder::scheduler' :
552     manage_service => false,
553     enabled        => false,
554   }
555   class { '::cinder::volume' :
556     manage_service => false,
557     enabled        => false,
558   }
559   include ::cinder::glance
560   include ::cinder::ceilometer
561   class { '::cinder::setup_test_volume':
562     size => join([hiera('cinder_lvm_loop_device_size'), 'M']),
563   }
564
565   $cinder_enable_iscsi = hiera('cinder_enable_iscsi_backend', true)
566   if $cinder_enable_iscsi {
567     $cinder_iscsi_backend = 'tripleo_iscsi'
568
569     cinder::backend::iscsi { $cinder_iscsi_backend :
570       iscsi_ip_address => hiera('cinder_iscsi_ip_address'),
571       iscsi_helper     => hiera('cinder_iscsi_helper'),
572     }
573   }
574
575   if $enable_ceph {
576
577     $ceph_pools = hiera('ceph_pools')
578     ceph::pool { $ceph_pools :
579       pg_num  => hiera('ceph::profile::params::osd_pool_default_pg_num'),
580       pgp_num => hiera('ceph::profile::params::osd_pool_default_pgp_num'),
581       size    => hiera('ceph::profile::params::osd_pool_default_size'),
582     }
583
584     $cinder_pool_requires = [Ceph::Pool[hiera('cinder_rbd_pool_name')]]
585
586   } else {
587     $cinder_pool_requires = []
588   }
589
590   if hiera('cinder_enable_rbd_backend', false) {
591     $cinder_rbd_backend = 'tripleo_ceph'
592
593     cinder::backend::rbd { $cinder_rbd_backend :
594       backend_host    => hiera('cinder::host'),
595       rbd_pool        => hiera('cinder_rbd_pool_name'),
596       rbd_user        => hiera('ceph_client_user_name'),
597       rbd_secret_uuid => hiera('ceph::profile::params::fsid'),
598       require         => $cinder_pool_requires,
599     }
600   }
601
602   if hiera('cinder_enable_eqlx_backend', false) {
603     $cinder_eqlx_backend = hiera('cinder::backend::eqlx::volume_backend_name')
604
605     cinder::backend::eqlx { $cinder_eqlx_backend :
606       volume_backend_name => hiera('cinder::backend::eqlx::volume_backend_name', undef),
607       san_ip              => hiera('cinder::backend::eqlx::san_ip', undef),
608       san_login           => hiera('cinder::backend::eqlx::san_login', undef),
609       san_password        => hiera('cinder::backend::eqlx::san_password', undef),
610       san_thin_provision  => hiera('cinder::backend::eqlx::san_thin_provision', undef),
611       eqlx_group_name     => hiera('cinder::backend::eqlx::eqlx_group_name', undef),
612       eqlx_pool           => hiera('cinder::backend::eqlx::eqlx_pool', undef),
613       eqlx_use_chap       => hiera('cinder::backend::eqlx::eqlx_use_chap', undef),
614       eqlx_chap_login     => hiera('cinder::backend::eqlx::eqlx_chap_login', undef),
615       eqlx_chap_password  => hiera('cinder::backend::eqlx::eqlx_san_password', undef),
616     }
617   }
618
619   if hiera('cinder_enable_dellsc_backend', false) {
620     $cinder_dellsc_backend = hiera('cinder::backend::dellsc_iscsi::volume_backend_name')
621
622     cinder::backend::dellsc_iscsi{ $cinder_dellsc_backend :
623       volume_backend_name   => hiera('cinder::backend::dellsc_iscsi::volume_backend_name', undef),
624       san_ip                => hiera('cinder::backend::dellsc_iscsi::san_ip', undef),
625       san_login             => hiera('cinder::backend::dellsc_iscsi::san_login', undef),
626       san_password          => hiera('cinder::backend::dellsc_iscsi::san_password', undef),
627       dell_sc_ssn           => hiera('cinder::backend::dellsc_iscsi::dell_sc_ssn', undef),
628       iscsi_ip_address      => hiera('cinder::backend::dellsc_iscsi::iscsi_ip_address', undef),
629       iscsi_port            => hiera('cinder::backend::dellsc_iscsi::iscsi_port', undef),
630       dell_sc_api_port      => hiera('cinder::backend::dellsc_iscsi::dell_sc_api_port', undef),
631       dell_sc_server_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_server_folder', undef),
632       dell_sc_volume_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_volume_folder', undef),
633     }
634   }
635
636   if hiera('cinder_enable_netapp_backend', false) {
637     $cinder_netapp_backend = hiera('cinder::backend::netapp::title')
638
639     if hiera('cinder::backend::netapp::nfs_shares', undef) {
640       $cinder_netapp_nfs_shares = split(hiera('cinder::backend::netapp::nfs_shares', undef), ',')
641     }
642
643     cinder::backend::netapp { $cinder_netapp_backend :
644       netapp_login                 => hiera('cinder::backend::netapp::netapp_login', undef),
645       netapp_password              => hiera('cinder::backend::netapp::netapp_password', undef),
646       netapp_server_hostname       => hiera('cinder::backend::netapp::netapp_server_hostname', undef),
647       netapp_server_port           => hiera('cinder::backend::netapp::netapp_server_port', undef),
648       netapp_size_multiplier       => hiera('cinder::backend::netapp::netapp_size_multiplier', undef),
649       netapp_storage_family        => hiera('cinder::backend::netapp::netapp_storage_family', undef),
650       netapp_storage_protocol      => hiera('cinder::backend::netapp::netapp_storage_protocol', undef),
651       netapp_transport_type        => hiera('cinder::backend::netapp::netapp_transport_type', undef),
652       netapp_vfiler                => hiera('cinder::backend::netapp::netapp_vfiler', undef),
653       netapp_volume_list           => hiera('cinder::backend::netapp::netapp_volume_list', undef),
654       netapp_vserver               => hiera('cinder::backend::netapp::netapp_vserver', undef),
655       netapp_partner_backend_name  => hiera('cinder::backend::netapp::netapp_partner_backend_name', undef),
656       nfs_shares                   => $cinder_netapp_nfs_shares,
657       nfs_shares_config            => hiera('cinder::backend::netapp::nfs_shares_config', undef),
658       netapp_copyoffload_tool_path => hiera('cinder::backend::netapp::netapp_copyoffload_tool_path', undef),
659       netapp_controller_ips        => hiera('cinder::backend::netapp::netapp_controller_ips', undef),
660       netapp_sa_password           => hiera('cinder::backend::netapp::netapp_sa_password', undef),
661       netapp_storage_pools         => hiera('cinder::backend::netapp::netapp_storage_pools', undef),
662       netapp_eseries_host_type     => hiera('cinder::backend::netapp::netapp_eseries_host_type', undef),
663       netapp_webservice_path       => hiera('cinder::backend::netapp::netapp_webservice_path', undef),
664     }
665   }
666
667   if hiera('cinder_enable_nfs_backend', false) {
668     $cinder_nfs_backend = 'tripleo_nfs'
669
670     if str2bool($::selinux) {
671       selboolean { 'virt_use_nfs':
672         value      => on,
673         persistent => true,
674       } -> Package['nfs-utils']
675     }
676
677     package { 'nfs-utils': } ->
678     cinder::backend::nfs { $cinder_nfs_backend:
679       nfs_servers       => hiera('cinder_nfs_servers'),
680       nfs_mount_options => hiera('cinder_nfs_mount_options',''),
681       nfs_shares_config => '/etc/cinder/shares-nfs.conf',
682     }
683   }
684
685   $cinder_enabled_backends = delete_undef_values([$cinder_iscsi_backend, $cinder_rbd_backend, $cinder_eqlx_backend, $cinder_dellsc_backend, $cinder_netapp_backend, $cinder_nfs_backend])
686   class { '::cinder::backends' :
687     enabled_backends => union($cinder_enabled_backends, hiera('cinder_user_enabled_backends')),
688   }
689
690   class { '::sahara':
691     sync_db => $sync_db,
692   }
693   class { '::sahara::service::api':
694     manage_service => false,
695     enabled        => false,
696   }
697   class { '::sahara::service::engine':
698     manage_service => false,
699     enabled        => false,
700   }
701
702   # swift proxy
703   class { '::swift::proxy' :
704     manage_service => $non_pcmk_start,
705     enabled        => $non_pcmk_start,
706   }
707   include ::swift::proxy::proxy_logging
708   include ::swift::proxy::healthcheck
709   include ::swift::proxy::cache
710   include ::swift::proxy::keystone
711   include ::swift::proxy::authtoken
712   include ::swift::proxy::staticweb
713   include ::swift::proxy::ratelimit
714   include ::swift::proxy::catch_errors
715   include ::swift::proxy::tempurl
716   include ::swift::proxy::formpost
717
718   # swift storage
719   if str2bool(hiera('enable_swift_storage', true)) {
720     class {'::swift::storage::all':
721       mount_check => str2bool(hiera('swift_mount_check')),
722     }
723     class {'::swift::storage::account':
724       manage_service => $non_pcmk_start,
725       enabled        => $non_pcmk_start,
726     }
727     class {'::swift::storage::container':
728       manage_service => $non_pcmk_start,
729       enabled        => $non_pcmk_start,
730     }
731     class {'::swift::storage::object':
732       manage_service => $non_pcmk_start,
733       enabled        => $non_pcmk_start,
734     }
735     if(!defined(File['/srv/node'])) {
736       file { '/srv/node':
737         ensure  => directory,
738         owner   => 'swift',
739         group   => 'swift',
740         require => Package['openstack-swift'],
741       }
742     }
743     $swift_components = ['account', 'container', 'object']
744     swift::storage::filter::recon { $swift_components : }
745     swift::storage::filter::healthcheck { $swift_components : }
746   }
747
748   # Ceilometer
749   case downcase(hiera('ceilometer_backend')) {
750     /mysql/: {
751       $ceilometer_database_connection = hiera('ceilometer_mysql_conn_string')
752     }
753     default: {
754       $mongo_node_string = join($mongo_node_ips_with_port, ',')
755       $ceilometer_database_connection = "mongodb://${mongo_node_string}/ceilometer?replicaSet=${mongodb_replset}"
756     }
757   }
758   include ::ceilometer
759   include ::ceilometer::config
760   class { '::ceilometer::api' :
761     manage_service => false,
762     enabled        => false,
763   }
764   class { '::ceilometer::agent::notification' :
765     manage_service => false,
766     enabled        => false,
767   }
768   class { '::ceilometer::agent::central' :
769     manage_service => false,
770     enabled        => false,
771   }
772   class { '::ceilometer::collector' :
773     manage_service => false,
774     enabled        => false,
775   }
776   include ::ceilometer::expirer
777   class { '::ceilometer::db' :
778     database_connection => $ceilometer_database_connection,
779     sync_db             => $sync_db,
780   }
781   include ::ceilometer::agent::auth
782   include ::ceilometer::dispatcher::gnocchi
783
784   Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" }
785
786   # httpd/apache and horizon
787   # NOTE(gfidente): server-status can be consumed by the pacemaker resource agent
788   class { '::apache' :
789     service_enable => false,
790     # service_manage => false, # <-- not supported with horizon&apache mod_wsgi?
791   }
792   include ::apache::mod::remoteip
793   include ::apache::mod::status
794   if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
795     $_profile_support = 'cisco'
796   } else {
797     $_profile_support = 'None'
798   }
799   $neutron_options   = {'profile_support' => $_profile_support }
800
801   $memcached_ipv6 = hiera('memcached_ipv6', false)
802   if $memcached_ipv6 {
803     $horizon_memcached_servers = hiera('memcache_node_ips_v6', '[::1]')
804   } else {
805     $horizon_memcached_servers = hiera('memcache_node_ips', '127.0.0.1')
806   }
807
808   class { '::horizon':
809     cache_server_ip => $horizon_memcached_servers,
810     neutron_options => $neutron_options,
811   }
812
813   # Aodh
814   class { '::aodh' :
815     database_connection => $ceilometer_database_connection,
816   }
817   include ::aodh::config
818   include ::aodh::auth
819   include ::aodh::client
820   include ::aodh::wsgi::apache
821   class { '::aodh::api':
822     manage_service => false,
823     enabled        => false,
824     service_name   => 'httpd',
825   }
826   class { '::aodh::evaluator':
827     manage_service => false,
828     enabled        => false,
829   }
830   class { '::aodh::notifier':
831     manage_service => false,
832     enabled        => false,
833   }
834   class { '::aodh::listener':
835     manage_service => false,
836     enabled        => false,
837   }
838
839   # Gnocchi
840   $gnocchi_database_connection = hiera('gnocchi_mysql_conn_string')
841   include ::gnocchi::client
842   if $sync_db {
843     include ::gnocchi::db::sync
844   }
845   include ::gnocchi::storage
846   $gnocchi_backend = downcase(hiera('gnocchi_backend', 'swift'))
847   case $gnocchi_backend {
848       'swift': { include ::gnocchi::storage::swift }
849       'file': { include ::gnocchi::storage::file }
850       'rbd': { include ::gnocchi::storage::ceph }
851       default: { fail('Unrecognized gnocchi_backend parameter.') }
852   }
853   class { '::gnocchi':
854     database_connection => $gnocchi_database_connection,
855   }
856   class { '::gnocchi::api' :
857     manage_service => false,
858     enabled        => false,
859     service_name   => 'httpd',
860   }
861   class { '::gnocchi::wsgi::apache' :
862     ssl => false,
863   }
864   class { '::gnocchi::metricd' :
865     manage_service => false,
866     enabled        => false,
867   }
868   class { '::gnocchi::statsd' :
869     manage_service => false,
870     enabled        => false,
871   }
872
873   $snmpd_user = hiera('snmpd_readonly_user_name')
874   snmp::snmpv3_user { $snmpd_user:
875     authtype => 'MD5',
876     authpass => hiera('snmpd_readonly_user_password'),
877   }
878   class { '::snmp':
879     agentaddress => ['udp:161','udp6:[::1]:161'],
880     snmpd_config => [ join(['createUser ', hiera('snmpd_readonly_user_name'), ' MD5 "', hiera('snmpd_readonly_user_password'), '"']), join(['rouser ', hiera('snmpd_readonly_user_name')]), 'proc  cron', 'includeAllDisks  10%', 'master agentx', 'trapsink localhost public', 'iquerySecName internalUser', 'rouser internalUser', 'defaultMonitors yes', 'linkUpDownNotifications yes' ],
881   }
882
883   hiera_include('controller_classes')
884
885 } #END STEP 4
886
887 if hiera('step') >= 5 {
888   # We now make sure that the root db password is set to a random one
889   # At first installation /root/.my.cnf will be empty and we connect without a root
890   # password. On second runs or updates /root/.my.cnf will already be populated
891   # with proper credentials. This step happens on every node because this sql
892   # statement does not automatically replicate across nodes.
893   exec { 'galera-set-root-password':
894     command => "/bin/touch /root/.my.cnf && /bin/echo \"UPDATE mysql.user SET Password = PASSWORD('${mysql_root_password}') WHERE user = 'root'; flush privileges;\" | /bin/mysql --defaults-extra-file=/root/.my.cnf -u root",
895   }
896   file { '/root/.my.cnf' :
897     ensure  => file,
898     mode    => '0600',
899     owner   => 'root',
900     group   => 'root',
901     content => "[client]
902 user=root
903 password=\"${mysql_root_password}\"
904
905 [mysql]
906 user=root
907 password=\"${mysql_root_password}\"",
908     require => Exec['galera-set-root-password'],
909   }
910
911   $nova_enable_db_purge = hiera('nova_enable_db_purge', true)
912   $cinder_enable_db_purge = hiera('cinder_enable_db_purge', true)
913
914   if $nova_enable_db_purge {
915     include ::nova::cron::archive_deleted_rows
916   }
917   if $cinder_enable_db_purge {
918     include ::cinder::cron::db_purge
919   }
920
921   if $pacemaker_master {
922
923     pacemaker::constraint::base { 'openstack-core-then-httpd-constraint':
924       constraint_type => 'order',
925       first_resource  => 'openstack-core-clone',
926       second_resource => "${::apache::params::service_name}-clone",
927       first_action    => 'start',
928       second_action   => 'start',
929       require         => [Pacemaker::Resource::Service[$::apache::params::service_name],
930                           Pacemaker::Resource::Ocf['openstack-core']],
931     }
932     pacemaker::constraint::base { 'galera-then-openstack-core-constraint':
933       constraint_type => 'order',
934       first_resource  => 'galera-master',
935       second_resource => 'openstack-core-clone',
936       first_action    => 'promote',
937       second_action   => 'start',
938       require         => [Pacemaker::Resource::Ocf['galera'],
939                           Pacemaker::Resource::Ocf['openstack-core']],
940     }
941
942     # Cinder
943     pacemaker::resource::service { $::cinder::params::api_service :
944       clone_params => 'interleave=true',
945       require      => Pacemaker::Resource::Ocf['openstack-core'],
946     }
947     pacemaker::resource::service { $::cinder::params::scheduler_service :
948       clone_params => 'interleave=true',
949     }
950     pacemaker::resource::service { $::cinder::params::volume_service : }
951
952     pacemaker::constraint::base { 'keystone-then-cinder-api-constraint':
953       constraint_type => 'order',
954       first_resource  => 'openstack-core-clone',
955       second_resource => "${::cinder::params::api_service}-clone",
956       first_action    => 'start',
957       second_action   => 'start',
958       require         => [Pacemaker::Resource::Ocf['openstack-core'],
959                           Pacemaker::Resource::Service[$::cinder::params::api_service]],
960     }
961     pacemaker::constraint::base { 'cinder-api-then-cinder-scheduler-constraint':
962       constraint_type => 'order',
963       first_resource  => "${::cinder::params::api_service}-clone",
964       second_resource => "${::cinder::params::scheduler_service}-clone",
965       first_action    => 'start',
966       second_action   => 'start',
967       require         => [Pacemaker::Resource::Service[$::cinder::params::api_service],
968                           Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
969     }
970     pacemaker::constraint::colocation { 'cinder-scheduler-with-cinder-api-colocation':
971       source  => "${::cinder::params::scheduler_service}-clone",
972       target  => "${::cinder::params::api_service}-clone",
973       score   => 'INFINITY',
974       require => [Pacemaker::Resource::Service[$::cinder::params::api_service],
975                   Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
976     }
977     pacemaker::constraint::base { 'cinder-scheduler-then-cinder-volume-constraint':
978       constraint_type => 'order',
979       first_resource  => "${::cinder::params::scheduler_service}-clone",
980       second_resource => $::cinder::params::volume_service,
981       first_action    => 'start',
982       second_action   => 'start',
983       require         => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
984                           Pacemaker::Resource::Service[$::cinder::params::volume_service]],
985     }
986     pacemaker::constraint::colocation { 'cinder-volume-with-cinder-scheduler-colocation':
987       source  => $::cinder::params::volume_service,
988       target  => "${::cinder::params::scheduler_service}-clone",
989       score   => 'INFINITY',
990       require => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
991                   Pacemaker::Resource::Service[$::cinder::params::volume_service]],
992     }
993
994     # Sahara
995     pacemaker::resource::service { $::sahara::params::api_service_name :
996       clone_params => 'interleave=true',
997       require      => Pacemaker::Resource::Ocf['openstack-core'],
998     }
999     pacemaker::resource::service { $::sahara::params::engine_service_name :
1000       clone_params => 'interleave=true',
1001     }
1002     pacemaker::constraint::base { 'keystone-then-sahara-api-constraint':
1003       constraint_type => 'order',
1004       first_resource  => 'openstack-core-clone',
1005       second_resource => "${::sahara::params::api_service_name}-clone",
1006       first_action    => 'start',
1007       second_action   => 'start',
1008       require         => [Pacemaker::Resource::Service[$::sahara::params::api_service_name],
1009                           Pacemaker::Resource::Ocf['openstack-core']],
1010     }
1011     pacemaker::constraint::base { 'sahara-api-then-sahara-engine-constraint':
1012       constraint_type => 'order',
1013       first_resource  => "${::sahara::params::api_service_name}-clone",
1014       second_resource => "${::sahara::params::engine_service_name}-clone",
1015       first_action    => 'start',
1016       second_action   => 'start',
1017       require         => [Pacemaker::Resource::Service[$::sahara::params::api_service_name],
1018                           Pacemaker::Resource::Service[$::sahara::params::engine_service_name]],
1019     }
1020
1021     if hiera('neutron::enable_ovs_agent', true) {
1022       pacemaker::resource::service { $::neutron::params::ovs_agent_service:
1023         clone_params => 'interleave=true',
1024       }
1025     }
1026     if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
1027       pacemaker::resource::service {'tomcat':
1028         clone_params => 'interleave=true',
1029       }
1030     }
1031     if hiera('neutron::enable_ovs_agent', true) {
1032       pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
1033         ocf_agent_name => 'neutron:OVSCleanup',
1034         clone_params   => 'interleave=true',
1035       }
1036       pacemaker::resource::ocf { 'neutron-netns-cleanup':
1037         ocf_agent_name => 'neutron:NetnsCleanup',
1038         clone_params   => 'interleave=true',
1039       }
1040
1041       # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
1042       pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
1043         constraint_type => 'order',
1044         first_resource  => "${::neutron::params::ovs_cleanup_service}-clone",
1045         second_resource => 'neutron-netns-cleanup-clone',
1046         first_action    => 'start',
1047         second_action   => 'start',
1048         require         => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1049                             Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1050       }
1051       pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
1052         source  => 'neutron-netns-cleanup-clone',
1053         target  => "${::neutron::params::ovs_cleanup_service}-clone",
1054         score   => 'INFINITY',
1055         require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1056                     Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1057       }
1058       pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
1059         constraint_type => 'order',
1060         first_resource  => 'neutron-netns-cleanup-clone',
1061         second_resource => "${::neutron::params::ovs_agent_service}-clone",
1062         first_action    => 'start',
1063         second_action   => 'start',
1064         require         => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1065                             Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1066       }
1067       pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
1068         source  => "${::neutron::params::ovs_agent_service}-clone",
1069         target  => 'neutron-netns-cleanup-clone',
1070         score   => 'INFINITY',
1071         require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1072                     Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1073       }
1074     }
1075     if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
1076       #midonet-chain chain keystone-->neutron-server-->dhcp-->metadata->tomcat
1077       pacemaker::constraint::base { 'neutron-server-to-dhcp-agent-constraint':
1078         constraint_type => 'order',
1079         first_resource  => "${::neutron::params::server_service}-clone",
1080         second_resource => "${::neutron::params::dhcp_agent_service}-clone",
1081         first_action    => 'start',
1082         second_action   => 'start',
1083         require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
1084                             Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1085       }
1086       pacemaker::constraint::base { 'neutron-dhcp-agent-to-metadata-agent-constraint':
1087         constraint_type => 'order',
1088         first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
1089         second_resource => "${::neutron::params::metadata_agent_service}-clone",
1090         first_action    => 'start',
1091         second_action   => 'start',
1092         require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1093                             Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1094       }
1095       pacemaker::constraint::base { 'neutron-metadata-agent-to-tomcat-constraint':
1096         constraint_type => 'order',
1097         first_resource  => "${::neutron::params::metadata_agent_service}-clone",
1098         second_resource => 'tomcat-clone',
1099         first_action    => 'start',
1100         second_action   => 'start',
1101         require         => [Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service],
1102                             Pacemaker::Resource::Service['tomcat']],
1103       }
1104       pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-metadata-agent-colocation':
1105         source  => "${::neutron::params::metadata_agent_service}-clone",
1106         target  => "${::neutron::params::dhcp_agent_service}-clone",
1107         score   => 'INFINITY',
1108         require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1109                     Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1110       }
1111     }
1112
1113     # Nova
1114     pacemaker::resource::service { $::nova::params::api_service_name :
1115       clone_params => 'interleave=true',
1116     }
1117     pacemaker::resource::service { $::nova::params::conductor_service_name :
1118       clone_params => 'interleave=true',
1119     }
1120     pacemaker::resource::service { $::nova::params::consoleauth_service_name :
1121       clone_params => 'interleave=true',
1122       require      => Pacemaker::Resource::Ocf['openstack-core'],
1123     }
1124     pacemaker::resource::service { $::nova::params::vncproxy_service_name :
1125       clone_params => 'interleave=true',
1126     }
1127     pacemaker::resource::service { $::nova::params::scheduler_service_name :
1128       clone_params => 'interleave=true',
1129     }
1130
1131     pacemaker::constraint::base { 'keystone-then-nova-consoleauth-constraint':
1132       constraint_type => 'order',
1133       first_resource  => 'openstack-core-clone',
1134       second_resource => "${::nova::params::consoleauth_service_name}-clone",
1135       first_action    => 'start',
1136       second_action   => 'start',
1137       require         => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1138                           Pacemaker::Resource::Ocf['openstack-core']],
1139     }
1140     pacemaker::constraint::base { 'nova-consoleauth-then-nova-vncproxy-constraint':
1141       constraint_type => 'order',
1142       first_resource  => "${::nova::params::consoleauth_service_name}-clone",
1143       second_resource => "${::nova::params::vncproxy_service_name}-clone",
1144       first_action    => 'start',
1145       second_action   => 'start',
1146       require         => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1147                           Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1148     }
1149     pacemaker::constraint::colocation { 'nova-vncproxy-with-nova-consoleauth-colocation':
1150       source  => "${::nova::params::vncproxy_service_name}-clone",
1151       target  => "${::nova::params::consoleauth_service_name}-clone",
1152       score   => 'INFINITY',
1153       require => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1154                   Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1155     }
1156     pacemaker::constraint::base { 'nova-vncproxy-then-nova-api-constraint':
1157       constraint_type => 'order',
1158       first_resource  => "${::nova::params::vncproxy_service_name}-clone",
1159       second_resource => "${::nova::params::api_service_name}-clone",
1160       first_action    => 'start',
1161       second_action   => 'start',
1162       require         => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1163                           Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1164     }
1165     pacemaker::constraint::colocation { 'nova-api-with-nova-vncproxy-colocation':
1166       source  => "${::nova::params::api_service_name}-clone",
1167       target  => "${::nova::params::vncproxy_service_name}-clone",
1168       score   => 'INFINITY',
1169       require => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1170                   Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1171     }
1172     pacemaker::constraint::base { 'nova-api-then-nova-scheduler-constraint':
1173       constraint_type => 'order',
1174       first_resource  => "${::nova::params::api_service_name}-clone",
1175       second_resource => "${::nova::params::scheduler_service_name}-clone",
1176       first_action    => 'start',
1177       second_action   => 'start',
1178       require         => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1179                           Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1180     }
1181     pacemaker::constraint::colocation { 'nova-scheduler-with-nova-api-colocation':
1182       source  => "${::nova::params::scheduler_service_name}-clone",
1183       target  => "${::nova::params::api_service_name}-clone",
1184       score   => 'INFINITY',
1185       require => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1186                   Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1187     }
1188     pacemaker::constraint::base { 'nova-scheduler-then-nova-conductor-constraint':
1189       constraint_type => 'order',
1190       first_resource  => "${::nova::params::scheduler_service_name}-clone",
1191       second_resource => "${::nova::params::conductor_service_name}-clone",
1192       first_action    => 'start',
1193       second_action   => 'start',
1194       require         => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1195                           Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1196     }
1197     pacemaker::constraint::colocation { 'nova-conductor-with-nova-scheduler-colocation':
1198       source  => "${::nova::params::conductor_service_name}-clone",
1199       target  => "${::nova::params::scheduler_service_name}-clone",
1200       score   => 'INFINITY',
1201       require => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1202                   Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1203     }
1204
1205     # Ceilometer and Aodh
1206     case downcase(hiera('ceilometer_backend')) {
1207       /mysql/: {
1208         pacemaker::resource::service { $::ceilometer::params::agent_central_service_name:
1209           clone_params => 'interleave=true',
1210           require      => Pacemaker::Resource::Ocf['openstack-core'],
1211         }
1212       }
1213       default: {
1214         pacemaker::resource::service { $::ceilometer::params::agent_central_service_name:
1215           clone_params => 'interleave=true',
1216           require      => [Pacemaker::Resource::Ocf['openstack-core'],
1217                           Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1218         }
1219       }
1220     }
1221     pacemaker::resource::service { $::ceilometer::params::collector_service_name :
1222       clone_params => 'interleave=true',
1223     }
1224     pacemaker::resource::service { $::ceilometer::params::api_service_name :
1225       clone_params => 'interleave=true',
1226     }
1227     pacemaker::resource::service { $::ceilometer::params::agent_notification_service_name :
1228       clone_params => 'interleave=true',
1229     }
1230     pacemaker::resource::ocf { 'delay' :
1231       ocf_agent_name  => 'heartbeat:Delay',
1232       clone_params    => 'interleave=true',
1233       resource_params => 'startdelay=10',
1234     }
1235     # Fedora doesn't know `require-all` parameter for constraints yet
1236     if $::operatingsystem == 'Fedora' {
1237       $redis_ceilometer_constraint_params = undef
1238       $redis_aodh_constraint_params = undef
1239     } else {
1240       $redis_ceilometer_constraint_params = 'require-all=false'
1241       $redis_aodh_constraint_params = 'require-all=false'
1242     }
1243     pacemaker::constraint::base { 'redis-then-ceilometer-central-constraint':
1244       constraint_type   => 'order',
1245       first_resource    => 'redis-master',
1246       second_resource   => "${::ceilometer::params::agent_central_service_name}-clone",
1247       first_action      => 'promote',
1248       second_action     => 'start',
1249       constraint_params => $redis_ceilometer_constraint_params,
1250       require           => [Pacemaker::Resource::Ocf['redis'],
1251                             Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name]],
1252     }
1253     pacemaker::constraint::base { 'redis-then-aodh-evaluator-constraint':
1254       constraint_type   => 'order',
1255       first_resource    => 'redis-master',
1256       second_resource   => "${::aodh::params::evaluator_service_name}-clone",
1257       first_action      => 'promote',
1258       second_action     => 'start',
1259       constraint_params => $redis_aodh_constraint_params,
1260       require           => [Pacemaker::Resource::Ocf['redis'],
1261                             Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name]],
1262     }
1263     pacemaker::constraint::base { 'keystone-then-ceilometer-central-constraint':
1264       constraint_type => 'order',
1265       first_resource  => 'openstack-core-clone',
1266       second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1267       first_action    => 'start',
1268       second_action   => 'start',
1269       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1270                           Pacemaker::Resource::Ocf['openstack-core']],
1271     }
1272     pacemaker::constraint::base { 'keystone-then-ceilometer-notification-constraint':
1273       constraint_type => 'order',
1274       first_resource  => 'openstack-core-clone',
1275       second_resource => "${::ceilometer::params::agent_notification_service_name}-clone",
1276       first_action    => 'start',
1277       second_action   => 'start',
1278       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1279                           Pacemaker::Resource::Ocf['openstack-core']],
1280     }
1281     pacemaker::constraint::base { 'ceilometer-central-then-ceilometer-collector-constraint':
1282       constraint_type => 'order',
1283       first_resource  => "${::ceilometer::params::agent_central_service_name}-clone",
1284       second_resource => "${::ceilometer::params::collector_service_name}-clone",
1285       first_action    => 'start',
1286       second_action   => 'start',
1287       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1288                           Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1289     }
1290     pacemaker::constraint::base { 'ceilometer-collector-then-ceilometer-api-constraint':
1291       constraint_type => 'order',
1292       first_resource  => "${::ceilometer::params::collector_service_name}-clone",
1293       second_resource => "${::ceilometer::params::api_service_name}-clone",
1294       first_action    => 'start',
1295       second_action   => 'start',
1296       require         => [Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name],
1297                           Pacemaker::Resource::Service[$::ceilometer::params::api_service_name]],
1298     }
1299     pacemaker::constraint::colocation { 'ceilometer-api-with-ceilometer-collector-colocation':
1300       source  => "${::ceilometer::params::api_service_name}-clone",
1301       target  => "${::ceilometer::params::collector_service_name}-clone",
1302       score   => 'INFINITY',
1303       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1304                   Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1305     }
1306     pacemaker::constraint::base { 'ceilometer-api-then-ceilometer-delay-constraint':
1307       constraint_type => 'order',
1308       first_resource  => "${::ceilometer::params::api_service_name}-clone",
1309       second_resource => 'delay-clone',
1310       first_action    => 'start',
1311       second_action   => 'start',
1312       require         => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1313                           Pacemaker::Resource::Ocf['delay']],
1314     }
1315     pacemaker::constraint::colocation { 'ceilometer-delay-with-ceilometer-api-colocation':
1316       source  => 'delay-clone',
1317       target  => "${::ceilometer::params::api_service_name}-clone",
1318       score   => 'INFINITY',
1319       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1320                   Pacemaker::Resource::Ocf['delay']],
1321     }
1322     # Aodh
1323     pacemaker::resource::service { $::aodh::params::evaluator_service_name :
1324       clone_params => 'interleave=true',
1325     }
1326     pacemaker::resource::service { $::aodh::params::notifier_service_name :
1327       clone_params => 'interleave=true',
1328     }
1329     pacemaker::resource::service { $::aodh::params::listener_service_name :
1330       clone_params => 'interleave=true',
1331     }
1332     pacemaker::constraint::base { 'aodh-delay-then-aodh-evaluator-constraint':
1333       constraint_type => 'order',
1334       first_resource  => 'delay-clone',
1335       second_resource => "${::aodh::params::evaluator_service_name}-clone",
1336       first_action    => 'start',
1337       second_action   => 'start',
1338       require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1339                           Pacemaker::Resource::Ocf['delay']],
1340     }
1341     pacemaker::constraint::colocation { 'aodh-evaluator-with-aodh-delay-colocation':
1342       source  => "${::aodh::params::evaluator_service_name}-clone",
1343       target  => 'delay-clone',
1344       score   => 'INFINITY',
1345       require => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1346                   Pacemaker::Resource::Ocf['delay']],
1347     }
1348     pacemaker::constraint::base { 'aodh-evaluator-then-aodh-notifier-constraint':
1349       constraint_type => 'order',
1350       first_resource  => "${::aodh::params::evaluator_service_name}-clone",
1351       second_resource => "${::aodh::params::notifier_service_name}-clone",
1352       first_action    => 'start',
1353       second_action   => 'start',
1354       require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1355                           Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1356     }
1357     pacemaker::constraint::colocation { 'aodh-notifier-with-aodh-evaluator-colocation':
1358       source  => "${::aodh::params::notifier_service_name}-clone",
1359       target  => "${::aodh::params::evaluator_service_name}-clone",
1360       score   => 'INFINITY',
1361       require => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1362                   Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1363     }
1364     pacemaker::constraint::base { 'aodh-evaluator-then-aodh-listener-constraint':
1365       constraint_type => 'order',
1366       first_resource  => "${::aodh::params::evaluator_service_name}-clone",
1367       second_resource => "${::aodh::params::listener_service_name}-clone",
1368       first_action    => 'start',
1369       second_action   => 'start',
1370       require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1371                           Pacemaker::Resource::Service[$::aodh::params::listener_service_name]],
1372     }
1373     pacemaker::constraint::colocation { 'aodh-listener-with-aodh-evaluator-colocation':
1374       source  => "${::aodh::params::listener_service_name}-clone",
1375       target  => "${::aodh::params::evaluator_service_name}-clone",
1376       score   => 'INFINITY',
1377       require => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1378                   Pacemaker::Resource::Service[$::aodh::params::listener_service_name]],
1379     }
1380     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
1381       pacemaker::constraint::base { 'mongodb-then-ceilometer-central-constraint':
1382         constraint_type => 'order',
1383         first_resource  => "${::mongodb::params::service_name}-clone",
1384         second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1385         first_action    => 'start',
1386         second_action   => 'start',
1387         require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1388                             Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1389       }
1390     }
1391
1392     # gnocchi
1393     pacemaker::resource::service { $::gnocchi::params::metricd_service_name :
1394       clone_params => 'interleave=true',
1395     }
1396     pacemaker::resource::service { $::gnocchi::params::statsd_service_name :
1397       clone_params => 'interleave=true',
1398     }
1399     pacemaker::constraint::base { 'gnocchi-metricd-then-gnocchi-statsd-constraint':
1400       constraint_type => 'order',
1401       first_resource  => "${::gnocchi::params::metricd_service_name}-clone",
1402       second_resource => "${::gnocchi::params::statsd_service_name}-clone",
1403       first_action    => 'start',
1404       second_action   => 'start',
1405       require         => [Pacemaker::Resource::Service[$::gnocchi::params::metricd_service_name],
1406                           Pacemaker::Resource::Service[$::gnocchi::params::statsd_service_name]],
1407     }
1408     pacemaker::constraint::colocation { 'gnocchi-statsd-with-metricd-colocation':
1409       source  => "${::gnocchi::params::statsd_service_name}-clone",
1410       target  => "${::gnocchi::params::metricd_service_name}-clone",
1411       score   => 'INFINITY',
1412       require => [Pacemaker::Resource::Service[$::gnocchi::params::metricd_service_name],
1413                   Pacemaker::Resource::Service[$::gnocchi::params::statsd_service_name]],
1414     }
1415
1416     # Horizon and Keystone
1417     pacemaker::resource::service { $::apache::params::service_name:
1418       clone_params     => 'interleave=true',
1419       verify_on_create => true,
1420       require          => [File['/etc/keystone/ssl/certs/ca.pem'],
1421       File['/etc/keystone/ssl/private/signing_key.pem'],
1422       File['/etc/keystone/ssl/certs/signing_cert.pem']],
1423     }
1424
1425     #VSM
1426     if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
1427       pacemaker::resource::ocf { 'vsm-p' :
1428         ocf_agent_name  => 'heartbeat:VirtualDomain',
1429         resource_params => 'force_stop=true config=/var/spool/cisco/vsm/vsm_primary_deploy.xml',
1430         require         => Class['n1k_vsm'],
1431         meta_params     => 'resource-stickiness=INFINITY',
1432       }
1433       if str2bool(hiera('n1k_vsm::pacemaker_control', true)) {
1434         pacemaker::resource::ocf { 'vsm-s' :
1435           ocf_agent_name  => 'heartbeat:VirtualDomain',
1436           resource_params => 'force_stop=true config=/var/spool/cisco/vsm/vsm_secondary_deploy.xml',
1437           require         => Class['n1k_vsm'],
1438           meta_params     => 'resource-stickiness=INFINITY',
1439         }
1440         pacemaker::constraint::colocation { 'vsm-colocation-contraint':
1441           source  => 'vsm-p',
1442           target  => 'vsm-s',
1443           score   => '-INFINITY',
1444           require => [Pacemaker::Resource::Ocf['vsm-p'],
1445                       Pacemaker::Resource::Ocf['vsm-s']],
1446         }
1447       }
1448     }
1449
1450   }
1451
1452 } #END STEP 5
1453
1454 $package_manifest_name = join(['/var/lib/tripleo/installed-packages/overcloud_controller_pacemaker', hiera('step')])
1455 package_manifest{$package_manifest_name: ensure => present}