Set /64 cidr_netmask for pcmk VIPs when IPv6
[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 include ::tripleo::packages
22 include ::tripleo::firewall
23
24 if $::hostname == downcase(hiera('bootstrap_nodeid')) {
25   $pacemaker_master = true
26   $sync_db = true
27 } else {
28   $pacemaker_master = false
29   $sync_db = false
30 }
31
32 $enable_fencing = str2bool(hiera('enable_fencing', false)) and hiera('step') >= 5
33 $enable_load_balancer = hiera('enable_load_balancer', true)
34
35 # When to start and enable services which haven't been Pacemakerized
36 # FIXME: remove when we start all OpenStack services using Pacemaker
37 # (occurences of this variable will be gradually replaced with false)
38 $non_pcmk_start = hiera('step') >= 4
39
40 if hiera('step') >= 1 {
41
42   create_resources(kmod::load, hiera('kernel_modules'), {})
43   create_resources(sysctl::value, hiera('sysctl_settings'), {})
44   Exec <| tag == 'kmod::load' |>  -> Sysctl <| |>
45
46   include ::timezone
47
48   if count(hiera('ntp::servers')) > 0 {
49     include ::ntp
50   }
51
52   $controller_node_ips = split(hiera('controller_node_ips'), ',')
53   $controller_node_names = split(downcase(hiera('controller_node_names')), ',')
54   if $enable_load_balancer {
55     class { '::tripleo::loadbalancer' :
56       controller_hosts       => $controller_node_ips,
57       controller_hosts_names => $controller_node_names,
58       manage_vip             => false,
59       mysql_clustercheck     => true,
60       haproxy_service_manage => false,
61     }
62   }
63
64   $pacemaker_cluster_members = downcase(regsubst(hiera('controller_node_names'), ',', ' ', 'G'))
65   $corosync_ipv6 = str2bool(hiera('corosync_ipv6', false))
66   if $corosync_ipv6 {
67     $cluster_setup_extras = { '--ipv6' => '' }
68   } else {
69     $cluster_setup_extras = {}
70   }
71   user { 'hacluster':
72     ensure => present,
73   } ->
74   class { '::pacemaker':
75     hacluster_pwd => hiera('hacluster_pwd'),
76   } ->
77   class { '::pacemaker::corosync':
78     cluster_members      => $pacemaker_cluster_members,
79     setup_cluster        => $pacemaker_master,
80     cluster_setup_extras => $cluster_setup_extras,
81   }
82   class { '::pacemaker::stonith':
83     disable => !$enable_fencing,
84   }
85   if $enable_fencing {
86     include ::tripleo::fencing
87
88     # enable stonith after all fencing devices have been created
89     Class['tripleo::fencing'] -> Class['pacemaker::stonith']
90   }
91
92   # FIXME(gfidente): sets 200secs as default start timeout op
93   # param; until we can use pcmk global defaults we'll still
94   # need to add it to every resource which redefines op params
95   Pacemaker::Resource::Service {
96     op_params => 'start timeout=200s stop timeout=200s',
97   }
98
99   # Only configure RabbitMQ in this step, don't start it yet to
100   # avoid races where non-master nodes attempt to start without
101   # config (eg. binding on 0.0.0.0)
102   # The module ignores erlang_cookie if cluster_config is false
103   class { '::rabbitmq':
104     service_manage          => false,
105     tcp_keepalive           => false,
106     config_kernel_variables => hiera('rabbitmq_kernel_variables'),
107     config_variables        => hiera('rabbitmq_config_variables'),
108     environment_variables   => hiera('rabbitmq_environment'),
109   } ->
110   file { '/var/lib/rabbitmq/.erlang.cookie':
111     ensure  => file,
112     owner   => 'rabbitmq',
113     group   => 'rabbitmq',
114     mode    => '0400',
115     content => hiera('rabbitmq::erlang_cookie'),
116     replace => true,
117   }
118
119   if downcase(hiera('ceilometer_backend')) == 'mongodb' {
120     include ::mongodb::globals
121     class { '::mongodb::server' :
122       service_manage => false,
123     }
124   }
125
126   # Memcached
127   class {'::memcached' :
128     service_manage => false,
129   }
130
131   # Redis
132   class { '::redis' :
133     service_manage => false,
134     notify_service => false,
135   }
136
137   # Galera
138   if str2bool(hiera('enable_galera', true)) {
139     $mysql_config_file = '/etc/my.cnf.d/galera.cnf'
140   } else {
141     $mysql_config_file = '/etc/my.cnf.d/server.cnf'
142   }
143   $galera_nodes = downcase(hiera('galera_node_names', $::hostname))
144   $galera_nodes_count = count(split($galera_nodes, ','))
145
146   # FIXME: due to https://bugzilla.redhat.com/show_bug.cgi?id=1298671 we
147   # set bind-address to a hostname instead of an ip address; to move Mysql
148   # from internal_api on another network we'll have to customize both
149   # MysqlNetwork and ControllerHostnameResolveNetwork in ServiceNetMap
150   $mysql_bind_host = hiera('mysql_bind_host')
151   $mysqld_options = {
152     'mysqld' => {
153       'skip-name-resolve'             => '1',
154       'binlog_format'                 => 'ROW',
155       'default-storage-engine'        => 'innodb',
156       'innodb_autoinc_lock_mode'      => '2',
157       'innodb_locks_unsafe_for_binlog'=> '1',
158       'query_cache_size'              => '0',
159       'query_cache_type'              => '0',
160       'bind-address'                  => $::hostname,
161       'max_connections'               => hiera('mysql_max_connections'),
162       'open_files_limit'              => '-1',
163       'wsrep_provider'                => '/usr/lib64/galera/libgalera_smm.so',
164       'wsrep_cluster_name'            => 'galera_cluster',
165       'wsrep_slave_threads'           => '1',
166       'wsrep_certify_nonPK'           => '1',
167       'wsrep_max_ws_rows'             => '131072',
168       'wsrep_max_ws_size'             => '1073741824',
169       'wsrep_debug'                   => '0',
170       'wsrep_convert_LOCK_to_trx'     => '0',
171       'wsrep_retry_autocommit'        => '1',
172       'wsrep_auto_increment_control'  => '1',
173       'wsrep_drupal_282555_workaround'=> '0',
174       'wsrep_causal_reads'            => '0',
175       'wsrep_sst_method'              => 'rsync',
176       'wsrep_provider_options'        => "gmcast.listen_addr=tcp://[${mysql_bind_host}]:4567;",
177     },
178   }
179
180   class { '::mysql::server':
181     create_root_user        => false,
182     create_root_my_cnf      => false,
183     config_file             => $mysql_config_file,
184     override_options        => $mysqld_options,
185     remove_default_accounts => $pacemaker_master,
186     service_manage          => false,
187     service_enabled         => false,
188   }
189
190 }
191
192 if hiera('step') >= 2 {
193
194   # NOTE(gfidente): the following vars are needed on all nodes so they
195   # need to stay out of pacemaker_master conditional
196   $mongo_node_ips_with_port = suffix(hiera('mongo_node_ips'), ':27017')
197   $mongodb_replset = hiera('mongodb::server::replset')
198
199   if $pacemaker_master {
200
201     if $enable_load_balancer {
202
203       include ::pacemaker::resource_defaults
204
205       # FIXME: we should not have to access tripleo::loadbalancer class
206       # parameters here to configure pacemaker VIPs. The configuration
207       # of pacemaker VIPs could move into puppet-tripleo or we should
208       # make use of less specific hiera parameters here for the settings.
209       pacemaker::resource::service { 'haproxy':
210         clone_params => true,
211       }
212
213       $control_vip = hiera('tripleo::loadbalancer::controller_virtual_ip')
214       if is_ipv6_address($control_vip) {
215         $control_vip_netmask = '64'
216       } else {
217         $control_vip_netmask = '32'
218       }
219       pacemaker::resource::ip { 'control_vip':
220         ip_address   => $control_vip,
221         cidr_netmask => $control_vip_netmask,
222       }
223       pacemaker::constraint::base { 'control_vip-then-haproxy':
224         constraint_type   => 'order',
225         first_resource    => "ip-${control_vip}",
226         second_resource   => 'haproxy-clone',
227         first_action      => 'start',
228         second_action     => 'start',
229         constraint_params => 'kind=Optional',
230         require           => [Pacemaker::Resource::Service['haproxy'],
231                               Pacemaker::Resource::Ip['control_vip']],
232       }
233       pacemaker::constraint::colocation { 'control_vip-with-haproxy':
234         source  => "ip-${control_vip}",
235         target  => 'haproxy-clone',
236         score   => 'INFINITY',
237         require => [Pacemaker::Resource::Service['haproxy'],
238                     Pacemaker::Resource::Ip['control_vip']],
239       }
240
241       $public_vip = hiera('tripleo::loadbalancer::public_virtual_ip')
242       if is_ipv6_address($public_vip) {
243         $public_vip_netmask = '64'
244       } else {
245         $public_vip_netmask = '32'
246       }
247       if $public_vip and $public_vip != $control_vip {
248         pacemaker::resource::ip { 'public_vip':
249           ip_address   => $public_vip,
250           cidr_netmask => $public_vip_netmask,
251         }
252         pacemaker::constraint::base { 'public_vip-then-haproxy':
253           constraint_type   => 'order',
254           first_resource    => "ip-${public_vip}",
255           second_resource   => 'haproxy-clone',
256           first_action      => 'start',
257           second_action     => 'start',
258           constraint_params => 'kind=Optional',
259           require           => [Pacemaker::Resource::Service['haproxy'],
260                                 Pacemaker::Resource::Ip['public_vip']],
261         }
262         pacemaker::constraint::colocation { 'public_vip-with-haproxy':
263           source  => "ip-${public_vip}",
264           target  => 'haproxy-clone',
265           score   => 'INFINITY',
266           require => [Pacemaker::Resource::Service['haproxy'],
267                       Pacemaker::Resource::Ip['public_vip']],
268         }
269       }
270
271       $redis_vip = hiera('redis_vip')
272       if is_ipv6_address($redis_vip) {
273         $redis_vip_netmask = '64'
274       } else {
275         $redis_vip_netmask = '32'
276       }
277       if $redis_vip and $redis_vip != $control_vip {
278         pacemaker::resource::ip { 'redis_vip':
279           ip_address   => $redis_vip,
280           cidr_netmask => $redis_vip_netmask,
281         }
282         pacemaker::constraint::base { 'redis_vip-then-haproxy':
283           constraint_type   => 'order',
284           first_resource    => "ip-${redis_vip}",
285           second_resource   => 'haproxy-clone',
286           first_action      => 'start',
287           second_action     => 'start',
288           constraint_params => 'kind=Optional',
289           require           => [Pacemaker::Resource::Service['haproxy'],
290                                 Pacemaker::Resource::Ip['redis_vip']],
291         }
292         pacemaker::constraint::colocation { 'redis_vip-with-haproxy':
293           source  => "ip-${redis_vip}",
294           target  => 'haproxy-clone',
295           score   => 'INFINITY',
296           require => [Pacemaker::Resource::Service['haproxy'],
297                       Pacemaker::Resource::Ip['redis_vip']],
298         }
299       }
300
301       $internal_api_vip = hiera('tripleo::loadbalancer::internal_api_virtual_ip')
302       if is_ipv6_address($internal_api_vip) {
303         $internal_api_vip_netmask = '64'
304       } else {
305         $internal_api_vip_netmask = '32'
306       }
307       if $internal_api_vip and $internal_api_vip != $control_vip {
308         pacemaker::resource::ip { 'internal_api_vip':
309           ip_address   => $internal_api_vip,
310           cidr_netmask => $internal_api_vip_netmask,
311         }
312         pacemaker::constraint::base { 'internal_api_vip-then-haproxy':
313           constraint_type   => 'order',
314           first_resource    => "ip-${internal_api_vip}",
315           second_resource   => 'haproxy-clone',
316           first_action      => 'start',
317           second_action     => 'start',
318           constraint_params => 'kind=Optional',
319           require           => [Pacemaker::Resource::Service['haproxy'],
320                                 Pacemaker::Resource::Ip['internal_api_vip']],
321         }
322         pacemaker::constraint::colocation { 'internal_api_vip-with-haproxy':
323           source  => "ip-${internal_api_vip}",
324           target  => 'haproxy-clone',
325           score   => 'INFINITY',
326           require => [Pacemaker::Resource::Service['haproxy'],
327                       Pacemaker::Resource::Ip['internal_api_vip']],
328         }
329       }
330
331       $storage_vip = hiera('tripleo::loadbalancer::storage_virtual_ip')
332       if is_ipv6_address($storage_vip) {
333         $storage_vip_netmask = '64'
334       } else {
335         $storage_vip_netmask = '32'
336       }
337       if $storage_vip and $storage_vip != $control_vip {
338         pacemaker::resource::ip { 'storage_vip':
339           ip_address   => $storage_vip,
340           cidr_netmask => $storage_vip_netmask,
341         }
342         pacemaker::constraint::base { 'storage_vip-then-haproxy':
343           constraint_type   => 'order',
344           first_resource    => "ip-${storage_vip}",
345           second_resource   => 'haproxy-clone',
346           first_action      => 'start',
347           second_action     => 'start',
348           constraint_params => 'kind=Optional',
349           require           => [Pacemaker::Resource::Service['haproxy'],
350                                 Pacemaker::Resource::Ip['storage_vip']],
351         }
352         pacemaker::constraint::colocation { 'storage_vip-with-haproxy':
353           source  => "ip-${storage_vip}",
354           target  => 'haproxy-clone',
355           score   => 'INFINITY',
356           require => [Pacemaker::Resource::Service['haproxy'],
357                       Pacemaker::Resource::Ip['storage_vip']],
358         }
359       }
360
361       $storage_mgmt_vip = hiera('tripleo::loadbalancer::storage_mgmt_virtual_ip')
362       if is_ipv6_address($storage_mgmt_vip) {
363         $storage_mgmt_vip_netmask = '64'
364       } else {
365         $storage_mgmt_vip_netmask = '32'
366       }
367       if $storage_mgmt_vip and $storage_mgmt_vip != $control_vip {
368         pacemaker::resource::ip { 'storage_mgmt_vip':
369           ip_address   => $storage_mgmt_vip,
370           cidr_netmask => $storage_mgmt_vip_netmask,
371         }
372         pacemaker::constraint::base { 'storage_mgmt_vip-then-haproxy':
373           constraint_type   => 'order',
374           first_resource    => "ip-${storage_mgmt_vip}",
375           second_resource   => 'haproxy-clone',
376           first_action      => 'start',
377           second_action     => 'start',
378           constraint_params => 'kind=Optional',
379           require           => [Pacemaker::Resource::Service['haproxy'],
380                                 Pacemaker::Resource::Ip['storage_mgmt_vip']],
381         }
382         pacemaker::constraint::colocation { 'storage_mgmt_vip-with-haproxy':
383           source  => "ip-${storage_mgmt_vip}",
384           target  => 'haproxy-clone',
385           score   => 'INFINITY',
386           require => [Pacemaker::Resource::Service['haproxy'],
387                       Pacemaker::Resource::Ip['storage_mgmt_vip']],
388         }
389       }
390
391     }
392
393     pacemaker::resource::service { $::memcached::params::service_name :
394       clone_params => 'interleave=true',
395       require      => Class['::memcached'],
396     }
397
398     pacemaker::resource::ocf { 'rabbitmq':
399       ocf_agent_name  => 'heartbeat:rabbitmq-cluster',
400       resource_params => 'set_policy=\'ha-all ^(?!amq\.).* {"ha-mode":"all"}\'',
401       clone_params    => 'ordered=true interleave=true',
402       meta_params     => 'notify=true',
403       require         => Class['::rabbitmq'],
404     }
405
406     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
407       pacemaker::resource::service { $::mongodb::params::service_name :
408         op_params    => 'start timeout=370s stop timeout=200s',
409         clone_params => true,
410         require      => Class['::mongodb::server'],
411       }
412       # NOTE (spredzy) : The replset can only be run
413       # once all the nodes have joined the cluster.
414       mongodb_conn_validator { $mongo_node_ips_with_port :
415         timeout => '600',
416         require => Pacemaker::Resource::Service[$::mongodb::params::service_name],
417         before  => Mongodb_replset[$mongodb_replset],
418       }
419       mongodb_replset { $mongodb_replset :
420         members => $mongo_node_ips_with_port,
421       }
422     }
423
424     pacemaker::resource::ocf { 'galera' :
425       ocf_agent_name  => 'heartbeat:galera',
426       op_params       => 'promote timeout=300s on-fail=block',
427       master_params   => '',
428       meta_params     => "master-max=${galera_nodes_count} ordered=true",
429       resource_params => "additional_parameters='--open-files-limit=16384' enable_creation=true wsrep_cluster_address='gcomm://${galera_nodes}'",
430       require         => Class['::mysql::server'],
431       before          => Exec['galera-ready'],
432     }
433
434     pacemaker::resource::ocf { 'redis':
435       ocf_agent_name  => 'heartbeat:redis',
436       master_params   => '',
437       meta_params     => 'notify=true ordered=true interleave=true',
438       resource_params => 'wait_last_known_master=true',
439       require         => Class['::redis'],
440     }
441
442   }
443
444   exec { 'galera-ready' :
445     command     => '/usr/bin/clustercheck >/dev/null',
446     timeout     => 30,
447     tries       => 180,
448     try_sleep   => 10,
449     environment => ['AVAILABLE_WHEN_READONLY=0'],
450     require     => File['/etc/sysconfig/clustercheck'],
451   }
452
453   file { '/etc/sysconfig/clustercheck' :
454     ensure  => file,
455     content => "MYSQL_USERNAME=root\n
456 MYSQL_PASSWORD=''\n
457 MYSQL_HOST=localhost\n",
458   }
459
460   xinetd::service { 'galera-monitor' :
461     port           => '9200',
462     server         => '/usr/bin/clustercheck',
463     per_source     => 'UNLIMITED',
464     log_on_success => '',
465     log_on_failure => 'HOST',
466     flags          => 'REUSE',
467     service_type   => 'UNLISTED',
468     user           => 'root',
469     group          => 'root',
470     require        => File['/etc/sysconfig/clustercheck'],
471   }
472
473   # Create all the database schemas
474   if $sync_db {
475     class { '::keystone::db::mysql':
476       require => Exec['galera-ready'],
477     }
478     class { '::glance::db::mysql':
479       require => Exec['galera-ready'],
480     }
481     class { '::nova::db::mysql':
482       require => Exec['galera-ready'],
483     }
484     class { '::nova::db::mysql_api':
485       require => Exec['galera-ready'],
486     }
487     class { '::neutron::db::mysql':
488       require => Exec['galera-ready'],
489     }
490     class { '::cinder::db::mysql':
491       require => Exec['galera-ready'],
492     }
493     class { '::heat::db::mysql':
494       require => Exec['galera-ready'],
495     }
496
497     if downcase(hiera('ceilometer_backend')) == 'mysql' {
498       class { '::ceilometer::db::mysql':
499         require => Exec['galera-ready'],
500       }
501     }
502
503     class { '::sahara::db::mysql':
504       require       => Exec['galera-ready'],
505     }
506   }
507
508   # pre-install swift here so we can build rings
509   include ::swift
510
511   # Ceph
512   $enable_ceph = hiera('ceph_storage_count', 0) > 0 or hiera('enable_ceph_storage', false)
513
514   if $enable_ceph {
515     class { '::ceph::profile::params':
516       mon_initial_members => downcase(hiera('ceph_mon_initial_members')),
517     }
518     include ::ceph::conf
519     include ::ceph::profile::mon
520   }
521
522   if str2bool(hiera('enable_ceph_storage', false)) {
523     if str2bool(hiera('ceph_osd_selinux_permissive', true)) {
524       exec { 'set selinux to permissive on boot':
525         command => "sed -ie 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config",
526         onlyif  => "test -f /etc/selinux/config && ! grep '^SELINUX=permissive' /etc/selinux/config",
527         path    => ['/usr/bin', '/usr/sbin'],
528       }
529
530       exec { 'set selinux to permissive':
531         command => 'setenforce 0',
532         onlyif  => "which setenforce && getenforce | grep -i 'enforcing'",
533         path    => ['/usr/bin', '/usr/sbin'],
534       } -> Class['ceph::profile::osd']
535     }
536
537     include ::ceph::conf
538     include ::ceph::profile::osd
539   }
540
541   if str2bool(hiera('enable_external_ceph', false)) {
542     include ::ceph::conf
543     include ::ceph::profile::client
544   }
545
546
547 } #END STEP 2
548
549 if hiera('step') >= 3 {
550
551   class { '::keystone':
552     sync_db          => $sync_db,
553     manage_service   => false,
554     enabled          => false,
555     enable_bootstrap => $pacemaker_master,
556   }
557   include ::keystone::config
558
559   #TODO: need a cleanup-keystone-tokens.sh solution here
560
561   file { [ '/etc/keystone/ssl', '/etc/keystone/ssl/certs', '/etc/keystone/ssl/private' ]:
562     ensure  => 'directory',
563     owner   => 'keystone',
564     group   => 'keystone',
565     require => Package['keystone'],
566   }
567   file { '/etc/keystone/ssl/certs/signing_cert.pem':
568     content => hiera('keystone_signing_certificate'),
569     owner   => 'keystone',
570     group   => 'keystone',
571     notify  => Service['keystone'],
572     require => File['/etc/keystone/ssl/certs'],
573   }
574   file { '/etc/keystone/ssl/private/signing_key.pem':
575     content => hiera('keystone_signing_key'),
576     owner   => 'keystone',
577     group   => 'keystone',
578     notify  => Service['keystone'],
579     require => File['/etc/keystone/ssl/private'],
580   }
581   file { '/etc/keystone/ssl/certs/ca.pem':
582     content => hiera('keystone_ca_certificate'),
583     owner   => 'keystone',
584     group   => 'keystone',
585     notify  => Service['keystone'],
586     require => File['/etc/keystone/ssl/certs'],
587   }
588
589   $glance_backend = downcase(hiera('glance_backend', 'swift'))
590   case $glance_backend {
591       'swift': { $backend_store = 'glance.store.swift.Store' }
592       'file': { $backend_store = 'glance.store.filesystem.Store' }
593       'rbd': { $backend_store = 'glance.store.rbd.Store' }
594       default: { fail('Unrecognized glance_backend parameter.') }
595   }
596   $http_store = ['glance.store.http.Store']
597   $glance_store = concat($http_store, $backend_store)
598
599   if $glance_backend == 'file' and hiera('glance_file_pcmk_manage', false) {
600     $secontext = 'context="system_u:object_r:glance_var_lib_t:s0"'
601     pacemaker::resource::filesystem { 'glance-fs':
602       device       => hiera('glance_file_pcmk_device'),
603       directory    => hiera('glance_file_pcmk_directory'),
604       fstype       => hiera('glance_file_pcmk_fstype'),
605       fsoptions    => join([$secontext, hiera('glance_file_pcmk_options', '')],','),
606       clone_params => '',
607     }
608   }
609
610   # TODO: notifications, scrubber, etc.
611   include ::glance
612   include ::glance::config
613   class { '::glance::api':
614     known_stores   => $glance_store,
615     manage_service => false,
616     enabled        => false,
617   }
618   class { '::glance::registry' :
619     sync_db        => $sync_db,
620     manage_service => false,
621     enabled        => false,
622   }
623   include join(['::glance::backend::', $glance_backend])
624   $rabbit_port = hiera('rabbitmq::port')
625   class { '::glance::notify::rabbitmq':
626     rabbit_hosts => suffix(hiera('rabbit_node_ips'), ":${rabbit_port}"),
627   }
628
629   class { '::nova' :
630     memcached_servers => suffix(hiera('memcache_node_ips'), ':11211'),
631   }
632
633   include ::nova::config
634
635   class { '::nova::api' :
636     sync_db        => $sync_db,
637     sync_db_api    => $sync_db,
638     manage_service => false,
639     enabled        => false,
640   }
641   class { '::nova::cert' :
642     manage_service => false,
643     enabled        => false,
644   }
645   class { '::nova::conductor' :
646     manage_service => false,
647     enabled        => false,
648   }
649   class { '::nova::consoleauth' :
650     manage_service => false,
651     enabled        => false,
652   }
653   class { '::nova::vncproxy' :
654     manage_service => false,
655     enabled        => false,
656   }
657   include ::nova::scheduler::filter
658   class { '::nova::scheduler' :
659     manage_service => false,
660     enabled        => false,
661   }
662   include ::nova::network::neutron
663
664   if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
665
666     # TODO(devvesa) provide non-controller ips for these services
667     $zookeeper_node_ips = hiera('neutron_api_node_ips')
668     $cassandra_node_ips = hiera('neutron_api_node_ips')
669
670     # Run zookeeper in the controller if configured
671     if hiera('enable_zookeeper_on_controller') {
672       class {'::tripleo::cluster::zookeeper':
673         zookeeper_server_ips => $zookeeper_node_ips,
674         # TODO: create a 'bind' hiera key for zookeeper
675         zookeeper_client_ip  => hiera('neutron::bind_host'),
676         zookeeper_hostnames  => split(hiera('controller_node_names'), ',')
677       }
678     }
679
680     # Run cassandra in the controller if configured
681     if hiera('enable_cassandra_on_controller') {
682       class {'::tripleo::cluster::cassandra':
683         cassandra_servers => $cassandra_node_ips,
684         # TODO: create a 'bind' hiera key for cassandra
685         cassandra_ip      => hiera('neutron::bind_host'),
686       }
687     }
688
689     class {'::tripleo::network::midonet::agent':
690       zookeeper_servers => $zookeeper_node_ips,
691       cassandra_seeds   => $cassandra_node_ips
692     }
693
694     class {'::tripleo::network::midonet::api':
695       zookeeper_servers    => $zookeeper_node_ips,
696       vip                  => hiera('tripleo::loadbalancer::public_virtual_ip'),
697       keystone_ip          => hiera('tripleo::loadbalancer::public_virtual_ip'),
698       keystone_admin_token => hiera('keystone::admin_token'),
699       # TODO: create a 'bind' hiera key for api
700       bind_address         => hiera('neutron::bind_host'),
701       admin_password       => hiera('admin_password')
702     }
703
704     # Configure Neutron
705     class {'::neutron':
706       service_plugins => []
707     }
708
709   }
710   else {
711     # Neutron class definitions
712     include ::neutron
713   }
714
715   include ::neutron::config
716   class { '::neutron::server' :
717     sync_db        => $sync_db,
718     manage_service => false,
719     enabled        => false,
720   }
721   include ::neutron::server::notifications
722   if  hiera('neutron::core_plugin') == 'neutron.plugins.nuage.plugin.NuagePlugin' {
723     include ::neutron::plugins::nuage
724   }
725   if  hiera('neutron::core_plugin') == 'neutron_plugin_contrail.plugins.opencontrail.contrail_plugin.NeutronPluginContrailCoreV2' {
726     include ::neutron::plugins::opencontrail
727   }
728   if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
729     class {'::neutron::plugins::midonet':
730       midonet_api_ip    => hiera('tripleo::loadbalancer::public_virtual_ip'),
731       keystone_tenant   => hiera('neutron::server::auth_tenant'),
732       keystone_password => hiera('neutron::server::auth_password')
733     }
734   }
735   if hiera('neutron::enable_dhcp_agent',true) {
736     class { '::neutron::agents::dhcp' :
737       manage_service => false,
738       enabled        => false,
739     }
740     file { '/etc/neutron/dnsmasq-neutron.conf':
741       content => hiera('neutron_dnsmasq_options'),
742       owner   => 'neutron',
743       group   => 'neutron',
744       notify  => Service['neutron-dhcp-service'],
745       require => Package['neutron'],
746     }
747   }
748   if hiera('neutron::enable_l3_agent',true) {
749     class { '::neutron::agents::l3' :
750       manage_service => false,
751       enabled        => false,
752     }
753   }
754   if hiera('neutron::enable_metadata_agent',true) {
755     class { '::neutron::agents::metadata':
756       manage_service => false,
757       enabled        => false,
758     }
759   }
760   include ::neutron::plugins::ml2
761   class { '::neutron::agents::ml2::ovs':
762     manage_service => false,
763     enabled        => false,
764   }
765
766   if 'cisco_ucsm' in hiera('neutron::plugins::ml2::mechanism_drivers') {
767     include ::neutron::plugins::ml2::cisco::ucsm
768   }
769   if 'cisco_nexus' in hiera('neutron::plugins::ml2::mechanism_drivers') {
770     include ::neutron::plugins::ml2::cisco::nexus
771     include ::neutron::plugins::ml2::cisco::type_nexus_vxlan
772   }
773   if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
774     include ::neutron::plugins::ml2::cisco::nexus1000v
775
776     class { '::neutron::agents::n1kv_vem':
777       n1kv_source  => hiera('n1kv_vem_source', undef),
778       n1kv_version => hiera('n1kv_vem_version', undef),
779     }
780
781     class { '::n1k_vsm':
782       n1kv_source  => hiera('n1kv_vsm_source', undef),
783       n1kv_version => hiera('n1kv_vsm_version', undef),
784     }
785   }
786
787   if 'bsn_ml2' in hiera('neutron::plugins::ml2::mechanism_drivers') {
788     include ::neutron::plugins::ml2::bigswitch::restproxy
789     include ::neutron::agents::bigswitch
790   }
791   neutron_l3_agent_config {
792     'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
793   }
794   neutron_dhcp_agent_config {
795     'DEFAULT/ovs_use_veth': value => hiera('neutron_ovs_use_veth', false);
796   }
797   neutron_config {
798     'DEFAULT/notification_driver': value => 'messaging';
799   }
800
801   include ::cinder
802   include ::cinder::config
803   include ::tripleo::ssl::cinder_config
804   class { '::cinder::api':
805     sync_db        => $sync_db,
806     manage_service => false,
807     enabled        => false,
808   }
809   class { '::cinder::scheduler' :
810     manage_service => false,
811     enabled        => false,
812   }
813   class { '::cinder::volume' :
814     manage_service => false,
815     enabled        => false,
816   }
817   include ::cinder::glance
818   include ::cinder::ceilometer
819   class { '::cinder::setup_test_volume':
820     size => join([hiera('cinder_lvm_loop_device_size'), 'M']),
821   }
822
823   $cinder_enable_iscsi = hiera('cinder_enable_iscsi_backend', true)
824   if $cinder_enable_iscsi {
825     $cinder_iscsi_backend = 'tripleo_iscsi'
826
827     cinder::backend::iscsi { $cinder_iscsi_backend :
828       iscsi_ip_address => hiera('cinder_iscsi_ip_address'),
829       iscsi_helper     => hiera('cinder_iscsi_helper'),
830     }
831   }
832
833   if $enable_ceph {
834
835     $ceph_pools = hiera('ceph_pools')
836     ceph::pool { $ceph_pools :
837       pg_num  => hiera('ceph::profile::params::osd_pool_default_pg_num'),
838       pgp_num => hiera('ceph::profile::params::osd_pool_default_pgp_num'),
839       size    => hiera('ceph::profile::params::osd_pool_default_size'),
840     }
841
842     $cinder_pool_requires = [Ceph::Pool[hiera('cinder_rbd_pool_name')]]
843
844   } else {
845     $cinder_pool_requires = []
846   }
847
848   if hiera('cinder_enable_rbd_backend', false) {
849     $cinder_rbd_backend = 'tripleo_ceph'
850
851     cinder::backend::rbd { $cinder_rbd_backend :
852       rbd_pool        => hiera('cinder_rbd_pool_name'),
853       rbd_user        => hiera('ceph_client_user_name'),
854       rbd_secret_uuid => hiera('ceph::profile::params::fsid'),
855       require         => $cinder_pool_requires,
856     }
857   }
858
859   if hiera('cinder_enable_eqlx_backend', false) {
860     $cinder_eqlx_backend = hiera('cinder::backend::eqlx::volume_backend_name')
861
862     cinder::backend::eqlx { $cinder_eqlx_backend :
863       volume_backend_name => hiera('cinder::backend::eqlx::volume_backend_name', undef),
864       san_ip              => hiera('cinder::backend::eqlx::san_ip', undef),
865       san_login           => hiera('cinder::backend::eqlx::san_login', undef),
866       san_password        => hiera('cinder::backend::eqlx::san_password', undef),
867       san_thin_provision  => hiera('cinder::backend::eqlx::san_thin_provision', undef),
868       eqlx_group_name     => hiera('cinder::backend::eqlx::eqlx_group_name', undef),
869       eqlx_pool           => hiera('cinder::backend::eqlx::eqlx_pool', undef),
870       eqlx_use_chap       => hiera('cinder::backend::eqlx::eqlx_use_chap', undef),
871       eqlx_chap_login     => hiera('cinder::backend::eqlx::eqlx_chap_login', undef),
872       eqlx_chap_password  => hiera('cinder::backend::eqlx::eqlx_san_password', undef),
873     }
874   }
875
876   if hiera('cinder_enable_dellsc_backend', false) {
877     $cinder_dellsc_backend = hiera('cinder::backend::dellsc_iscsi::volume_backend_name')
878
879     cinder::backend::dellsc_iscsi{ $cinder_dellsc_backend :
880       volume_backend_name   => hiera('cinder::backend::dellsc_iscsi::volume_backend_name', undef),
881       san_ip                => hiera('cinder::backend::dellsc_iscsi::san_ip', undef),
882       san_login             => hiera('cinder::backend::dellsc_iscsi::san_login', undef),
883       san_password          => hiera('cinder::backend::dellsc_iscsi::san_password', undef),
884       dell_sc_ssn           => hiera('cinder::backend::dellsc_iscsi::dell_sc_ssn', undef),
885       iscsi_ip_address      => hiera('cinder::backend::dellsc_iscsi::iscsi_ip_address', undef),
886       iscsi_port            => hiera('cinder::backend::dellsc_iscsi::iscsi_port', undef),
887       dell_sc_api_port      => hiera('cinder::backend::dellsc_iscsi::dell_sc_api_port', undef),
888       dell_sc_server_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_server_folder', undef),
889       dell_sc_volume_folder => hiera('cinder::backend::dellsc_iscsi::dell_sc_volume_folder', undef),
890     }
891   }
892
893   if hiera('cinder_enable_netapp_backend', false) {
894     $cinder_netapp_backend = hiera('cinder::backend::netapp::title')
895
896     if hiera('cinder::backend::netapp::nfs_shares', undef) {
897       $cinder_netapp_nfs_shares = split(hiera('cinder::backend::netapp::nfs_shares', undef), ',')
898     }
899
900     cinder::backend::netapp { $cinder_netapp_backend :
901       netapp_login                 => hiera('cinder::backend::netapp::netapp_login', undef),
902       netapp_password              => hiera('cinder::backend::netapp::netapp_password', undef),
903       netapp_server_hostname       => hiera('cinder::backend::netapp::netapp_server_hostname', undef),
904       netapp_server_port           => hiera('cinder::backend::netapp::netapp_server_port', undef),
905       netapp_size_multiplier       => hiera('cinder::backend::netapp::netapp_size_multiplier', undef),
906       netapp_storage_family        => hiera('cinder::backend::netapp::netapp_storage_family', undef),
907       netapp_storage_protocol      => hiera('cinder::backend::netapp::netapp_storage_protocol', undef),
908       netapp_transport_type        => hiera('cinder::backend::netapp::netapp_transport_type', undef),
909       netapp_vfiler                => hiera('cinder::backend::netapp::netapp_vfiler', undef),
910       netapp_volume_list           => hiera('cinder::backend::netapp::netapp_volume_list', undef),
911       netapp_vserver               => hiera('cinder::backend::netapp::netapp_vserver', undef),
912       netapp_partner_backend_name  => hiera('cinder::backend::netapp::netapp_partner_backend_name', undef),
913       nfs_shares                   => $cinder_netapp_nfs_shares,
914       nfs_shares_config            => hiera('cinder::backend::netapp::nfs_shares_config', undef),
915       netapp_copyoffload_tool_path => hiera('cinder::backend::netapp::netapp_copyoffload_tool_path', undef),
916       netapp_controller_ips        => hiera('cinder::backend::netapp::netapp_controller_ips', undef),
917       netapp_sa_password           => hiera('cinder::backend::netapp::netapp_sa_password', undef),
918       netapp_storage_pools         => hiera('cinder::backend::netapp::netapp_storage_pools', undef),
919       netapp_eseries_host_type     => hiera('cinder::backend::netapp::netapp_eseries_host_type', undef),
920       netapp_webservice_path       => hiera('cinder::backend::netapp::netapp_webservice_path', undef),
921     }
922   }
923
924   if hiera('cinder_enable_nfs_backend', false) {
925     $cinder_nfs_backend = 'tripleo_nfs'
926
927     if str2bool($::selinux) {
928       selboolean { 'virt_use_nfs':
929         value      => on,
930         persistent => true,
931       } -> Package['nfs-utils']
932     }
933
934     package { 'nfs-utils': } ->
935     cinder::backend::nfs { $cinder_nfs_backend:
936       nfs_servers       => hiera('cinder_nfs_servers'),
937       nfs_mount_options => hiera('cinder_nfs_mount_options',''),
938       nfs_shares_config => '/etc/cinder/shares-nfs.conf',
939     }
940   }
941
942   $cinder_enabled_backends = delete_undef_values([$cinder_iscsi_backend, $cinder_rbd_backend, $cinder_eqlx_backend, $cinder_dellsc_backend, $cinder_netapp_backend, $cinder_nfs_backend])
943   class { '::cinder::backends' :
944     enabled_backends => $cinder_enabled_backends,
945   }
946
947   class { '::sahara':
948     sync_db => $sync_db,
949   }
950   class { '::sahara::service::api':
951     manage_service => false,
952     enabled        => false,
953   }
954   class { '::sahara::service::engine':
955     manage_service => false,
956     enabled        => false,
957   }
958
959   # swift proxy
960   class { '::swift::proxy' :
961     manage_service => $non_pcmk_start,
962     enabled        => $non_pcmk_start,
963   }
964   include ::swift::proxy::proxy_logging
965   include ::swift::proxy::healthcheck
966   include ::swift::proxy::cache
967   include ::swift::proxy::keystone
968   include ::swift::proxy::authtoken
969   include ::swift::proxy::staticweb
970   include ::swift::proxy::ratelimit
971   include ::swift::proxy::catch_errors
972   include ::swift::proxy::tempurl
973   include ::swift::proxy::formpost
974
975   # swift storage
976   if str2bool(hiera('enable_swift_storage', true)) {
977     class {'::swift::storage::all':
978       mount_check => str2bool(hiera('swift_mount_check')),
979     }
980     class {'::swift::storage::account':
981       manage_service => $non_pcmk_start,
982       enabled        => $non_pcmk_start,
983     }
984     class {'::swift::storage::container':
985       manage_service => $non_pcmk_start,
986       enabled        => $non_pcmk_start,
987     }
988     class {'::swift::storage::object':
989       manage_service => $non_pcmk_start,
990       enabled        => $non_pcmk_start,
991     }
992     if(!defined(File['/srv/node'])) {
993       file { '/srv/node':
994         ensure  => directory,
995         owner   => 'swift',
996         group   => 'swift',
997         require => Package['openstack-swift'],
998       }
999     }
1000     $swift_components = ['account', 'container', 'object']
1001     swift::storage::filter::recon { $swift_components : }
1002     swift::storage::filter::healthcheck { $swift_components : }
1003   }
1004
1005   # Ceilometer
1006   case downcase(hiera('ceilometer_backend')) {
1007     /mysql/: {
1008       $ceilometer_database_connection = hiera('ceilometer_mysql_conn_string')
1009     }
1010     default: {
1011       $mongo_node_string = join($mongo_node_ips_with_port, ',')
1012       $ceilometer_database_connection = "mongodb://${mongo_node_string}/ceilometer?replicaSet=${mongodb_replset}"
1013     }
1014   }
1015   include ::ceilometer
1016   include ::ceilometer::config
1017   class { '::ceilometer::api' :
1018     manage_service => false,
1019     enabled        => false,
1020   }
1021   class { '::ceilometer::agent::notification' :
1022     manage_service => false,
1023     enabled        => false,
1024   }
1025   class { '::ceilometer::agent::central' :
1026     manage_service => false,
1027     enabled        => false,
1028   }
1029   class { '::ceilometer::collector' :
1030     manage_service => false,
1031     enabled        => false,
1032   }
1033   include ::ceilometer::expirer
1034   class { '::ceilometer::db' :
1035     database_connection => $ceilometer_database_connection,
1036     sync_db             => $sync_db,
1037   }
1038   include ::ceilometer::agent::auth
1039
1040   Cron <| title == 'ceilometer-expirer' |> { command => "sleep $((\$(od -A n -t d -N 3 /dev/urandom) % 86400)) && ${::ceilometer::params::expirer_command}" }
1041
1042   # Heat
1043   include ::heat::config
1044   class { '::heat' :
1045     sync_db             => $sync_db,
1046     notification_driver => 'messaging',
1047   }
1048   class { '::heat::api' :
1049     manage_service => false,
1050     enabled        => false,
1051   }
1052   class { '::heat::api_cfn' :
1053     manage_service => false,
1054     enabled        => false,
1055   }
1056   class { '::heat::api_cloudwatch' :
1057     manage_service => false,
1058     enabled        => false,
1059   }
1060   class { '::heat::engine' :
1061     manage_service => false,
1062     enabled        => false,
1063   }
1064
1065   # httpd/apache and horizon
1066   # NOTE(gfidente): server-status can be consumed by the pacemaker resource agent
1067   class { '::apache' :
1068     service_enable => false,
1069     # service_manage => false, # <-- not supported with horizon&apache mod_wsgi?
1070   }
1071   include ::keystone::wsgi::apache
1072   include ::apache::mod::status
1073   if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
1074     $_profile_support = 'cisco'
1075   } else {
1076     $_profile_support = 'None'
1077   }
1078   $neutron_options   = {'profile_support' => $_profile_support }
1079   class { '::horizon':
1080     cache_server_ip => hiera('memcache_node_ips', '127.0.0.1'),
1081     neutron_options => $neutron_options,
1082   }
1083
1084   # Aodh
1085   class { '::aodh' :
1086     database_connection => $ceilometer_database_connection,
1087   }
1088   include ::aodh::config
1089   include ::aodh::auth
1090   include ::aodh::client
1091   include ::aodh::wsgi::apache
1092   class { '::aodh::api':
1093     manage_service => false,
1094     enabled        => false,
1095     service_name   => 'httpd',
1096   }
1097   class { '::aodh::evaluator':
1098     manage_service => false,
1099     enabled        => false,
1100   }
1101   class { '::aodh::notifier':
1102     manage_service => false,
1103     enabled        => false,
1104   }
1105   class { '::aodh::listener':
1106     manage_service => false,
1107     enabled        => false,
1108   }
1109
1110   $snmpd_user = hiera('snmpd_readonly_user_name')
1111   snmp::snmpv3_user { $snmpd_user:
1112     authtype => 'MD5',
1113     authpass => hiera('snmpd_readonly_user_password'),
1114   }
1115   class { '::snmp':
1116     agentaddress => ['udp:161','udp6:[::1]:161'],
1117     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' ],
1118   }
1119
1120   hiera_include('controller_classes')
1121
1122 } #END STEP 3
1123
1124 if hiera('step') >= 4 {
1125   $keystone_enable_db_purge = hiera('keystone_enable_db_purge', true)
1126   $nova_enable_db_purge = hiera('nova_enable_db_purge', true)
1127   $cinder_enable_db_purge = hiera('cinder_enable_db_purge', true)
1128   $heat_enable_db_purge = hiera('heat_enable_db_purge', true)
1129
1130   if $keystone_enable_db_purge {
1131     include ::keystone::cron::token_flush
1132   }
1133   if $nova_enable_db_purge {
1134     include ::nova::cron::archive_deleted_rows
1135   }
1136   if $cinder_enable_db_purge {
1137     include ::cinder::cron::db_purge
1138   }
1139   if $heat_enable_db_purge {
1140     include ::heat::cron::purge_deleted
1141   }
1142
1143   if $pacemaker_master {
1144
1145     if $enable_load_balancer {
1146       pacemaker::constraint::base { 'haproxy-then-keystone-constraint':
1147         constraint_type => 'order',
1148         first_resource  => 'haproxy-clone',
1149         second_resource => "${::apache::params::service_name}-clone",
1150         first_action    => 'start',
1151         second_action   => 'start',
1152         require         => [Pacemaker::Resource::Service['haproxy'],
1153                             Pacemaker::Resource::Service[$::apache::params::service_name]],
1154       }
1155     }
1156     pacemaker::constraint::base { 'rabbitmq-then-keystone-constraint':
1157       constraint_type => 'order',
1158       first_resource  => 'rabbitmq-clone',
1159       second_resource => "${::apache::params::service_name}-clone",
1160       first_action    => 'start',
1161       second_action   => 'start',
1162       require         => [Pacemaker::Resource::Ocf['rabbitmq'],
1163                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1164     }
1165     pacemaker::constraint::base { 'memcached-then-keystone-constraint':
1166       constraint_type => 'order',
1167       first_resource  => 'memcached-clone',
1168       second_resource => "${::apache::params::service_name}-clone",
1169       first_action    => 'start',
1170       second_action   => 'start',
1171       require         => [Pacemaker::Resource::Service['memcached'],
1172                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1173     }
1174     pacemaker::constraint::base { 'galera-then-keystone-constraint':
1175       constraint_type => 'order',
1176       first_resource  => 'galera-master',
1177       second_resource => "${::apache::params::service_name}-clone",
1178       first_action    => 'promote',
1179       second_action   => 'start',
1180       require         => [Pacemaker::Resource::Ocf['galera'],
1181                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1182     }
1183
1184     # Cinder
1185     pacemaker::resource::service { $::cinder::params::api_service :
1186       clone_params => 'interleave=true',
1187       require      => Pacemaker::Resource::Service[$::apache::params::service_name],
1188     }
1189     pacemaker::resource::service { $::cinder::params::scheduler_service :
1190       clone_params => 'interleave=true',
1191     }
1192     pacemaker::resource::service { $::cinder::params::volume_service : }
1193
1194     pacemaker::constraint::base { 'keystone-then-cinder-api-constraint':
1195       constraint_type => 'order',
1196       first_resource  => "${::apache::params::service_name}-clone",
1197       second_resource => "${::cinder::params::api_service}-clone",
1198       first_action    => 'start',
1199       second_action   => 'start',
1200       require         => [Pacemaker::Resource::Service[$::cinder::params::api_service],
1201                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1202     }
1203     pacemaker::constraint::base { 'cinder-api-then-cinder-scheduler-constraint':
1204       constraint_type => 'order',
1205       first_resource  => "${::cinder::params::api_service}-clone",
1206       second_resource => "${::cinder::params::scheduler_service}-clone",
1207       first_action    => 'start',
1208       second_action   => 'start',
1209       require         => [Pacemaker::Resource::Service[$::cinder::params::api_service],
1210                           Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
1211     }
1212     pacemaker::constraint::colocation { 'cinder-scheduler-with-cinder-api-colocation':
1213       source  => "${::cinder::params::scheduler_service}-clone",
1214       target  => "${::cinder::params::api_service}-clone",
1215       score   => 'INFINITY',
1216       require => [Pacemaker::Resource::Service[$::cinder::params::api_service],
1217                   Pacemaker::Resource::Service[$::cinder::params::scheduler_service]],
1218     }
1219     pacemaker::constraint::base { 'cinder-scheduler-then-cinder-volume-constraint':
1220       constraint_type => 'order',
1221       first_resource  => "${::cinder::params::scheduler_service}-clone",
1222       second_resource => $::cinder::params::volume_service,
1223       first_action    => 'start',
1224       second_action   => 'start',
1225       require         => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
1226                           Pacemaker::Resource::Service[$::cinder::params::volume_service]],
1227     }
1228     pacemaker::constraint::colocation { 'cinder-volume-with-cinder-scheduler-colocation':
1229       source  => $::cinder::params::volume_service,
1230       target  => "${::cinder::params::scheduler_service}-clone",
1231       score   => 'INFINITY',
1232       require => [Pacemaker::Resource::Service[$::cinder::params::scheduler_service],
1233                   Pacemaker::Resource::Service[$::cinder::params::volume_service]],
1234     }
1235
1236     # Sahara
1237     pacemaker::resource::service { $::sahara::params::api_service_name :
1238       clone_params => 'interleave=true',
1239       require      => Pacemaker::Resource::Service[$::apache::params::service_name],
1240     }
1241     pacemaker::resource::service { $::sahara::params::engine_service_name :
1242       clone_params => 'interleave=true',
1243     }
1244     pacemaker::constraint::base { 'keystone-then-sahara-api-constraint':
1245       constraint_type => 'order',
1246       first_resource  => "${::apache::params::service_name}-clone",
1247       second_resource => "${::sahara::params::api_service_name}-clone",
1248       first_action    => 'start',
1249       second_action   => 'start',
1250       require         => [Pacemaker::Resource::Service[$::sahara::params::api_service_name],
1251                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1252     }
1253
1254     # Glance
1255     pacemaker::resource::service { $::glance::params::registry_service_name :
1256       clone_params => 'interleave=true',
1257       require      => Pacemaker::Resource::Service[$::apache::params::service_name],
1258     }
1259     pacemaker::resource::service { $::glance::params::api_service_name :
1260       clone_params => 'interleave=true',
1261     }
1262
1263     pacemaker::constraint::base { 'keystone-then-glance-registry-constraint':
1264       constraint_type => 'order',
1265       first_resource  => "${::apache::params::service_name}-clone",
1266       second_resource => "${::glance::params::registry_service_name}-clone",
1267       first_action    => 'start',
1268       second_action   => 'start',
1269       require         => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
1270                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1271     }
1272     pacemaker::constraint::base { 'glance-registry-then-glance-api-constraint':
1273       constraint_type => 'order',
1274       first_resource  => "${::glance::params::registry_service_name}-clone",
1275       second_resource => "${::glance::params::api_service_name}-clone",
1276       first_action    => 'start',
1277       second_action   => 'start',
1278       require         => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
1279                           Pacemaker::Resource::Service[$::glance::params::api_service_name]],
1280     }
1281     pacemaker::constraint::colocation { 'glance-api-with-glance-registry-colocation':
1282       source  => "${::glance::params::api_service_name}-clone",
1283       target  => "${::glance::params::registry_service_name}-clone",
1284       score   => 'INFINITY',
1285       require => [Pacemaker::Resource::Service[$::glance::params::registry_service_name],
1286                   Pacemaker::Resource::Service[$::glance::params::api_service_name]],
1287     }
1288
1289     if hiera('step') == 4 {
1290       # Neutron
1291       # NOTE(gfidente): Neutron will try to populate the database with some data
1292       # as soon as neutron-server is started; to avoid races we want to make this
1293       # happen only on one node, before normal Pacemaker initialization
1294       # https://bugzilla.redhat.com/show_bug.cgi?id=1233061
1295       # NOTE(emilien): we need to run this Exec only at Step 4 otherwise this exec
1296       # will try to start the service while it's already started by Pacemaker
1297       # It would result to a deployment failure since systemd would return 1 to Puppet
1298       # and the overcloud would fail to deploy (6 would be returned).
1299       # This conditional prevents from a race condition during the deployment.
1300       # https://bugzilla.redhat.com/show_bug.cgi?id=1290582
1301       exec { 'neutron-server-systemd-start-sleep' :
1302         command => 'systemctl start neutron-server && /usr/bin/sleep 5',
1303         path    => '/usr/bin',
1304         unless  => '/sbin/pcs resource show neutron-server',
1305       } ->
1306       pacemaker::resource::service { $::neutron::params::server_service:
1307         clone_params => 'interleave=true',
1308         require      => Pacemaker::Resource::Service[$::apache::params::service_name]
1309       }
1310     } else {
1311       pacemaker::resource::service { $::neutron::params::server_service:
1312         clone_params => 'interleave=true',
1313         require      => Pacemaker::Resource::Service[$::apache::params::service_name]
1314       }
1315     }
1316     if hiera('neutron::enable_l3_agent', true) {
1317       pacemaker::resource::service { $::neutron::params::l3_agent_service:
1318         clone_params => 'interleave=true',
1319       }
1320     }
1321     if hiera('neutron::enable_dhcp_agent', true) {
1322       pacemaker::resource::service { $::neutron::params::dhcp_agent_service:
1323         clone_params => 'interleave=true',
1324       }
1325     }
1326     if hiera('neutron::enable_ovs_agent', true) {
1327       pacemaker::resource::service { $::neutron::params::ovs_agent_service:
1328         clone_params => 'interleave=true',
1329       }
1330     }
1331     if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
1332       pacemaker::resource::service {'tomcat':
1333         clone_params => 'interleave=true',
1334       }
1335     }
1336     if hiera('neutron::enable_metadata_agent', true) {
1337       pacemaker::resource::service { $::neutron::params::metadata_agent_service:
1338         clone_params => 'interleave=true',
1339       }
1340     }
1341     if hiera('neutron::enable_ovs_agent', true) {
1342       pacemaker::resource::ocf { $::neutron::params::ovs_cleanup_service:
1343         ocf_agent_name => 'neutron:OVSCleanup',
1344         clone_params   => 'interleave=true',
1345       }
1346       pacemaker::resource::ocf { 'neutron-netns-cleanup':
1347         ocf_agent_name => 'neutron:NetnsCleanup',
1348         clone_params   => 'interleave=true',
1349       }
1350
1351       # neutron - one chain ovs-cleanup-->netns-cleanup-->ovs-agent
1352       pacemaker::constraint::base { 'neutron-ovs-cleanup-to-netns-cleanup-constraint':
1353         constraint_type => 'order',
1354         first_resource  => "${::neutron::params::ovs_cleanup_service}-clone",
1355         second_resource => 'neutron-netns-cleanup-clone',
1356         first_action    => 'start',
1357         second_action   => 'start',
1358         require         => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1359                             Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1360       }
1361       pacemaker::constraint::colocation { 'neutron-ovs-cleanup-to-netns-cleanup-colocation':
1362         source  => 'neutron-netns-cleanup-clone',
1363         target  => "${::neutron::params::ovs_cleanup_service}-clone",
1364         score   => 'INFINITY',
1365         require => [Pacemaker::Resource::Ocf[$::neutron::params::ovs_cleanup_service],
1366                     Pacemaker::Resource::Ocf['neutron-netns-cleanup']],
1367       }
1368       pacemaker::constraint::base { 'neutron-netns-cleanup-to-openvswitch-agent-constraint':
1369         constraint_type => 'order',
1370         first_resource  => 'neutron-netns-cleanup-clone',
1371         second_resource => "${::neutron::params::ovs_agent_service}-clone",
1372         first_action    => 'start',
1373         second_action   => 'start',
1374         require         => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1375                             Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1376       }
1377       pacemaker::constraint::colocation { 'neutron-netns-cleanup-to-openvswitch-agent-colocation':
1378         source  => "${::neutron::params::ovs_agent_service}-clone",
1379         target  => 'neutron-netns-cleanup-clone',
1380         score   => 'INFINITY',
1381         require => [Pacemaker::Resource::Ocf['neutron-netns-cleanup'],
1382                     Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1383       }
1384     }
1385     pacemaker::constraint::base { 'keystone-to-neutron-server-constraint':
1386       constraint_type   => 'order',
1387       first_resource    => "${::apache::params::service_name}-clone",
1388         second_resource => "${::neutron::params::server_service}-clone",
1389         first_action    => 'start',
1390         second_action   => 'start',
1391         require         => [Pacemaker::Resource::Service[$::apache::params::service_name],
1392                             Pacemaker::Resource::Service[$::neutron::params::server_service]],
1393       }
1394     if hiera('neutron::enable_ovs_agent',true) {
1395       pacemaker::constraint::base { 'neutron-openvswitch-agent-to-dhcp-agent-constraint':
1396         constraint_type => 'order',
1397         first_resource  => "${::neutron::params::ovs_agent_service}-clone",
1398         second_resource => "${::neutron::params::dhcp_agent_service}-clone",
1399         first_action    => 'start',
1400         second_action   => 'start',
1401         require         => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
1402                             Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1403       }
1404     }
1405     if hiera('neutron::enable_dhcp_agent',true) and hiera('neutron::enable_ovs_agent',true) {
1406       pacemaker::constraint::base { 'neutron-server-to-openvswitch-agent-constraint':
1407         constraint_type => 'order',
1408         first_resource  => "${::neutron::params::server_service}-clone",
1409         second_resource => "${::neutron::params::ovs_agent_service}-clone",
1410         first_action    => 'start',
1411         second_action   => 'start',
1412         require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
1413                             Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service]],
1414     }
1415
1416       pacemaker::constraint::colocation { 'neutron-openvswitch-agent-to-dhcp-agent-colocation':
1417         source  => "${::neutron::params::dhcp_agent_service}-clone",
1418         target  => "${::neutron::params::ovs_agent_service}-clone",
1419         score   => 'INFINITY',
1420         require => [Pacemaker::Resource::Service[$::neutron::params::ovs_agent_service],
1421                     Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1422       }
1423     }
1424     if hiera('neutron::enable_dhcp_agent',true) and hiera('l3_agent_service',true) {
1425       pacemaker::constraint::base { 'neutron-dhcp-agent-to-l3-agent-constraint':
1426         constraint_type => 'order',
1427         first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
1428         second_resource => "${::neutron::params::l3_agent_service}-clone",
1429         first_action    => 'start',
1430         second_action   => 'start',
1431         require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1432                             Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]]
1433       }
1434       pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-l3-agent-colocation':
1435         source  => "${::neutron::params::l3_agent_service}-clone",
1436         target  => "${::neutron::params::dhcp_agent_service}-clone",
1437         score   => 'INFINITY',
1438         require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1439                     Pacemaker::Resource::Service[$::neutron::params::l3_agent_service]]
1440       }
1441     }
1442     if hiera('neutron::enable_l3_agent',true) and hiera('neutron::enable_metadata_agent',true) {
1443       pacemaker::constraint::base { 'neutron-l3-agent-to-metadata-agent-constraint':
1444         constraint_type => 'order',
1445         first_resource  => "${::neutron::params::l3_agent_service}-clone",
1446         second_resource => "${::neutron::params::metadata_agent_service}-clone",
1447         first_action    => 'start',
1448         second_action   => 'start',
1449         require         => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1450                             Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]]
1451       }
1452       pacemaker::constraint::colocation { 'neutron-l3-agent-to-metadata-agent-colocation':
1453         source  => "${::neutron::params::metadata_agent_service}-clone",
1454         target  => "${::neutron::params::l3_agent_service}-clone",
1455         score   => 'INFINITY',
1456         require => [Pacemaker::Resource::Service[$::neutron::params::l3_agent_service],
1457                     Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]]
1458       }
1459     }
1460     if hiera('neutron::core_plugin') == 'midonet.neutron.plugin_v1.MidonetPluginV2' {
1461       #midonet-chain chain keystone-->neutron-server-->dhcp-->metadata->tomcat
1462       pacemaker::constraint::base { 'neutron-server-to-dhcp-agent-constraint':
1463         constraint_type => 'order',
1464         first_resource  => "${::neutron::params::server_service}-clone",
1465         second_resource => "${::neutron::params::dhcp_agent_service}-clone",
1466         first_action    => 'start',
1467         second_action   => 'start',
1468         require         => [Pacemaker::Resource::Service[$::neutron::params::server_service],
1469                             Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service]],
1470       }
1471       pacemaker::constraint::base { 'neutron-dhcp-agent-to-metadata-agent-constraint':
1472         constraint_type => 'order',
1473         first_resource  => "${::neutron::params::dhcp_agent_service}-clone",
1474         second_resource => "${::neutron::params::metadata_agent_service}-clone",
1475         first_action    => 'start',
1476         second_action   => 'start',
1477         require         => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1478                             Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1479       }
1480       pacemaker::constraint::base { 'neutron-metadata-agent-to-tomcat-constraint':
1481         constraint_type => 'order',
1482         first_resource  => "${::neutron::params::metadata_agent_service}-clone",
1483         second_resource => 'tomcat-clone',
1484         first_action    => 'start',
1485         second_action   => 'start',
1486         require         => [Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service],
1487                             Pacemaker::Resource::Service['tomcat']],
1488       }
1489       pacemaker::constraint::colocation { 'neutron-dhcp-agent-to-metadata-agent-colocation':
1490         source  => "${::neutron::params::metadata_agent_service}-clone",
1491         target  => "${::neutron::params::dhcp_agent_service}-clone",
1492         score   => 'INFINITY',
1493         require => [Pacemaker::Resource::Service[$::neutron::params::dhcp_agent_service],
1494                     Pacemaker::Resource::Service[$::neutron::params::metadata_agent_service]],
1495       }
1496     }
1497
1498     # Nova
1499     pacemaker::resource::service { $::nova::params::api_service_name :
1500       clone_params => 'interleave=true',
1501     }
1502     pacemaker::resource::service { $::nova::params::conductor_service_name :
1503       clone_params => 'interleave=true',
1504     }
1505     pacemaker::resource::service { $::nova::params::consoleauth_service_name :
1506       clone_params => 'interleave=true',
1507       require      => Pacemaker::Resource::Service[$::apache::params::service_name],
1508     }
1509     pacemaker::resource::service { $::nova::params::vncproxy_service_name :
1510       clone_params => 'interleave=true',
1511     }
1512     pacemaker::resource::service { $::nova::params::scheduler_service_name :
1513       clone_params => 'interleave=true',
1514     }
1515
1516     pacemaker::constraint::base { 'keystone-then-nova-consoleauth-constraint':
1517       constraint_type => 'order',
1518       first_resource  => "${::apache::params::service_name}-clone",
1519       second_resource => "${::nova::params::consoleauth_service_name}-clone",
1520       first_action    => 'start',
1521       second_action   => 'start',
1522       require         => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1523                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1524     }
1525     pacemaker::constraint::base { 'nova-consoleauth-then-nova-vncproxy-constraint':
1526       constraint_type => 'order',
1527       first_resource  => "${::nova::params::consoleauth_service_name}-clone",
1528       second_resource => "${::nova::params::vncproxy_service_name}-clone",
1529       first_action    => 'start',
1530       second_action   => 'start',
1531       require         => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1532                           Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1533     }
1534     pacemaker::constraint::colocation { 'nova-vncproxy-with-nova-consoleauth-colocation':
1535       source  => "${::nova::params::vncproxy_service_name}-clone",
1536       target  => "${::nova::params::consoleauth_service_name}-clone",
1537       score   => 'INFINITY',
1538       require => [Pacemaker::Resource::Service[$::nova::params::consoleauth_service_name],
1539                   Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name]],
1540     }
1541     pacemaker::constraint::base { 'nova-vncproxy-then-nova-api-constraint':
1542       constraint_type => 'order',
1543       first_resource  => "${::nova::params::vncproxy_service_name}-clone",
1544       second_resource => "${::nova::params::api_service_name}-clone",
1545       first_action    => 'start',
1546       second_action   => 'start',
1547       require         => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1548                           Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1549     }
1550     pacemaker::constraint::colocation { 'nova-api-with-nova-vncproxy-colocation':
1551       source  => "${::nova::params::api_service_name}-clone",
1552       target  => "${::nova::params::vncproxy_service_name}-clone",
1553       score   => 'INFINITY',
1554       require => [Pacemaker::Resource::Service[$::nova::params::vncproxy_service_name],
1555                   Pacemaker::Resource::Service[$::nova::params::api_service_name]],
1556     }
1557     pacemaker::constraint::base { 'nova-api-then-nova-scheduler-constraint':
1558       constraint_type => 'order',
1559       first_resource  => "${::nova::params::api_service_name}-clone",
1560       second_resource => "${::nova::params::scheduler_service_name}-clone",
1561       first_action    => 'start',
1562       second_action   => 'start',
1563       require         => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1564                           Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1565     }
1566     pacemaker::constraint::colocation { 'nova-scheduler-with-nova-api-colocation':
1567       source  => "${::nova::params::scheduler_service_name}-clone",
1568       target  => "${::nova::params::api_service_name}-clone",
1569       score   => 'INFINITY',
1570       require => [Pacemaker::Resource::Service[$::nova::params::api_service_name],
1571                   Pacemaker::Resource::Service[$::nova::params::scheduler_service_name]],
1572     }
1573     pacemaker::constraint::base { 'nova-scheduler-then-nova-conductor-constraint':
1574       constraint_type => 'order',
1575       first_resource  => "${::nova::params::scheduler_service_name}-clone",
1576       second_resource => "${::nova::params::conductor_service_name}-clone",
1577       first_action    => 'start',
1578       second_action   => 'start',
1579       require         => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1580                           Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1581     }
1582     pacemaker::constraint::colocation { 'nova-conductor-with-nova-scheduler-colocation':
1583       source  => "${::nova::params::conductor_service_name}-clone",
1584       target  => "${::nova::params::scheduler_service_name}-clone",
1585       score   => 'INFINITY',
1586       require => [Pacemaker::Resource::Service[$::nova::params::scheduler_service_name],
1587                   Pacemaker::Resource::Service[$::nova::params::conductor_service_name]],
1588     }
1589
1590     # Ceilometer and Aodh
1591     case downcase(hiera('ceilometer_backend')) {
1592       /mysql/: {
1593         pacemaker::resource::service { $::ceilometer::params::agent_central_service_name :
1594           clone_params => 'interleave=true',
1595           require      => Pacemaker::Resource::Service[$::apache::params::service_name],
1596         }
1597       }
1598       default: {
1599         pacemaker::resource::service { $::ceilometer::params::agent_central_service_name :
1600           clone_params => 'interleave=true',
1601           require      => [Pacemaker::Resource::Service[$::apache::params::service_name],
1602           Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1603         }
1604       }
1605     }
1606     pacemaker::resource::service { $::ceilometer::params::collector_service_name :
1607       clone_params => 'interleave=true',
1608     }
1609     pacemaker::resource::service { $::ceilometer::params::api_service_name :
1610       clone_params => 'interleave=true',
1611     }
1612     pacemaker::resource::service { $::ceilometer::params::agent_notification_service_name :
1613       clone_params => 'interleave=true',
1614     }
1615     pacemaker::resource::ocf { 'delay' :
1616       ocf_agent_name  => 'heartbeat:Delay',
1617       clone_params    => 'interleave=true',
1618       resource_params => 'startdelay=10',
1619     }
1620     # Fedora doesn't know `require-all` parameter for constraints yet
1621     if $::operatingsystem == 'Fedora' {
1622       $redis_ceilometer_constraint_params = undef
1623       $redis_aodh_constraint_params = undef
1624     } else {
1625       $redis_ceilometer_constraint_params = 'require-all=false'
1626       $redis_aodh_constraint_params = 'require-all=false'
1627     }
1628     pacemaker::constraint::base { 'redis-then-ceilometer-central-constraint':
1629       constraint_type   => 'order',
1630       first_resource    => 'redis-master',
1631       second_resource   => "${::ceilometer::params::agent_central_service_name}-clone",
1632       first_action      => 'promote',
1633       second_action     => 'start',
1634       constraint_params => $redis_ceilometer_constraint_params,
1635       require           => [Pacemaker::Resource::Ocf['redis'],
1636                             Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name]],
1637     }
1638     pacemaker::constraint::base { 'redis-then-aodh-evaluator-constraint':
1639       constraint_type   => 'order',
1640       first_resource    => 'redis-master',
1641       second_resource   => "${::aodh::params::evaluator_service_name}-clone",
1642       first_action      => 'promote',
1643       second_action     => 'start',
1644       constraint_params => $redis_aodh_constraint_params,
1645       require           => [Pacemaker::Resource::Ocf['redis'],
1646                             Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name]],
1647     }
1648     pacemaker::constraint::base { 'keystone-then-ceilometer-central-constraint':
1649       constraint_type => 'order',
1650       first_resource  => "${::apache::params::service_name}-clone",
1651       second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1652       first_action    => 'start',
1653       second_action   => 'start',
1654       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1655                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1656     }
1657     pacemaker::constraint::base { 'ceilometer-central-then-ceilometer-collector-constraint':
1658       constraint_type => 'order',
1659       first_resource  => "${::ceilometer::params::agent_central_service_name}-clone",
1660       second_resource => "${::ceilometer::params::collector_service_name}-clone",
1661       first_action    => 'start',
1662       second_action   => 'start',
1663       require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1664                           Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1665     }
1666     pacemaker::constraint::base { 'ceilometer-collector-then-ceilometer-api-constraint':
1667       constraint_type => 'order',
1668       first_resource  => "${::ceilometer::params::collector_service_name}-clone",
1669       second_resource => "${::ceilometer::params::api_service_name}-clone",
1670       first_action    => 'start',
1671       second_action   => 'start',
1672       require         => [Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name],
1673                           Pacemaker::Resource::Service[$::ceilometer::params::api_service_name]],
1674     }
1675     pacemaker::constraint::colocation { 'ceilometer-api-with-ceilometer-collector-colocation':
1676       source  => "${::ceilometer::params::api_service_name}-clone",
1677       target  => "${::ceilometer::params::collector_service_name}-clone",
1678       score   => 'INFINITY',
1679       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1680                   Pacemaker::Resource::Service[$::ceilometer::params::collector_service_name]],
1681     }
1682     pacemaker::constraint::base { 'ceilometer-api-then-ceilometer-delay-constraint':
1683       constraint_type => 'order',
1684       first_resource  => "${::ceilometer::params::api_service_name}-clone",
1685       second_resource => 'delay-clone',
1686       first_action    => 'start',
1687       second_action   => 'start',
1688       require         => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1689                           Pacemaker::Resource::Ocf['delay']],
1690     }
1691     pacemaker::constraint::colocation { 'ceilometer-delay-with-ceilometer-api-colocation':
1692       source  => 'delay-clone',
1693       target  => "${::ceilometer::params::api_service_name}-clone",
1694       score   => 'INFINITY',
1695       require => [Pacemaker::Resource::Service[$::ceilometer::params::api_service_name],
1696                   Pacemaker::Resource::Ocf['delay']],
1697     }
1698     # Aodh
1699     pacemaker::resource::service { $::aodh::params::api_service_name :
1700       clone_params => 'interleave=true',
1701     }
1702     pacemaker::resource::service { $::aodh::params::evaluator_service_name :
1703       clone_params => 'interleave=true',
1704     }
1705     pacemaker::resource::service { $::aodh::params::notifier_service_name :
1706       clone_params => 'interleave=true',
1707     }
1708     pacemaker::resource::service { $::aodh::params::listener_service_name :
1709       clone_params => 'interleave=true',
1710     }
1711     pacemaker::constraint::base { 'keystone-then-aodh-api-constraint':
1712       constraint_type => 'order',
1713       first_resource  => "${::apache::params::service_name}-clone",
1714       second_resource => "${::aodh::params::api_service_name}-clone",
1715       first_action    => 'start',
1716       second_action   => 'start',
1717       require         => [Pacemaker::Resource::Service[$::aodh::params::api_service_name],
1718                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1719     }
1720     pacemaker::constraint::base { 'aodh-delay-then-aodh-evaluator-constraint':
1721       constraint_type => 'order',
1722       first_resource  => 'delay-clone',
1723       second_resource => "${::aodh::params::evaluator_service_name}-clone",
1724       first_action    => 'start',
1725       second_action   => 'start',
1726       require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1727                           Pacemaker::Resource::Ocf['delay']],
1728     }
1729     pacemaker::constraint::colocation { 'aodh-evaluator-with-aodh-delay-colocation':
1730       source  => "${::aodh::params::evaluator_service_name}-clone",
1731       target  => 'delay-clone',
1732       score   => 'INFINITY',
1733       require => [Pacemaker::Resource::Service[$::horizon::params::http_service],
1734                   Pacemaker::Resource::Ocf['delay']],
1735     }
1736     pacemaker::constraint::base { 'aodh-evaluator-then-aodh-notifier-constraint':
1737       constraint_type => 'order',
1738       first_resource  => "${::aodh::params::evaluator_service_name}-clone",
1739       second_resource => "${::aodh::params::notifier_service_name}-clone",
1740       first_action    => 'start',
1741       second_action   => 'start',
1742       require         => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1743                           Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1744     }
1745     pacemaker::constraint::colocation { 'aodh-notifier-with-aodh-evaluator-colocation':
1746       source  => "${::aodh::params::notifier_service_name}-clone",
1747       target  => "${::aodh::params::evaluator_service_name}-clone",
1748       score   => 'INFINITY',
1749       require => [Pacemaker::Resource::Service[$::aodh::params::evaluator_service_name],
1750                   Pacemaker::Resource::Service[$::aodh::params::notifier_service_name]],
1751     }
1752     if downcase(hiera('ceilometer_backend')) == 'mongodb' {
1753       pacemaker::constraint::base { 'mongodb-then-ceilometer-central-constraint':
1754         constraint_type => 'order',
1755         first_resource  => "${::mongodb::params::service_name}-clone",
1756         second_resource => "${::ceilometer::params::agent_central_service_name}-clone",
1757         first_action    => 'start',
1758         second_action   => 'start',
1759         require         => [Pacemaker::Resource::Service[$::ceilometer::params::agent_central_service_name],
1760                             Pacemaker::Resource::Service[$::mongodb::params::service_name]],
1761       }
1762     }
1763
1764     # Heat
1765     pacemaker::resource::service { $::heat::params::api_service_name :
1766       clone_params => 'interleave=true',
1767     }
1768     pacemaker::resource::service { $::heat::params::api_cloudwatch_service_name :
1769       clone_params => 'interleave=true',
1770     }
1771     pacemaker::resource::service { $::heat::params::api_cfn_service_name :
1772       clone_params => 'interleave=true',
1773     }
1774     pacemaker::resource::service { $::heat::params::engine_service_name :
1775       clone_params => 'interleave=true',
1776     }
1777     pacemaker::constraint::base { 'keystone-then-heat-api-constraint':
1778       constraint_type => 'order',
1779       first_resource  => "${::apache::params::service_name}-clone",
1780       second_resource => "${::heat::params::api_service_name}-clone",
1781       first_action    => 'start',
1782       second_action   => 'start',
1783       require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1784                           Pacemaker::Resource::Service[$::apache::params::service_name]],
1785     }
1786     pacemaker::constraint::base { 'heat-api-then-heat-api-cfn-constraint':
1787       constraint_type => 'order',
1788       first_resource  => "${::heat::params::api_service_name}-clone",
1789       second_resource => "${::heat::params::api_cfn_service_name}-clone",
1790       first_action    => 'start',
1791       second_action   => 'start',
1792       require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1793                           Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
1794     }
1795     pacemaker::constraint::colocation { 'heat-api-cfn-with-heat-api-colocation':
1796       source  => "${::heat::params::api_cfn_service_name}-clone",
1797       target  => "${::heat::params::api_service_name}-clone",
1798       score   => 'INFINITY',
1799       require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
1800                   Pacemaker::Resource::Service[$::heat::params::api_service_name]],
1801     }
1802     pacemaker::constraint::base { 'heat-api-cfn-then-heat-api-cloudwatch-constraint':
1803       constraint_type => 'order',
1804       first_resource  => "${::heat::params::api_cfn_service_name}-clone",
1805       second_resource => "${::heat::params::api_cloudwatch_service_name}-clone",
1806       first_action    => 'start',
1807       second_action   => 'start',
1808       require         => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1809                           Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name]],
1810     }
1811     pacemaker::constraint::colocation { 'heat-api-cloudwatch-with-heat-api-cfn-colocation':
1812       source  => "${::heat::params::api_cloudwatch_service_name}-clone",
1813       target  => "${::heat::params::api_cfn_service_name}-clone",
1814       score   => 'INFINITY',
1815       require => [Pacemaker::Resource::Service[$::heat::params::api_cfn_service_name],
1816                   Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name]],
1817     }
1818     pacemaker::constraint::base { 'heat-api-cloudwatch-then-heat-engine-constraint':
1819       constraint_type => 'order',
1820       first_resource  => "${::heat::params::api_cloudwatch_service_name}-clone",
1821       second_resource => "${::heat::params::engine_service_name}-clone",
1822       first_action    => 'start',
1823       second_action   => 'start',
1824       require         => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1825                           Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
1826     }
1827     pacemaker::constraint::colocation { 'heat-engine-with-heat-api-cloudwatch-colocation':
1828       source  => "${::heat::params::engine_service_name}-clone",
1829       target  => "${::heat::params::api_cloudwatch_service_name}-clone",
1830       score   => 'INFINITY',
1831       require => [Pacemaker::Resource::Service[$::heat::params::api_cloudwatch_service_name],
1832                   Pacemaker::Resource::Service[$::heat::params::engine_service_name]],
1833     }
1834     pacemaker::constraint::base { 'ceilometer-notification-then-heat-api-constraint':
1835       constraint_type => 'order',
1836       first_resource  => "${::ceilometer::params::agent_notification_service_name}-clone",
1837       second_resource => "${::heat::params::api_service_name}-clone",
1838       first_action    => 'start',
1839       second_action   => 'start',
1840       require         => [Pacemaker::Resource::Service[$::heat::params::api_service_name],
1841                           Pacemaker::Resource::Service[$::ceilometer::params::agent_notification_service_name]],
1842     }
1843
1844     # Horizon and Keystone
1845     pacemaker::resource::service { $::apache::params::service_name:
1846       clone_params     => 'interleave=true',
1847       verify_on_create => true,
1848       require          => [File['/etc/keystone/ssl/certs/ca.pem'],
1849       File['/etc/keystone/ssl/private/signing_key.pem'],
1850       File['/etc/keystone/ssl/certs/signing_cert.pem']],
1851     }
1852
1853     #VSM
1854     if 'cisco_n1kv' in hiera('neutron::plugins::ml2::mechanism_drivers') {
1855       pacemaker::resource::ocf { 'vsm-p' :
1856         ocf_agent_name  => 'heartbeat:VirtualDomain',
1857         resource_params => 'force_stop=true config=/var/spool/cisco/vsm/vsm_primary_deploy.xml',
1858         require         => Class['n1k_vsm'],
1859         meta_params     => 'resource-stickiness=INFINITY',
1860       }
1861       if str2bool(hiera('n1k_vsm::pacemaker_control', true)) {
1862         pacemaker::resource::ocf { 'vsm-s' :
1863           ocf_agent_name  => 'heartbeat:VirtualDomain',
1864           resource_params => 'force_stop=true config=/var/spool/cisco/vsm/vsm_secondary_deploy.xml',
1865           require         => Class['n1k_vsm'],
1866           meta_params     => 'resource-stickiness=INFINITY',
1867         }
1868         pacemaker::constraint::colocation { 'vsm-colocation-contraint':
1869           source  => 'vsm-p',
1870           target  => 'vsm-s',
1871           score   => '-INFINITY',
1872           require => [Pacemaker::Resource::Ocf['vsm-p'],
1873                       Pacemaker::Resource::Ocf['vsm-s']],
1874         }
1875       }
1876     }
1877
1878   }
1879
1880 } #END STEP 4
1881
1882 if hiera('step') >= 5 {
1883
1884   if $pacemaker_master {
1885
1886     class {'::keystone::roles::admin' :
1887       require => Pacemaker::Resource::Service[$::apache::params::service_name],
1888     } ->
1889     class {'::keystone::endpoint' :
1890       require => Pacemaker::Resource::Service[$::apache::params::service_name],
1891     }
1892   }
1893
1894 } #END STEP 5
1895
1896 $package_manifest_name = join(['/var/lib/tripleo/installed-packages/overcloud_controller_pacemaker', hiera('step')])
1897 package_manifest{$package_manifest_name: ensure => present}