Implement Aodh integration into Fuel

Key moments:
  * add aodh upstream module usage
  * implement aodh database and installation manifests
  * remove outdated ceilometer alarm agents
  * move aodh alarm evaluator engine under Pacemaker
    as it was done before for ceilometer alarm evaluator
  * setup HAProxy for aodh api service
  * keep ceilometer-alarm-evaluator ocf script and
    ceilometer_ha/alarm/evaluator class for Kilo support

Blueprint: fuel-aodh-integration
Depends-on: Idbbcb0a2c4d4c7e624a4615fc6f7c527f0020c02

Authors:
  * Dmitry Burmistrov
  * Ivan Berezovskiy

Change-Id: I8d5069514ea1aad107581dfc468bdde65d8c3a86
This commit is contained in:
Dmitry Burmistrov 2016-02-11 15:14:21 +03:00 committed by iberezovskiy
parent aa63d25519
commit 362f86c838
29 changed files with 1022 additions and 31 deletions

View File

@ -2,6 +2,7 @@ Puppetfile.lock
.tmp
# add modules being managed via librarian-puppet under here
puppet/aodh
puppet/apache
puppet/apt
puppet/ceilometer

View File

@ -206,3 +206,8 @@ mod 'mysql',
mod 'galera',
:git => 'https://github.com/fuel-infra/puppet-galera.git',
:ref => '0.0.3-rc1'
# Pull in puppet-aodh
mod 'aodh',
:git => 'https://github.com/fuel-infra/puppet-aodh.git',
:ref => 'master'

View File

@ -0,0 +1,40 @@
#
# Configure aodh-evaluator service in pacemaker/corosync
#
# == Parameters
#
# None.
#
class cluster::aodh_evaluator {
include ::aodh::params
# migration-threshold is number of tries to
# start resource on each controller node
$metadata = {
'resource-stickiness' => '1',
'migration-threshold' => '3'
}
$operations = {
'monitor' => {
'interval' => '20',
'timeout' => '30',
},
'start' => {
'interval' => '0',
'timeout' => '60',
},
'stop' => {
'interval' => '0',
'timeout' => '60',
},
}
pacemaker_wrappers::service { $::aodh::params::evaluator_service_name:
primitive_type => 'aodh-evaluator',
metadata => $metadata,
parameters => { 'user' => 'aodh' },
operations => $operations,
}
}

View File

@ -78,7 +78,7 @@ class openstack::ceilometer (
# Configure authentication for agents
class { '::ceilometer::agent::auth':
auth_url => "${keystone_protocol}://${keystone_host}:5000/v2.0",
auth_url => $keystone_auth_uri,
auth_password => $keystone_password,
auth_region => $keystone_region,
auth_tenant_name => $keystone_tenant,
@ -133,12 +133,6 @@ class openstack::ceilometer (
collector_workers => $collector_workers,
}
class { '::ceilometer::alarm::evaluator':
evaluation_interval => 60,
}
class { '::ceilometer::alarm::notifier': }
class { '::ceilometer::agent::notification':
notification_workers => $notification_workers,
store_events => true,
@ -156,22 +150,6 @@ class openstack::ceilometer (
}
}
if $ha_mode {
include ceilometer_ha::alarm::evaluator
case $::osfamily {
'RedHat': {
$alarm_package = $::ceilometer::params::alarm_package_name[0]
}
'Debian': {
$alarm_package = $::ceilometer::params::alarm_package_name[1]
}
}
Package[$::ceilometer::params::common_package_name] -> Class['ceilometer_ha::alarm::evaluator']
Package[$alarm_package] -> Class['ceilometer_ha::alarm::evaluator']
}
if ($swift_rados_backend) {
ceilometer_config {
'DEFAULT/swift_rados_backend' : value => true;
@ -184,10 +162,6 @@ class openstack::ceilometer (
}
}
Package<| title == $::ceilometer::params::alarm_package or
title == 'ceilometer-common'|> ~>
Service<| title == 'ceilometer-alarm-evaluator'|>
if ($on_compute) {
if $::operatingsystem == 'Ubuntu' and $::ceilometer::params::libvirt_group {
# Our libvirt-bin deb package (1.2.9 version) creates 'libvirt' group on Ubuntu

View File

@ -0,0 +1,79 @@
# == Class: openstack::ha::aodh
#
# HA configuration for OpenStack Aodh
#
# === Parameters
#
# [*internal_virtual_ip*]
# (required) String. This is the ipaddress to be used for the internal facing
# vip
#
# [*ipaddresses*]
# (required) Array. This is an array of ipaddresses for the backend services
# to be loadbalanced
#
# [*listen_port*]
# (optional) The aodh api port.
# Defaults to 8042
#
# [*public_ssl*]
# (optional) Boolean. If true, enables SSL for $public_virtual_ip
# Defaults to false.
#
# [*public_ssl_path*]
# (optional) String. Filesystem path to the file with public certificate
# content
# Defaults to undef
#
# [*internal_ssl*]
# (optional) Boolean. If true, enables SSL for $internal_virtual_ip
# Defaults to false.
#
# [*internal_ssl_path*]
# (optional) String. Filesystem path to the file with internal certificate
# content
# Defaults to undef
#
# [*public_virtual_ip*]
# (required) String. This is the ipaddress to be used for the external facing
# vip
#
# [*server_names*]
# (required) Array. This is an array of server names for the haproxy service
#
class openstack::ha::aodh (
$internal_virtual_ip,
$ipaddresses,
$public_virtual_ip,
$server_names,
$listen_port = '8042',
$public_ssl = false,
$public_ssl_path = undef,
$internal_ssl = false,
$internal_ssl_path = undef,
) {
# defaults for any haproxy_service within this class
Openstack::Ha::Haproxy_service {
internal_virtual_ip => $internal_virtual_ip,
ipaddresses => $ipaddresses,
public_virtual_ip => $public_virtual_ip,
server_names => $server_names,
}
openstack::ha::haproxy_service { 'aodh':
order => '135',
listen_port => $listen_port,
public => true,
public_ssl => $public_ssl,
public_ssl_path => $public_ssl_path,
internal_ssl => $internal_ssl,
internal_ssl_path => $internal_ssl_path,
require_service => 'aodh-api',
haproxy_config_options => {
'option' => ['httplog', 'forceclose'],
'http-request' => 'set-header X-Forwarded-Proto https if { ssl_fc }',
},
}
}

View File

@ -206,6 +206,11 @@ class openstack::logging (
content => template("${module_name}/51-ceilometer.conf.erb"),
}
file { "${::rsyslog::params::rsyslog_d}53-aodh.conf":
ensure => present,
content => template("${module_name}/53-aodh.conf.erb"),
}
file { "${::rsyslog::params::rsyslog_d}54-heat.conf":
ensure => present,
content => template("${module_name}/54-heat.conf.erb"),

View File

@ -48,13 +48,11 @@ describe 'openstack::ceilometer' do
it { is_expected.to contain_class('ceilometer::db') }
it { is_expected.to contain_class('ceilometer::expirer') }
it { is_expected.to contain_class('ceilometer::agent::notification') }
it { is_expected.to contain_class('ceilometer::alarm::evaluator') }
it { is_expected.to contain_class('ceilometer::collector') }
it { is_expected.to contain_class('ceilometer::alarm::notifier') }
it { is_expected.to contain_class('ceilometer::client') }
it { is_expected.to contain_class('ceilometer::agent::auth').with(
:auth_url => "#{params[:keystone_protocol]}://#{params[:keystone_host]}:5000/v2.0",
:auth_url => params[:keystone_auth_uri],
:auth_password => params[:keystone_password],
:auth_region => params[:keystone_region],
:auth_tenant_name => params[:keystone_tenant],

View File

@ -58,6 +58,7 @@ describe 'openstack::logging' do
'40-glance',
'50-neutron',
'51-ceilometer',
'53-aodh',
'54-heat',
'52-sahara',
'02-ha',

View File

@ -1,5 +1,6 @@
# managed by puppet
"/var/log/aodh/*.log"
"/var/log/audit/audit.log"
"/var/log/ceilometer/*.log"
"/var/log/cinder/*.log"

View File

@ -0,0 +1,4 @@
# managed by puppet
:syslogtag, contains, "aodh" -/var/log/aodh-all.log
&~

View File

@ -0,0 +1,184 @@
notice('MODULAR: aodh.pp')
$notification_topics = 'notifications'
$rpc_backend = 'rabbit'
$rabbit_ha_queues = hiera('rabbit_ha_queues')
$rabbit_hash = hiera_hash('rabbit_hash', {})
$rabbit_userid = pick($rabbit_hash['user'], 'nova')
$rabbit_password = $rabbit_hash['password']
$amqp_hosts = hiera('amqp_hosts')
$rabbit_port = hiera('amqp_port')
$rabbit_hosts = split($amqp_hosts, ',')
$rabbit_virtual_host = '/'
prepare_network_config(hiera_hash('network_scheme', {}))
$aodh_hash = hiera_hash('aodh', {})
$aodh_user_name = pick($aodh_hash['user'], 'aodh')
$aodh_user_password = $aodh_hash['user_password']
$service_name = pick($aodh_hash['service'], 'aodh')
$region = pick($aodh_hash['region'], hiera('region', 'RegionOne'))
$tenant = pick($aodh_hash['tenant'], 'services')
$debug = pick($aodh_hash['debug'], hiera('debug', false))
$verbose = pick($aodh_hash['verbose'], hiera('verbose', true))
$database_vip = hiera('database_vip')
$db_type = pick($aodh_hash['db_type'], 'mysql')
$db_name = pick($aodh_hash['db_name'], 'aodh')
$db_user = pick($aodh_hash['db_user'], 'aodh')
$db_password = $aodh_hash['db_password']
$db_host = pick($aodh_hash['db_host'], $database_vip)
$db_collate = pick($aodh_hash['db_collate'], 'utf8_general_ci')
$db_charset = pick($aodh_hash['db_charset'], 'utf8')
$db_allowed_hosts = pick($aodh_hash['db_allowed_hosts'], '%')
if $::os_package_type == 'debian' {
$extra_params = { 'charset' => 'utf8', 'read_timeout' => 60 }
} else {
$extra_params = { 'charset' => 'utf8' }
}
$database_connection = os_database_connection({
'dialect' => $db_type,
'host' => $db_host,
'database' => $db_name,
'username' => $db_user,
'password' => $db_password,
'extra' => $extra_params
})
$external_lb = hiera('external_lb', false)
$public_vip = hiera('public_vip')
$public_ssl_hash = hiera('public_ssl')
$public_address = $public_ssl_hash['services'] ? {
true => $public_ssl_hash['hostname'],
default => $public_vip,
}
$public_protocol = $public_ssl_hash['services'] ? {
true => 'https',
default => 'http',
}
$management_vip = hiera('management_vip')
$service_endpoint = hiera('service_endpoint')
$aodh_api_bind_port = '8042'
$aodh_api_bind_host = get_network_role_property('aodh/api', 'ipaddr')
$public_url = "${public_protocol}://${public_address}:${aodh_api_bind_port}"
$ssl_hash = hiera_hash('use_ssl', {})
$public_cert = get_ssl_property($ssl_hash, $public_ssl_hash, 'keystone', 'public', 'path', [''])
$memcache_address = get_network_role_property('mgmt/memcache', 'ipaddr')
$memcache_servers = "${memcache_address}:11211"
$internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http')
$internal_auth_address = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [$management_vip])
$keystone_auth_uri = "${internal_auth_protocol}://${internal_auth_address}:5000/"
$keystone_identity_uri = "${internal_auth_protocol}://${internal_auth_address}:35357/"
$ceilometer_hash = hiera_hash('ceilometer_hash', {})
$ha_mode = pick($ceilometer_hash['ha_mode'], true)
#################################################################
class { '::aodh':
debug => $debug,
verbose => $verbose,
notification_topics => $notification_topics,
rpc_backend => $rpc_backend,
rabbit_userid => $rabbit_userid,
rabbit_password => $rabbit_password,
rabbit_hosts => $rabbit_hosts,
rabbit_port => $rabbit_port,
rabbit_virtual_host => $rabbit_virtual_host,
rabbit_ha_queues => $rabbit_ha_queues,
database_connection => $database_connection,
}
class { 'aodh::auth':
auth_url => $keystone_auth_uri,
auth_user => $aodh_user_name,
auth_password => $aodh_user_password,
auth_region => $region,
auth_tenant_name => $tenant,
auth_cacert => $public_cert,
auth_endpoint_type => 'internalURL',
}
aodh_config { 'oslo_policy/policy_file' : value => '/etc/aodh/policy.json'; }
aodh_config { 'notification/store_events': value => true; }
if $debug {
aodh_config { 'api/pecan_debug': value => true; }
} else {
aodh_config { 'api/pecan_debug': value => false; }
}
class { 'aodh::db::sync':
user => $db_user,
}
# keystone
aodh_config {
'keystone_authtoken/memcache_servers': value => $memcache_servers;
'keystone_authtoken/signing_dir' : value => '/tmp/keystone-signing-aodh';
}
class { '::aodh::api':
enabled => true,
manage_service => true,
package_ensure => 'present',
keystone_user => $aodh_user_name,
keystone_password => $aodh_user_password,
keystone_tenant => $tenant,
keystone_auth_uri => $keystone_auth_uri,
keystone_identity_uri => $keystone_identity_uri,
host => $aodh_api_bind_host,
port => $aodh_api_bind_port,
}
$haproxy_stats_url = "http://${management_vip}:10000/;csv"
$aodh_protocol = get_ssl_property($ssl_hash, {}, 'aodh', 'internal', 'protocol', 'http')
$aodh_address = get_ssl_property($ssl_hash, {}, 'aodh', 'internal', 'hostname', [$service_endpoint, $management_vip])
$aodh_url = "${aodh_protocol}://${aodh_address}:${aodh_api_bind_port}"
$lb_defaults = { 'provider' => 'haproxy', 'url' => $haproxy_stats_url }
if $external_lb {
$lb_backend_provider = 'http'
$lb_url = $aodh_url
}
$lb_hash = {
aodh => {
name => 'aodh',
provider => $lb_backend_provider,
url => $lb_url
}
}
::osnailyfacter::wait_for_backend {'aodh':
lb_hash => $lb_hash,
lb_defaults => $lb_defaults
}
class { '::aodh::evaluator': }
class { '::aodh::notifier': }
class { '::aodh::listener': }
class { '::aodh::client': }
if $ha_mode {
include ::cluster::aodh_evaluator
Package[$::aodh::params::common_package_name] -> Class['::cluster::aodh_evaluator']
Package[$::aodh::params::evaluator_package_name] -> Class['::cluster::aodh_evaluator']
}
Service['aodh-api'] -> ::Osnailyfacter::Wait_for_backend['aodh']

View File

@ -0,0 +1,37 @@
require File.join File.dirname(__FILE__), '../test_common.rb'
PORT = 8042
PROCESSES = %w(
aodh-notifier
aodh-evaluator
aodh-listener
aodh-api
)
if TestCommon::Facts.osfamily == 'Debian'
PACEMAKER_SERVICES = %w(
p_aodh-evaluator
)
end
class AodhControllerPostTest < Test::Unit::TestCase
def test_aodh_processes_running
PROCESSES.each do |process|
assert TestCommon::Process.running?(process), "'#{process}' is not running!"
end
end
def test_haproxy_aodh_backend_online
assert TestCommon::HAProxy.backend_up?('aodh'), "HAProxy backend 'aodh' is not online!"
end
def test_pacemaker_services_running
return unless PACEMAKER_SERVICES
PACEMAKER_SERVICES.each do |service|
assert TestCommon::Pacemaker.primitive_started?(service), "Pacemaker service '#{service}' is not running!"
end
end
end

View File

@ -0,0 +1,8 @@
require File.join File.dirname(__FILE__), '../test_common.rb'
class AodhPreTest < Test::Unit::TestCase
def test_amqp_accessible
assert TestCommon::AMQP.connection?, 'Cannot connect to AMQP server!'
end
end

View File

@ -0,0 +1,45 @@
notice('MODULAR: aodh/db.pp')
$aodh_hash = hiera_hash('aodh', { 'db_password' => 'aodh' })
$database_vip = hiera('database_vip')
$db_type = pick($aodh_hash['db_type'], 'mysql')
$db_name = pick($aodh_hash['db_name'], 'aodh')
$db_user = pick($aodh_hash['db_user'], 'aodh')
$db_password = $aodh_hash['db_password']
$db_host = pick($aodh_hash['db_host'], $database_vip)
$db_collate = pick($aodh_hash['db_collate'], 'utf8_general_ci')
$db_charset = pick($aodh_hash['db_charset'], 'utf8')
$db_allowed_host = pick($aodh_hash['db_allowed_host'], '127.0.0.1')
$db_allowed_hosts = pick($aodh_hash['db_allowed_hosts'], '%')
$mysql_hash = hiera_hash('mysql_hash', {})
$mysql_root_user = pick($mysql_hash['root_user'], 'root')
$mysql_root_password = $mysql_hash['root_password']
$db_root_user = pick($aodh_hash['db_root_user'], $mysql_root_user)
$db_root_password = pick($aodh_hash['db_root_password'], $mysql_root_password)
class { '::openstack::galera::client':
custom_setup_class => hiera('mysql_custom_setup_class', 'galera'),
}
class { 'aodh::db::mysql':
user => $db_user,
password => $db_password,
dbname => $db_name,
host => $db_allowed_host,
charset => $db_charset,
collate => $db_collate,
allowed_hosts => $db_allowed_hosts,
}
class { 'osnailyfacter::mysql_access':
db_host => $db_host,
db_user => $db_root_user,
db_password => $db_root_password,
}
class mysql::config {}
include mysql::config
class mysql::server {}
include mysql::server

View File

@ -0,0 +1,44 @@
notice('MODULAR: aodh/keystone.pp')
$aodh_hash = hiera_hash('aodh', {})
$aodh_user_name = pick($aodh_hash['user'], 'aodh')
$aodh_user_password = $aodh_hash['user_password']
$service_name = pick($aodh_hash['service'], 'aodh')
$region = pick($aodh_hash['region'], hiera('region', 'RegionOne'))
$tenant = pick($aodh_hash['tenant'], 'services')
$public_vip = hiera('public_vip')
$public_ssl_hash = hiera('public_ssl')
$public_address = $public_ssl_hash['services'] ? {
true => $public_ssl_hash['hostname'],
default => $public_vip,
}
$public_protocol = $public_ssl_hash['services'] ? {
true => 'https',
default => 'http',
}
$ssl_hash = hiera_hash('use_ssl', {})
$management_vip = hiera('management_vip')
$aodh_api_bind_port = '8042'
$public_url = "${public_protocol}://${public_address}:${aodh_api_bind_port}"
$internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http')
$admin_url = "${internal_auth_protocol}://${management_vip}:${aodh_api_bind_port}"
#################################################################
Class['::osnailyfacter::wait_for_keystone_backends'] -> Class['aodh::keystone::auth']
class {'::osnailyfacter::wait_for_keystone_backends':}
class { 'aodh::keystone::auth':
auth_name => $aodh_user_name,
password => $aodh_user_password,
service_type => 'alarming',
service_name => $service_name,
region => $region,
tenant => $tenant,
public_url => $public_url,
internal_url => $admin_url,
admin_url => $admin_url,
}

View File

@ -0,0 +1,46 @@
- id: aodh
type: puppet
version: 2.0.0
groups: [primary-controller, controller]
required_for: [ceilometer-controller, openstack-controller]
requires: [openstack-haproxy]
cross-depends:
- name: aodh-db
- name: aodh-keystone
condition: "settings:additional_components.ceilometer.value == true"
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/aodh/aodh.pp
puppet_modules: /etc/puppet/modules
timeout: 3600
test_pre:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/aodh/aodh_pre.rb
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/aodh/aodh_post.rb
- id: aodh-keystone
type: puppet
version: 2.0.0
groups: [primary-controller, controller]
required_for: [aodh]
requires: [primary-keystone, keystone]
cross-depends:
- name: keystone
condition: "settings:additional_components.ceilometer.value == true"
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/aodh/keystone.pp
puppet_modules: /etc/puppet/modules
timeout: 1800
- id: aodh-db
type: puppet
version: 2.0.0
groups: [primary-controller]
cross-depends:
- name: /(primary-)?database/
required_for: [aodh]
condition: "settings:additional_components.ceilometer.value == true"
requires: [primary-database, database]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/aodh/db.pp
puppet_modules: /etc/puppet/modules
timeout: 1800

View File

@ -5,6 +5,7 @@ $network_metadata = hiera_hash('network_metadata')
$ironic_hash = hiera_hash('ironic', {})
$roles = hiera('roles')
$aodh_port = 8042
$ceilometer_port = 8777
$corosync_input_port = 5404
$corosync_output_port = 5405
@ -314,6 +315,12 @@ if member($roles, 'primary-controller') or member($roles, 'controller') {
action => 'accept',
}
firewall {'122 aodh':
port => $aodh_port,
proto => 'tcp',
action => 'accept',
}
firewall {'204 heat-api':
port => $heat_api_port,
proto => 'tcp',

View File

@ -92,6 +92,7 @@ $syslog_log_facility_sahara = hiera('syslog_log_facility_sahara','LOG_LOCAL0
$syslog_log_facility_ceilometer = hiera('syslog_log_facility_ceilometer','LOG_LOCAL0')
$syslog_log_facility_ceph = hiera('syslog_log_facility_ceph','LOG_LOCAL0')
$syslog_log_facility_ironic = hiera('syslog_log_facility_ironic','LOG_LOCAL0')
$syslog_log_facility_aodh = hiera('syslog_log_facility_aodh','LOG_LOCAL0')
$nova_report_interval = hiera('nova_report_interval', 60)
$nova_service_down_time = hiera('nova_service_down_time', 180)
@ -365,6 +366,10 @@ $glance_nodes = $controller_nodes
# todo: use special node-roles instead controllers in the future
$ceilometer_nodes = $controller_nodes
# Define aodh-related variables:
# todo: use special node-roles instead controllers in the future
$aodh_nodes = $controller_nodes
# Define memcached-related variables:
$memcache_roles = hiera('memcache_roles', ['primary-controller', 'controller'])
@ -417,6 +422,9 @@ $ceilometer_defaults = {
$real_ceilometer_hash = merge($ceilometer_defaults, $ceilometer)
# Define aodh-related paramteres
$aodh = hiera('aodh', {})
# Define database-related variables:
# todo: use special node-roles instead controllers in the future
$database_nodes = $controller_nodes

View File

@ -0,0 +1,37 @@
notice('MODULAR: openstack-haproxy-aodh.pp')
$ceilometer_hash = hiera_hash('ceilometer',{})
# enabled only in case of Ceilometer enabled
$use_aodh = pick($ceilometer_hash['enabled'], false)
$public_ssl_hash = hiera_hash('public_ssl', {})
$ssl_hash = hiera_hash('use_ssl', {})
$public_ssl = get_ssl_property($ssl_hash, $public_ssl_hash, 'aodh', 'public', 'usage', false)
$public_ssl_path = get_ssl_property($ssl_hash, $public_ssl_hash, 'aodh', 'public', 'path', [''])
$internal_ssl = get_ssl_property($ssl_hash, {}, 'aodh', 'internal', 'usage', false)
$internal_ssl_path = get_ssl_property($ssl_hash, {}, 'aodh', 'internal', 'path', [''])
$external_lb = hiera('external_lb', false)
if ($use_aodh and !$external_lb) {
$aodh_address_map = get_node_to_ipaddr_map_by_network_role(hiera_hash('aodh_nodes'), 'aodh/api')
$server_names = hiera_array('aodh_names', keys($aodh_address_map))
$ipaddresses = hiera_array('aodh_ipaddresses', values($aodh_address_map))
$public_virtual_ip = hiera('public_vip')
$internal_virtual_ip = hiera('management_vip')
# configure aodh ha proxy
class { '::openstack::ha::aodh':
internal_virtual_ip => $internal_virtual_ip,
ipaddresses => $ipaddresses,
public_virtual_ip => $public_virtual_ip,
server_names => $server_names,
public_ssl => $public_ssl,
public_ssl_path => $public_ssl_path,
internal_ssl => $internal_ssl,
internal_ssl_path => $internal_ssl_path,
}
}

View File

@ -0,0 +1,11 @@
require File.join File.dirname(__FILE__), 'haproxy_post_common.rb'
def expected_backends
return $expected_backends if $expected_backends
backends = %w(
aodh
)
$expected_backends = backends
end
OpenstackHaproxyPostTest.create_tests

View File

@ -3,7 +3,7 @@
version: 2.0.0
groups: [primary-controller, controller]
required_for: [deploy_end]
requires: [deploy_start, openstack-haproxy-ceilometer, openstack-haproxy-cinder, openstack-haproxy-glance, openstack-haproxy-heat, openstack-haproxy-horizon, openstack-haproxy-keystone, openstack-haproxy-mysqld, openstack-haproxy-neutron, openstack-haproxy-nova, openstack-haproxy-radosgw, openstack-haproxy-sahara, openstack-haproxy-swift, openstack-haproxy-stats, openstack-haproxy-ironic]
requires: [deploy_start, openstack-haproxy-ceilometer, openstack-haproxy-aodh, openstack-haproxy-cinder, openstack-haproxy-glance, openstack-haproxy-heat, openstack-haproxy-horizon, openstack-haproxy-keystone, openstack-haproxy-mysqld, openstack-haproxy-neutron, openstack-haproxy-nova, openstack-haproxy-radosgw, openstack-haproxy-sahara, openstack-haproxy-swift, openstack-haproxy-stats, openstack-haproxy-ironic]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/openstack-haproxy/openstack-haproxy.pp
puppet_modules: /etc/puppet/modules
@ -209,6 +209,24 @@
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/openstack-haproxy/openstack-haproxy-ceilometer_post.rb
- id: openstack-haproxy-aodh
type: puppet
version: 2.0.0
groups: [primary-controller, controller]
required_for: [deploy_end]
requires: [deploy_start, primary-cluster-haproxy, cluster-haproxy]
cross-depends:
- name: /(primary-)?cluster-haproxy/
role: self
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/openstack-haproxy/openstack-haproxy-aodh.pp
puppet_modules: /etc/puppet/modules
timeout: 300
test_pre:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/openstack-haproxy/openstack-haproxy_pre.rb
test_post:
cmd: ruby /etc/puppet/modules/osnailyfacter/modular/openstack-haproxy/openstack-haproxy-aodh_post.rb
- id: openstack-haproxy-sahara
type: puppet
version: 2.0.0

View File

@ -3,6 +3,8 @@
<% globals.store "access_hash", @access_hash -%>
<% globals.store "amqp_hosts", @amqp_hosts -%>
<% globals.store "amqp_port", @amqp_port -%>
<% globals.store "aodh_hash", @aodh -%>
<% globals.store "aodh_nodes", @aodh_nodes -%>
<% globals.store "apache_api_proxy_address", @apache_api_proxy_address -%>
<% globals.store "apache_ports", @apache_ports -%>
<% globals.store "base_mac", @base_mac -%>
@ -79,6 +81,7 @@
<% globals.store "swift_hash", @swift_hash -%>
<% globals.store "syslog_hash", @syslog_hash -%>
<% globals.store "default_log_levels", @default_log_levels -%>
<% globals.store "aodh::logging::default_log_levels", @default_log_levels -%>
<% globals.store "ceilometer::logging::default_log_levels", @default_log_levels -%>
<% globals.store "cinder::logging::default_log_levels", @default_log_levels -%>
<% globals.store "glance::api::logging::default_log_levels", @default_log_levels -%>
@ -88,6 +91,7 @@
<% globals.store "nova::logging::default_log_levels", @default_log_levels -%>
<% globals.store "sahara::logging::default_log_levels", @default_log_levels -%>
<% globals.store "ironic::logging::default_log_levels", @default_log_levels -%>
<% globals.store "syslog_log_facility_aodh", @syslog_log_facility_aodh -%>
<% globals.store "syslog_log_facility_ceilometer", @syslog_log_facility_ceilometer -%>
<% globals.store "syslog_log_facility_ceph", @syslog_log_facility_ceph -%>
<% globals.store "syslog_log_facility_cinder", @syslog_log_facility_cinder -%>

View File

@ -0,0 +1,287 @@
#!/bin/bash
#
#
# OpenStack Aodh Evaluator Service (aodh-evaluator)
#
# Description: Manages an OpenStack Aodh Evaluator Service (aodh-evaluator) process as an HA resource
#
# Authors: Emilien Macchi
# Mainly inspired by the Nova Scheduler resource agent written by Sebastien Han
#
# Support: openstack@lists.launchpad.net
# License: Apache Software License (ASL) 2.0
#
#
# See usage() function below for more details ...
#
# OCF instance parameters:
# OCF_RESKEY_binary
# OCF_RESKEY_config
# OCF_RESKEY_user
# OCF_RESKEY_pid
# OCF_RESKEY_monitor_binary
# OCF_RESKEY_additional_parameters
#######################################################################
# Initialization:
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
: ${OCF_FUEL_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/fuel}
. ${OCF_FUEL_FUNCTIONS_DIR}/ocf-fuel-funcs
#######################################################################
# Fill in some defaults if no values are specified
OCF_RESKEY_binary_default="aodh-evaluator"
OCF_RESKEY_config_default="/etc/aodh/aodh.conf"
OCF_RESKEY_user_default="aodh"
OCF_RESKEY_pid_default="${HA_RSCTMP}/${__SCRIPT_NAME}/${__SCRIPT_NAME}.pid"
: ${HA_LOGTAG="ocf-aodh-evaluator"}
: ${HA_LOGFACILITY="daemon"}
: ${OCF_RESKEY_binary=${OCF_RESKEY_binary_default}}
: ${OCF_RESKEY_config=${OCF_RESKEY_config_default}}
: ${OCF_RESKEY_user=${OCF_RESKEY_user_default}}
: ${OCF_RESKEY_pid=${OCF_RESKEY_pid_default}}
#######################################################################
usage() {
cat <<UEND
usage: $0 (start|stop|validate-all|meta-data|status|monitor)
$0 manages an OpenStack Aodh Evaluator Service (aodh-evaluator) process as an HA resource
The 'start' operation starts the service.
The 'stop' operation stops the service.
The 'validate-all' operation reports whether the parameters are valid
The 'meta-data' operation reports this RA's meta-data information
The 'status' operation reports whether the service is running
The 'monitor' operation reports whether the service seems to be working
UEND
}
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="aodh-evaluator">
<version>1.0</version>
<longdesc lang="en">
Resource agent for the OpenStack Aodh Evaluator Service (aodh-evaluator)
May manage a aodh-evaluator instance or a clone set that
creates a distributed aodh-evaluator cluster.
</longdesc>
<shortdesc lang="en">Manages the OpenStack Aodh Evaluator Service (aodh-evaluator)</shortdesc>
<parameters>
<parameter name="binary" unique="0" required="0">
<longdesc lang="en">
Location of the OpenStack Aodh Evaluator server binary (aodh-evaluator)
</longdesc>
<shortdesc lang="en">OpenStack Aodh Evaluator server binary (aodh-evaluator)</shortdesc>
<content type="string" default="${OCF_RESKEY_binary_default}" />
</parameter>
<parameter name="config" unique="0" required="0">
<longdesc lang="en">
Location of the OpenStack Aodh Evaluator Service (aodh-evaluator) configuration file
</longdesc>
<shortdesc lang="en">OpenStack Aodh Evaluator (aodh-evaluator) config file</shortdesc>
<content type="string" default="${OCF_RESKEY_config_default}" />
</parameter>
<parameter name="user" unique="0" required="0">
<longdesc lang="en">
User running OpenStack Aodh Evaluator Service (aodh-evaluator)
</longdesc>
<shortdesc lang="en">OpenStack Aodh Evaluator Service (aodh-evaluator) user</shortdesc>
<content type="string" default="${OCF_RESKEY_user_default}" />
</parameter>
<parameter name="pid" unique="0" required="0">
<longdesc lang="en">
The pid file to use for this OpenStack Aodh Evaluator Service (aodh-evaluator) instance
</longdesc>
<shortdesc lang="en">OpenStack Aodh Evaluator Service (aodh-evaluator) pid file</shortdesc>
<content type="string" default="${OCF_RESKEY_pid_default}" />
</parameter>
<parameter name="additional_parameters" unique="0" required="0">
<longdesc lang="en">
Additional parameters to pass on to the OpenStack Aodh Evaluator Service (aodh-evaluator)
</longdesc>
<shortdesc lang="en">Additional parameters for aodh-evaluator</shortdesc>
<content type="string" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="20" />
<action name="stop" timeout="20" />
<action name="status" timeout="20" />
<action name="monitor" timeout="30" interval="20" />
<action name="validate-all" timeout="5" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
END
}
#######################################################################
# Functions invoked by resource manager actions
aodh_evaluator_validate() {
local rc
check_binary $OCF_RESKEY_binary
check_binary netstat
# A config file on shared storage that is not available
# during probes is OK.
if [ ! -f $OCF_RESKEY_config ]; then
if ! ocf_is_probe; then
ocf_log err "Config $OCF_RESKEY_config doesn't exist"
return $OCF_ERR_INSTALLED
fi
ocf_log_warn "Config $OCF_RESKEY_config not available during a probe"
fi
getent passwd $OCF_RESKEY_user >/dev/null 2>&1
rc=$?
if [ $rc -ne 0 ]; then
ocf_log err "User $OCF_RESKEY_user doesn't exist"
return $OCF_ERR_INSTALLED
fi
return ${OCF_SUCCESS}
}
aodh_evaluator_status() {
local pid
local rc
# check and make PID file dir
local PID_DIR="$( dirname ${OCF_RESKEY_pid} )"
if [ ! -d "${PID_DIR}" ] ; then
ocf_log debug "Create pid file dir: ${PID_DIR} and chown to ${OCF_RESKEY_user}"
mkdir -p "${PID_DIR}"
chown -R ${OCF_RESKEY_user} "${PID_DIR}"
chmod 755 "${PID_DIR}"
fi
if [ ! -f $OCF_RESKEY_pid ]; then
ocf_log info "OpenStack Aodh Evaluator (aodh-evaluator) is not running"
return $OCF_NOT_RUNNING
else
pid=`cat $OCF_RESKEY_pid`
fi
if [ -n "${pid}" ]; then
ocf_run -warn kill -s 0 $pid
rc=$?
else
ocf_log err "PID file ${OCF_RESKEY_pid} is empty!"
return $OCF_ERR_GENERIC
fi
if [ $rc -eq 0 ]; then
return $OCF_SUCCESS
else
ocf_log info "Old PID file found, but OpenStack Aodh Evaluator (aodh-evaluator) is not running"
return $OCF_NOT_RUNNING
fi
}
aodh_evaluator_monitor() {
local rc
local pid
aodh_evaluator_status
rc=$?
# If status returned anything but success, return that immediately
if [ $rc -ne $OCF_SUCCESS ]; then
return $rc
fi
ocf_log debug "OpenStack Aodh Evaluator (aodh-evaluator) monitor succeeded"
return $OCF_SUCCESS
}
aodh_evaluator_start() {
local rc
aodh_evaluator_status
rc=$?
if [ $rc -eq $OCF_SUCCESS ]; then
ocf_log info "OpenStack Aodh Evaluator (aodh-evaluator) already running"
return $OCF_SUCCESS
fi
# run the actual aodh-evaluator daemon. Don't use ocf_run as we're sending the tool's output
# straight to /dev/null anyway and using ocf_run would break stdout-redirection here.
su ${OCF_RESKEY_user} -s /bin/sh -c "${OCF_RESKEY_binary} --config-file=$OCF_RESKEY_config \
$OCF_RESKEY_additional_parameters"' >> /dev/null 2>&1 & echo $!' > $OCF_RESKEY_pid
ocf_log debug "Create pid file: ${OCF_RESKEY_pid} with content $(cat ${OCF_RESKEY_pid})"
# Spin waiting for the server to come up.
while true; do
aodh_evaluator_monitor
rc=$?
[ $rc -eq $OCF_SUCCESS ] && break
if [ $rc -ne $OCF_NOT_RUNNING ]; then
ocf_log err "OpenStack Aodh Evaluator (aodh-evaluator) start failed"
exit $OCF_ERR_GENERIC
fi
sleep 1
done
ocf_log info "OpenStack Aodh Evaluator (aodh-evaluator) started"
return $OCF_SUCCESS
}
aodh_evaluator_stop() {
local rc
local shutdown_timeout=15
if [ -n "$OCF_RESKEY_CRM_meta_timeout" ]; then
shutdown_timeout=$(( ($OCF_RESKEY_CRM_meta_timeout/1000) ))
fi
aodh_evaluator_status
rc="${?}"
if [ "${rc}" -eq "${OCF_NOT_RUNNING}" ]; then
ocf_log info "OpenStack Aodh Evaluator (${OCF_RESKEY_binary}) already stopped"
return "${OCF_SUCCESS}"
fi
proc_stop "${OCF_RESKEY_pid}" "${OCF_RESKEY_binary}" $shutdown_timeout
return "${?}"
}
#######################################################################
case "$1" in
meta-data) meta_data
exit $OCF_SUCCESS;;
usage|help) usage
exit $OCF_SUCCESS;;
esac
# Anything except meta-data and help must pass validation
aodh_evaluator_validate || exit $?
# What kind of method was invoked?
case "$1" in
start) aodh_evaluator_start;;
stop) aodh_evaluator_stop;;
status) aodh_evaluator_status;;
monitor) aodh_evaluator_monitor;;
validate-all) ;;
*) usage
exit $OCF_ERR_UNIMPLEMENTED;;
esac

View File

@ -109,6 +109,7 @@ install -m 0755 %{files_source}/fuel-ha-utils/ocf/set_rabbitmq_policy.sh %{build
install -m 0755 %{files_source}/fuel-ha-utils/ocf/ns_IPaddr2 %{buildroot}/usr/lib/ocf/resource.d/fuel/ns_IPaddr2
install -m 0755 %{files_source}/fuel-ha-utils/ocf/ceilometer-agent-central %{buildroot}/usr/lib/ocf/resource.d/fuel/ceilometer-agent-central
install -m 0755 %{files_source}/fuel-ha-utils/ocf/ceilometer-alarm-evaluator %{buildroot}/usr/lib/ocf/resource.d/fuel/ceilometer-alarm-evaluator
install -m 0755 %{files_source}/fuel-ha-utils/ocf/aodh-evaluator %{buildroot}/usr/lib/ocf/resource.d/fuel/aodh-evaluator
install -m 0755 %{files_source}/fuel-ha-utils/ocf/nova-compute %{buildroot}/usr/lib/ocf/resource.d/fuel/nova-compute
install -m 0755 %{files_source}/fuel-ha-utils/ocf/nova-network %{buildroot}/usr/lib/ocf/resource.d/fuel/nova-network
install -m 0755 %{files_source}/fuel-ha-utils/ocf/ceilometer-agent-compute %{buildroot}/usr/lib/ocf/resource.d/fuel/ceilometer-agent-compute

View File

@ -0,0 +1,120 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'aodh/aodh.pp'
describe manifest do
shared_examples 'catalog' do
let(:network_scheme) do
Noop.hiera_hash 'network_scheme'
end
let(:prepare) do
Noop.puppet_function 'prepare_network_config', network_scheme
end
let(:memcache_address) do
prepare
Noop.puppet_function 'get_network_role_property', 'mgmt/memcache', 'ipaddr'
end
let(:aodh_api_bind_host) do
Noop.puppet_function 'get_network_role_property', 'aodh/api', 'ipaddr'
end
ssl_hash = Noop.hiera_structure 'use_ssl', {}
management_vip = Noop.hiera 'management_vip'
internal_auth_protocol = Noop.puppet_function 'get_ssl_property', ssl_hash, {}, 'keystone', 'internal', 'protocol', 'http'
internal_auth_address = Noop.puppet_function 'get_ssl_property', ssl_hash, {}, 'keystone', 'internal', 'hostname', [management_vip]
keystone_auth_uri = "#{internal_auth_protocol}://#{internal_auth_address}:5000/"
keystone_identity_uri = "#{internal_auth_protocol}://#{internal_auth_address}:35357/"
oslo_policy_file = '/etc/aodh/policy.json'
notification_store_events = 'true'
keystone_signing_dir = '/tmp/keystone-signing-aodh'
aodh_hash = Noop.hiera_structure 'aodh', {}
tenant = aodh_hash.fetch('tenant', 'services')
region = aodh_hash.fetch('region', (Noop.hiera 'region', 'RegionOne'))
user = aodh_hash.fetch('user', 'aodh')
password = aodh_hash['user_password']
debug = Noop.hiera 'debug'
verbose = Noop.hiera 'verbose'
api_pecan_debug = aodh_hash.fetch('debug', debug)
db_host = Noop.hiera 'database_vip'
db_name = aodh_hash.fetch('db_name', 'aodh')
db_user = aodh_hash.fetch('db_user', 'aodh')
db_password = aodh_hash['db_password']
rabbit_ha_queues = Noop.hiera 'rabbit_ha_queues'
rabbit_hash = Noop.hiera_structure 'rabbit_hash', {}
rabbit_userid = rabbit_hash.fetch('user', 'nova')
rabbit_password = rabbit_hash['password']
rabbit_port = Noop.hiera 'amqp_port'
rabbit_hosts = Noop.hiera 'amqp_hosts'
it 'should configure "DEFAULT/" section ' do
should contain_aodh_config('DEFAULT/debug').with(:value => debug)
should contain_aodh_config('DEFAULT/verbose').with(:value => verbose)
should contain_aodh_config('DEFAULT/rpc_backend').with(:value => 'rabbit')
should contain_aodh_config('DEFAULT/notification_topics').with(:value => 'notifications')
end
it 'should configure "api/" section ' do
should contain_aodh_config('api/host').with(:value => "#{aodh_api_bind_host}")
should contain_aodh_config('api/port').with(:value => '8042')
should contain_aodh_config('api/pecan_debug').with(:value => api_pecan_debug)
end
it 'should configure oslo_policy/policy_file, notification/store_events, api/pecan_debug' do
should contain_aodh_config('oslo_policy/policy_file').with(:value => oslo_policy_file)
should contain_aodh_config('notification/store_events').with(:value => notification_store_events)
end
it 'should configure "keystone_authtoken/" section' do
should contain_aodh_config('keystone_authtoken/memcache_servers').with(:value => "#{memcache_address}:11211")
should contain_aodh_config('keystone_authtoken/signing_dir').with(:value => keystone_signing_dir)
should contain_aodh_config('keystone_authtoken/identity_uri').with(:value => keystone_identity_uri)
should contain_aodh_config('keystone_authtoken/auth_uri').with(:value => keystone_auth_uri)
should contain_aodh_config('keystone_authtoken/admin_tenant_name').with(:value => tenant)
should contain_aodh_config('keystone_authtoken/admin_user').with(:value => user)
should contain_aodh_config('keystone_authtoken/admin_password').with(:value => password)
end
it 'should configure "service_credentials/" section' do
should contain_aodh_config('service_credentials/os_username').with(:value => user)
should contain_aodh_config('service_credentials/os_password').with(:value => password)
should contain_aodh_config('service_credentials/os_tenant_name').with(:value => tenant)
should contain_aodh_config('service_credentials/os_region_name').with(:value => region)
should contain_aodh_config('service_credentials/os_endpoint_type').with(:value => 'internalURL')
should contain_aodh_config('service_credentials/os_auth_url').with(:value => keystone_auth_uri)
end
it 'should configure "oslo_messaging_rabbit/" section' do
should contain_aodh_config('oslo_messaging_rabbit/rabbit_ha_queues').with(:value => rabbit_ha_queues)
should contain_aodh_config('oslo_messaging_rabbit/rabbit_virtual_host').with(:value => '/')
should contain_aodh_config('oslo_messaging_rabbit/rabbit_hosts').with(:value => rabbit_hosts)
should contain_aodh_config('oslo_messaging_rabbit/rabbit_userid').with(:value => rabbit_userid)
should contain_aodh_config('oslo_messaging_rabbit/rabbit_password').with(:value => rabbit_password)
end
it 'should properly build connection string' do
if facts[:os_package_type] == 'debian'
db_params = '?charset=utf8&read_timeout=60'
else
db_params = '?charset=utf8'
end
should contain_aodh_config('database/connection').with(:value => "mysql://#{db_user}:#{db_password}@#{db_host}/#{db_name}#{db_params}")
end
end # end of shared_examples
test_ubuntu_and_centos manifest
end

View File

@ -0,0 +1,7 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'aodh/db.pp'
describe manifest do
test_ubuntu_and_centos manifest
end

View File

@ -0,0 +1,7 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'aodh/keystone.pp'
describe manifest do
test_ubuntu_and_centos manifest
end

View File

@ -115,6 +115,11 @@ describe manifest do
should contain_ceilometer_config('collector/workers').with(:value => service_workers)
should contain_ceilometer_config('notification/workers').with(:value => service_workers)
end
it 'should configure auth url' do
should contain_ceilometer_config('service_credentials/os_auth_url').with(:value => keystone_auth_uri)
end
end
end # end of shared_examples

View File

@ -0,0 +1,7 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'openstack-haproxy/openstack-haproxy-aodh.pp'
describe manifest do
test_ubuntu_and_centos manifest
end