initial refactoring step and addition of gnocchi

* applied new template logic and refactored all recipes accordingly
* removed vmware and suse support and specs
* removed alarm ceilometer-alarm notifier and evaluator (needs to be rewritten
  for aodh)
* added recipe for telemetry-metric/gnocchi deployment
* set gnocchi as default dispatcher for ceilometer
* added initial specs for gnocchi recipes

Depends-On: I22114b6d2d46cce561a2f292b92ff5f531cff533
Change-Id: If513cb2715d8266845bd6541d12005edef70f11c
This commit is contained in:
Jan Klare 2016-05-19 18:10:21 +02:00
parent fd677da703
commit faceb7e6e0
40 changed files with 884 additions and 1356 deletions

135
README.md
View File

@ -1,106 +1,79 @@
Description Description
=========== ===========
Installs the OpenStack Metering service **Ceilometer** as part of the OpenStack Installs the OpenStack Metering service **Ceilometer** as well as **Gnocchi** as
reference deployment Chef for OpenStack. Ceilometer is currently installed the backend for Metrics as part of the OpenStack reference deployment Chef for
from packages. OpenStack. Both are currently installed from packages.
https://wiki.openstack.org/wiki/Ceilometer http://docs.openstack.org/developer/ceilometer/
http://docs.openstack.org/developer/gnocchi/
Requirements Requirements
============ ============
- Chef 12 or higher
- chefdk 0.9.0 for testing (also includes berkshelf for cookbook dependency
resolution)
WARNING:
- Currently there are no gnocchi packages included for Ubuntu Trusty. The
gnocchi recipe will only work on Ubuntu Xenial and above.
Platform
========
- ubuntu
- redhat
- centos
Cookbooks Cookbooks
--------- =========
The following cookbooks are dependencies: The following cookbooks are dependencies:
* openstack-common - 'openstack-common', '>= 13.0.0'
* openstack-identity - 'openstack-identity', '>= 13.0.0'
* openstack-compute
Usage
=====
agent-central
----
- Installs agent central service.
agent-compute
----
- Installs agent compute service.
agent-notification
----
- Installs agent notification service.
alarm-evaluator
----
- Installs alarm evaluator service.
alarm-notifier
----
- Installs alarm notifier service.
api
----
- Installs API service.
client
----
- Install the client packages
collector
----
- Installs collector package and service. If the NoSQL database is used for metering service, ceilometer-dbsync will not be executed.
common
----
- Common metering configuration.
identity_registration
----
- Registers the endpoints, tenant and user for metering service with Keystone.
Attributes Attributes
========== ==========
* `openstack['telemetry']['api']['auth']['version']` - Select v2.0 or v3.0. Default v2.0. The auth API version used to interact with identity service. Please see the extensive inline documentation in `attributes/*.rb` for
* `openstack['telemetry']['sample_source']` - The source name of emitted samples, default value is openstack. descriptions of all the settable attributes for this cookbook.
* `openstack['telemetry']['api']['auth']['memcached_servers']` - A list of memcached server(s) to use for caching
* `openstack['telemetry']['api']['auth']['memcache_security_strategy']` - Whether token data should be authenticated or authenticated and encrypted. Acceptable values are MAC or ENCRYPT
* `openstack['telemetry']['api']['auth']['memcache_secret_key']` - This string is used for key derivation
* `openstack['telemetry']['api']['auth']['hash_algorithms']` - Hash algorithms to use for hashing PKI tokens
* `openstack['telemetry']['api']['auth']['cafile']` - A PEM encoded Certificate Authority to use when verifying HTTPs connections
* `openstack['telemetry']['api']['auth']['insecure']` - Set whether to verify HTTPS connections
* `openstack['telemetry']['service-credentials']['cafile']` - A PEM encoded Certificate Authority to use when verifying HTTPs connections (for service polling authentication)
* `openstack['telemetry']['service-credentials']['insecure']` - Set whether to verify HTTPS connections (for service polling authentication)
* `openstack['telemetry']['dbsync_timeout']` - Set dbsync command timeout value
* `openstack['telemetry']['database']['time_to_live']` - Set a time_to_live parameter (ttl) for samples. Set -1 for no expiry
* `openstack['telemetry']['notification']['store_events']` - Set a store_events parameter for notification service
The following attributes are defined in attributes/default.rb of the common cookbook, but are documented here due to their relevance: Note that all attributes are in the `default['openstack']` "namespace"
* `openstack['endpoints']['telemetry-api-bind']['host']` - The IP address to bind the api service to The usage of attributes to generate the node.conf is decribed in the
* `openstack['endpoints']['telemetry-api-bind']['port']` - The port to bind the api service to openstack-common cookbook.
* `openstack['endpoints']['telemetry-api-bind']['bind_interface']` - The interface name to bind the api service to
If the value of the 'bind_interface' attribute is non-nil, then the telemetry service will be bound to the first IP address on that interface. If the value of the 'bind_interface' attribute is nil, then the telemetry service will be bound to the IP address specifie Recipes
=======
Testing ## agent-central
===== - Installs agent central service.
Please refer to the [TESTING.md](TESTING.md) for instructions for testing the cookbook. ## agent-compute
- Installs agent compute service.
Berkshelf ## agent-notification
===== - Installs agent notification service.
Berks will resolve version requirements and dependencies on first run and ## api
store these in Berksfile.lock. If new cookbooks become available you can run - Installs API service.
`berks update` to update the references in Berksfile.lock. Berksfile.lock will
be included in stable branches to provide a known good set of dependencies. ## client
Berksfile.lock will not be included in development branches to encourage - Install the client packages
development against the latest cookbooks.
## collector
- Installs collector package and service. If the NoSQL database is used for metering service, ceilometer-dbsync will not be executed.
## common
- Common metering configuration.
## identity_registration
- Registers the endpoints, tenant and user for metering and metric service with Keystone.
## gnocchi
- Installs gnochhi as default backend for ceilometer metrics
License and Author License and Author
================== ==================
@ -116,7 +89,7 @@ License and Author
| **Author** | Chen Zhiwei (<zhiwchen@cn.ibm.com>) | | **Author** | Chen Zhiwei (<zhiwchen@cn.ibm.com>) |
| **Author** | David Geng (<gengjh@cn.ibm.com>) | | **Author** | David Geng (<gengjh@cn.ibm.com>) |
| **Author** | Mark Vanderwiel (<vanderwl@us.ibm.com>) | | **Author** | Mark Vanderwiel (<vanderwl@us.ibm.com>) |
| **Author** | Jan Klare (<j.klare@x-ion.de>) | | **Author** | Jan Klare (<j.klare@cloudbau.de>) |
| | | | | |
| **Copyright** | Copyright (c) 2013, Opscode, Inc. | | **Copyright** | Copyright (c) 2013, Opscode, Inc. |
| **Copyright** | Copyright (c) 2013, AT&T Services, Inc. | | **Copyright** | Copyright (c) 2013, AT&T Services, Inc. |

View File

@ -0,0 +1,18 @@
default['openstack']['telemetry']['conf_secrets'] = {}
default['openstack']['telemetry']['conf'].tap do |conf|
# [DEFAULT] section
conf['DEFAULT']['rpc_backend'] = node['openstack']['mq']['service_type']
conf['DEFAULT']['meter_dispatchers'] = 'gnocchi'
# [keystone_authtoken] section
conf['keystone_authtoken']['username'] = 'ceilometer'
conf['keystone_authtoken']['project_name'] = 'service'
conf['keystone_authtoken']['auth_type'] = 'password'
conf['keystone_authtoken']['region_name'] = node['openstack']['region']
# [service_credentials] section
conf['service_credentials']['username'] = 'ceilometer'
conf['service_credentials']['project_name'] = 'service'
conf['service_credentials']['auth_type'] = 'password'
conf['service_credentials']['interface'] = 'internal'
conf['service_credentials']['region_name'] = node['openstack']['region']
end

View File

@ -19,104 +19,61 @@
# limitations under the License. # limitations under the License.
# #
# The name of the Chef role that knows about the message queue server # Set the endpoints for the telemetry services to allow all other cookbooks to
# that Nova uses # access and use them
default['openstack']['telemetry']['rabbit_server_chef_role'] = 'os-ops-messaging' %w(telemetry telemetry-metric).each do |ts|
%w(public internal admin).each do |ep_type|
default['openstack']['endpoints'][ep_type][ts]['host'] = '127.0.0.1'
default['openstack']['endpoints'][ep_type][ts]['scheme'] = 'http'
default['openstack']['endpoints'][ep_type][ts]['path'] = ''
default['openstack']['endpoints'][ep_type]['telemetry']['port'] = 8777
default['openstack']['endpoints'][ep_type]['telemetry-metric']['port'] = 8041
# web-service (e.g. apache) listen address (can be different from openstack
# telemetry endpoints)
end
default['openstack']['bind_service']['all'][ts]['host'] = '127.0.0.1'
end
default['openstack']['bind_service']['all']['telemetry']['port'] = 8777
default['openstack']['bind_service']['all']['telemetry-metric']['port'] = 8041
default['openstack']['telemetry']['conf_dir'] = '/etc/ceilometer' default['openstack']['telemetry']['conf_dir'] = '/etc/ceilometer'
default['openstack']['telemetry']['conf'] = ::File.join(node['openstack']['telemetry']['conf_dir'], 'ceilometer.conf') default['openstack']['telemetry']['conf_file'] =
default['openstack']['telemetry']['periodic_interval'] = 600 ::File.join(node['openstack']['telemetry']['conf_dir'], 'ceilometer.conf')
default['openstack']['telemetry-metric']['conf_dir'] = '/etc/gnocchi'
default['openstack']['telemetry-metric']['conf_file'] =
::File.join(node['openstack']['telemetry-metric']['conf_dir'], 'gnocchi.conf')
default['openstack']['telemetry']['syslog']['use'] = false default['openstack']['telemetry']['syslog']['use'] = false
default['openstack']['telemetry']['verbose'] = 'true'
default['openstack']['telemetry']['debug'] = 'false'
default['openstack']['telemetry']['api']['auth']['cache_dir'] = '/var/cache/ceilometer/api'
default['openstack']['telemetry']['api']['auth']['version'] = node['openstack']['api']['auth']['version']
# A list of memcached server(s) to use for caching
default['openstack']['telemetry']['api']['auth']['memcached_servers'] = nil
# Whether token data should be authenticated or authenticated and encrypted. Acceptable values are MAC or ENCRYPT
default['openstack']['telemetry']['api']['auth']['memcache_security_strategy'] = nil
# This string is used for key derivation
default['openstack']['telemetry']['api']['auth']['memcache_secret_key'] = nil
# Hash algorithms to use for hashing PKI tokens
default['openstack']['telemetry']['api']['auth']['hash_algorithms'] = 'md5'
# A PEM encoded Certificate Authority to use when verifying HTTPs connections
default['openstack']['telemetry']['api']['auth']['cafile'] = nil
# Verify HTTPS connections
default['openstack']['telemetry']['api']['auth']['insecure'] = false
default['openstack']['telemetry']['user'] = 'ceilometer' default['openstack']['telemetry']['user'] = 'ceilometer'
default['openstack']['telemetry']['group'] = 'ceilometer' default['openstack']['telemetry']['group'] = 'ceilometer'
default['openstack']['telemetry']['region'] = node['openstack']['region'] default['openstack']['telemetry-metric']['user'] = 'gnocchi'
default['openstack']['telemetry']['service_user'] = 'ceilometer' default['openstack']['telemetry-metric']['group'] = 'gnocchi'
default['openstack']['telemetry']['service_tenant_name'] = 'service'
default['openstack']['telemetry']['service_role'] = 'admin' default['openstack']['telemetry']['service_role'] = 'admin'
default['openstack']['telemetry-metric']['service_role'] = 'admin'
# A PEM encoded Certificate Authority to use when verifying HTTPs connections (for service polling authentication) default['openstack']['telemetry']['identity-api']['auth']['version'] =
default['openstack']['telemetry']['service-credentials']['cafile'] = nil node['openstack']['api']['auth']['version']
default['openstack']['telemetry-metric']['identity-api']['auth']['version'] =
# Verify HTTPS connections (for service polling authentication) node['openstack']['api']['auth']['version']
default['openstack']['telemetry']['service-credentials']['insecure'] = false
default['openstack']['telemetry']['sample_source'] = 'openstack'
default['openstack']['telemetry']['dbsync_timeout'] = 3600
case node['openstack']['compute']['driver']
when 'libvirt.LibvirtDriver'
default['openstack']['telemetry']['hypervisor_inspector'] = 'libvirt'
when 'vmwareapi.VMwareESXDriver', 'vmwareapi.VMwareVCDriver'
default['openstack']['telemetry']['hypervisor_inspector'] = 'vsphere'
else
default['openstack']['telemetry']['hypervisor_inspector'] = nil
end
case platform_family case platform_family
when 'suse' # :pragma-foodcritic: ~FC024 - won't fix this when 'rhel'
default['openstack']['telemetry']['platform'] = {
'common_packages' => ['openstack-ceilometer'],
'agent_central_packages' => ['openstack-ceilometer-agent-central'],
'agent_central_service' => 'openstack-ceilometer-agent-central',
'agent_compute_packages' => ['openstack-ceilometer-agent-compute'],
'agent_compute_service' => 'openstack-ceilometer-agent-compute',
'agent_notification_packages' => ['openstack-ceilometer-agent-notification'],
'agent_notification_service' => 'openstack-ceilometer-agent-notification',
'alarm_evaluator_packages' => ['openstack-ceilometer-alarm-evaluator'],
'alarm_evaluator_service' => 'openstack-ceilometer-alarm-evaluator',
'alarm_notifier_packages' => ['openstack-ceilometer-alarm-notifier'],
'alarm_notifier_service' => 'openstack-ceilometer-alarm-notifier',
'api_packages' => ['openstack-ceilometer-api'],
'api_service' => 'openstack-ceilometer-api',
'client_packages' => ['python-ceilometerclient'],
'collector_packages' => ['openstack-ceilometer-collector'],
'collector_service' => 'openstack-ceilometer-collector',
'package_overrides' => ''
}
when 'fedora', 'rhel'
default['openstack']['telemetry']['platform'] = { default['openstack']['telemetry']['platform'] = {
'common_packages' => ['openstack-ceilometer-common'], 'common_packages' => ['openstack-ceilometer-common'],
'gnocchi_packages' => ['openstack-gnocchi-api', 'openstack-gnocchi-metricd'],
'gnocchi-api_service' => 'openstack-gnocchi-api',
'gnocchi-metricd_service' => 'openstack-gnocchi-metricd',
'agent_central_packages' => ['openstack-ceilometer-central'], 'agent_central_packages' => ['openstack-ceilometer-central'],
'agent_central_service' => 'openstack-ceilometer-central', 'agent_central_service' => 'openstack-ceilometer-central',
'agent_compute_packages' => ['openstack-ceilometer-compute'], 'agent_compute_packages' => ['openstack-ceilometer-compute'],
'agent_compute_service' => 'openstack-ceilometer-compute', 'agent_compute_service' => 'openstack-ceilometer-compute',
'agent_notification_packages' => ['openstack-ceilometer-collector'], 'agent_notification_packages' => ['openstack-ceilometer-collector'],
'agent_notification_service' => 'openstack-ceilometer-notification', 'agent_notification_service' => 'openstack-ceilometer-notification',
'alarm_evaluator_packages' => ['openstack-ceilometer-alarm'],
'alarm_evaluator_service' => 'openstack-ceilometer-alarm-evaluator',
'alarm_notifier_packages' => ['openstack-ceilometer-alarm'],
'alarm_notifier_service' => 'openstack-ceilometer-alarm-notifier',
'api_packages' => ['openstack-ceilometer-api'], 'api_packages' => ['openstack-ceilometer-api'],
'api_service' => 'openstack-ceilometer-api', 'api_service' => 'openstack-ceilometer-api',
'client_packages' => ['python-ceilometerclient'], 'client_packages' => ['python-ceilometerclient', 'python-gnocchiclient'],
'collector_packages' => ['openstack-ceilometer-collector'], 'collector_packages' => ['openstack-ceilometer-collector'],
'collector_service' => 'openstack-ceilometer-collector', 'collector_service' => 'openstack-ceilometer-collector',
'package_overrides' => '' 'package_overrides' => ''
@ -125,27 +82,20 @@ when 'fedora', 'rhel'
when 'debian' when 'debian'
default['openstack']['telemetry']['platform'] = { default['openstack']['telemetry']['platform'] = {
'common_packages' => ['ceilometer-common'], 'common_packages' => ['ceilometer-common'],
'gnocchi_packages' => ['gnocchi-api', 'gnocchi-metricd'],
'gnocchi-api_service' => 'gnocchi-api',
'gnocchi-metricd_service' => 'gnocchi-metricd',
'agent_central_packages' => ['ceilometer-agent-central'], 'agent_central_packages' => ['ceilometer-agent-central'],
'agent_central_service' => 'ceilometer-agent-central', 'agent_central_service' => 'ceilometer-agent-central',
'agent_compute_packages' => ['ceilometer-agent-compute'], 'agent_compute_packages' => ['ceilometer-agent-compute'],
'agent_compute_service' => 'ceilometer-agent-compute', 'agent_compute_service' => 'ceilometer-agent-compute',
'agent_notification_packages' => ['ceilometer-agent-notification'], 'agent_notification_packages' => ['ceilometer-agent-notification'],
'agent_notification_service' => 'ceilometer-agent-notification', 'agent_notification_service' => 'ceilometer-agent-notification',
'alarm_evaluator_packages' => ['ceilometer-alarm-evaluator'],
'alarm_evaluator_service' => 'ceilometer-alarm-evaluator',
'alarm_notifier_packages' => ['ceilometer-alarm-notifier'],
'alarm_notifier_service' => 'ceilometer-alarm-notifier',
'api_packages' => ['ceilometer-api'], 'api_packages' => ['ceilometer-api'],
'api_service' => 'ceilometer-api', 'api_service' => 'ceilometer-api',
'client_packages' => ['python-ceilometerclient'], 'client_packages' => ['python-ceilometerclient', 'python-gnocchiclient'],
'collector_packages' => ['ceilometer-collector', 'python-mysqldb'], 'collector_packages' => ['ceilometer-collector', 'python-mysqldb'],
'collector_service' => 'ceilometer-collector', 'collector_service' => 'ceilometer-collector',
'package_overrides' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'" 'package_overrides' => "-o Dpkg::Options::='--force-confold' -o Dpkg::Options::='--force-confdef'"
} }
end end
# The time to live value for samples which is specified in seconds, override to -1 if no data expiry is required
default['openstack']['telemetry']['database']['time_to_live'] = 1800
# Decide whether to store events in notification service or not
default['openstack']['telemetry']['notification']['store_events'] = false

View File

@ -0,0 +1,15 @@
default['openstack']['telemetry-metric']['conf_secrets'] = {}
default['openstack']['telemetry-metric']['conf'].tap do |conf|
# [DEFAULT] section
conf['DEFAULT']['rpc_backend'] = node['openstack']['mq']['service_type']
# [keystone_authtoken] section
conf['keystone_authtoken']['username'] = 'gnocchi'
conf['keystone_authtoken']['project_name'] = 'service'
conf['keystone_authtoken']['auth_type'] = 'password'
conf['keystone_authtoken']['region_name'] = node['openstack']['region']
conf['storage']['driver'] = 'file'
if node['openstack']['telemetry-metric']['conf']['storage']['driver'] == 'file'
conf['storage']['file_basepath'] = '/var/lib/gnocchi'
end
end

31
files/api-paste.ini Normal file
View File

@ -0,0 +1,31 @@
[pipeline:main]
pipeline = gnocchi+auth
[composite:gnocchi+noauth]
use = egg:Paste#urlmap
/ = gnocchiversions
/v1 = gnocchiv1
[composite:gnocchi+auth]
use = egg:Paste#urlmap
/ = gnocchiversions
/v1 = gnocchiv1+auth
[pipeline:gnocchiv1+auth]
pipeline = keystone_authtoken gnocchiv1
[app:gnocchiversions]
paste.app_factory = gnocchi.rest.app:app_factory
root = gnocchi.rest.VersionsController
[app:gnocchiv1]
paste.app_factory = gnocchi.rest.app:app_factory
root = gnocchi.rest.V1Controller
[filter:keystone_authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
oslo_config_project = gnocchi
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = gnocchi

View File

@ -0,0 +1,213 @@
---
resources:
- resource_type: identity
archive_policy: low
metrics:
- 'identity.authenticate.success'
- 'identity.authenticate.pending'
- 'identity.authenticate.failure'
- 'identity.user.created'
- 'identity.user.deleted'
- 'identity.user.updated'
- 'identity.group.created'
- 'identity.group.deleted'
- 'identity.group.updated'
- 'identity.role.created'
- 'identity.role.deleted'
- 'identity.role.updated'
- 'identity.project.created'
- 'identity.project.deleted'
- 'identity.project.updated'
- 'identity.trust.created'
- 'identity.trust.deleted'
- 'identity.role_assignment.created'
- 'identity.role_assignment.deleted'
- resource_type: ceph_account
metrics:
- 'radosgw.objects'
- 'radosgw.objects.size'
- 'radosgw.objects.containers'
- 'radosgw.api.request'
- 'radosgw.containers.objects'
- 'radosgw.containers.objects.size'
- resource_type: instance
metrics:
- 'instance'
- 'memory'
- 'memory.usage'
- 'memory.resident'
- 'vcpus'
- 'cpu'
- 'cpu.delta'
- 'cpu_util'
- 'disk.root.size'
- 'disk.ephemeral.size'
- 'disk.read.requests'
- 'disk.read.requests.rate'
- 'disk.write.requests'
- 'disk.write.requests.rate'
- 'disk.read.bytes'
- 'disk.read.bytes.rate'
- 'disk.write.bytes'
- 'disk.write.bytes.rate'
- 'disk.latency'
- 'disk.iops'
- 'disk.capacity'
- 'disk.allocation'
- 'disk.usage'
attributes:
host: resource_metadata.host
image_ref: resource_metadata.image_ref
display_name: resource_metadata.display_name
flavor_id: resource_metadata.(instance_flavor_id|(flavor.id))
server_group: resource_metadata.user_metadata.server_group
- resource_type: instance_network_interface
metrics:
- 'network.outgoing.packets.rate'
- 'network.incoming.packets.rate'
- 'network.outgoing.packets'
- 'network.incoming.packets'
- 'network.outgoing.bytes.rate'
- 'network.incoming.bytes.rate'
- 'network.outgoing.bytes'
- 'network.incoming.bytes'
attributes:
name: resource_metadata.vnic_name
instance_id: resource_metadata.instance_id
- resource_type: instance_disk
metrics:
- 'disk.device.read.requests'
- 'disk.device.read.requests.rate'
- 'disk.device.write.requests'
- 'disk.device.write.requests.rate'
- 'disk.device.read.bytes'
- 'disk.device.read.bytes.rate'
- 'disk.device.write.bytes'
- 'disk.device.write.bytes.rate'
- 'disk.device.latency'
- 'disk.device.iops'
- 'disk.device.capacity'
- 'disk.device.allocation'
- 'disk.device.usage'
attributes:
name: resource_metadata.disk_name
instance_id: resource_metadata.instance_id
- resource_type: image
metrics:
- 'image'
- 'image.size'
- 'image.download'
- 'image.serve'
attributes:
name: resource_metadata.name
container_format: resource_metadata.container_format
disk_format: resource_metadata.disk_format
- resource_type: ipmi
metrics:
- 'hardware.ipmi.node.power'
- 'hardware.ipmi.node.temperature'
- 'hardware.ipmi.node.inlet_temperature'
- 'hardware.ipmi.node.outlet_temperature'
- 'hardware.ipmi.node.fan'
- 'hardware.ipmi.node.current'
- 'hardware.ipmi.node.voltage'
- 'hardware.ipmi.node.airflow'
- 'hardware.ipmi.node.cups'
- 'hardware.ipmi.node.cpu_util'
- 'hardware.ipmi.node.mem_util'
- 'hardware.ipmi.node.io_util'
- resource_type: network
metrics:
- 'bandwidth'
- 'network'
- 'network.create'
- 'network.update'
- 'subnet'
- 'subnet.create'
- 'subnet.update'
- 'port'
- 'port.create'
- 'port.update'
- 'router'
- 'router.create'
- 'router.update'
- 'ip.floating'
- 'ip.floating.create'
- 'ip.floating.update'
- resource_type: stack
metrics:
- 'stack.create'
- 'stack.update'
- 'stack.delete'
- 'stack.resume'
- 'stack.suspend'
- resource_type: swift_account
metrics:
- 'storage.objects.incoming.bytes'
- 'storage.objects.outgoing.bytes'
- 'storage.api.request'
- 'storage.objects.size'
- 'storage.objects'
- 'storage.objects.containers'
- 'storage.containers.objects'
- 'storage.containers.objects.size'
- resource_type: volume
metrics:
- 'volume'
- 'volume.size'
- 'volume.create'
- 'volume.delete'
- 'volume.update'
- 'volume.resize'
- 'volume.attach'
- 'volume.detach'
attributes:
display_name: resource_metadata.display_name
- resource_type: host
metrics:
- 'hardware.cpu.load.1min'
- 'hardware.cpu.load.5min'
- 'hardware.cpu.load.15min'
- 'hardware.cpu.util'
- 'hardware.memory.total'
- 'hardware.memory.used'
- 'hardware.memory.swap.total'
- 'hardware.memory.swap.avail'
- 'hardware.memory.buffer'
- 'hardware.memory.cached'
- 'hardware.network.ip.outgoing.datagrams'
- 'hardware.network.ip.incoming.datagrams'
- 'hardware.system_stats.cpu.idle'
- 'hardware.system_stats.io.outgoing.blocks'
- 'hardware.system_stats.io.incoming.blocks'
attributes:
host_name: resource_metadata.resource_url
- resource_type: host_disk
metrics:
- 'hardware.disk.size.total'
- 'hardware.disk.size.used'
attributes:
host_name: resource_metadata.resource_url
device_name: resource_metadata.device
- resource_type: host_network_interface
metrics:
- 'hardware.network.incoming.bytes'
- 'hardware.network.outgoing.bytes'
- 'hardware.network.outgoing.errors'
attributes:
host_name: resource_metadata.resource_url
device_name: resource_metadata.name

View File

@ -4,7 +4,7 @@ maintainer_email 'openstack-dev@lists.openstack.org'
license 'Apache 2.0' license 'Apache 2.0'
description 'The OpenStack Metering service Ceilometer.' description 'The OpenStack Metering service Ceilometer.'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '12.0.0' version '13.0.0'
recipe 'openstack-telemetry::agent-central', 'Installs agent central service.' recipe 'openstack-telemetry::agent-central', 'Installs agent central service.'
recipe 'openstack-telemetry::agent-compute', 'Installs agent compute service.' recipe 'openstack-telemetry::agent-compute', 'Installs agent compute service.'
@ -17,10 +17,9 @@ recipe 'openstack-telemetry::alarm-notifier', 'Installs the alarm notifier servi
recipe 'openstack-telemetry::common', 'Common metering configuration.' recipe 'openstack-telemetry::common', 'Common metering configuration.'
recipe 'openstack-telemetry::identity_registration', 'Registers the endpoints, tenant and user for metering service with Keystone' recipe 'openstack-telemetry::identity_registration', 'Registers the endpoints, tenant and user for metering service with Keystone'
%w(ubuntu suse).each do |os| %w(ubuntu redhat centos).each do |os|
supports os supports os
end end
depends 'openstack-common', '>= 12.0.0' depends 'openstack-common', '>= 13.0.0'
depends 'openstack-identity', '>= 12.0.0' depends 'openstack-identity', '>= 13.0.0'
depends 'openstack-compute', '>= 12.0.0'

View File

@ -31,8 +31,6 @@ end
service 'ceilometer-agent-central' do service 'ceilometer-agent-central' do
service_name platform['agent_central_service'] service_name platform['agent_central_service']
supports status: true, restart: true subscribes :restart, "template[#{node['openstack']['telemetry']['conf_file']}]"
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start] action [:enable, :start]
end end

View File

@ -29,20 +29,8 @@ platform['agent_compute_packages'].each do |pkg|
end end
end end
# temp fix for compute-agent init not installing properly ubuntu
# See https://bugs.launchpad.net/cloud-archive/+bug/1221945
if node['platform'] == 'ubuntu'
init_script = '/etc/init/ceilometer-agent-compute.conf'
execute 'fix init script' do
command "cp #{init_script}.dpkg-new #{init_script}"
not_if { ::File.exist?(init_script) }
end
end
service 'ceilometer-agent-compute' do service 'ceilometer-agent-compute' do
service_name platform['agent_compute_service'] service_name platform['agent_compute_service']
supports status: true, restart: true subscribes :restart, "template[#{node['openstack']['telemetry']['conf_file']}]"
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start] action [:enable, :start]
end end

View File

@ -30,8 +30,6 @@ end
service 'ceilometer-agent-notification' do service 'ceilometer-agent-notification' do
service_name platform['agent_notification_service'] service_name platform['agent_notification_service']
supports status: true, restart: true subscribes :restart, "template[#{node['openstack']['telemetry']['conf_file']}]"
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start] action [:enable, :start]
end end

View File

@ -1,37 +0,0 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-telemetry
# Recipe:: alarm-evaluator
#
# Copyright 2014, IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include_recipe 'openstack-telemetry::common'
platform = node['openstack']['telemetry']['platform']
platform['alarm_evaluator_packages'].each do |pkg|
package pkg do
options platform['package_overrides']
action :upgrade
end
end
service 'ceilometer-agent-evaluator' do
service_name platform['alarm_evaluator_service']
supports status: true, restart: true
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start]
end

View File

@ -22,12 +22,6 @@
include_recipe 'openstack-telemetry::common' include_recipe 'openstack-telemetry::common'
directory ::File.dirname(node['openstack']['telemetry']['api']['auth']['cache_dir']) do
owner node['openstack']['telemetry']['user']
group node['openstack']['telemetry']['group']
mode 00700
end
platform = node['openstack']['telemetry']['platform'] platform = node['openstack']['telemetry']['platform']
platform['api_packages'].each do |pkg| platform['api_packages'].each do |pkg|
package pkg do package pkg do
@ -38,8 +32,6 @@ end
service 'ceilometer-api' do service 'ceilometer-api' do
service_name platform['api_service'] service_name platform['api_service']
supports status: true, restart: true subscribes :restart, "template[#{node['openstack']['telemetry']['conf_file']}]"
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start] action [:enable, :start]
end end

View File

@ -22,13 +22,6 @@
include_recipe 'openstack-telemetry::common' include_recipe 'openstack-telemetry::common'
conf_switch = "--config-file #{node['openstack']['telemetry']['conf']}"
execute 'database migration' do
command "ceilometer-dbsync #{conf_switch}"
timeout node['openstack']['telemetry']['dbsync_timeout']
end
platform = node['openstack']['telemetry']['platform'] platform = node['openstack']['telemetry']['platform']
platform['collector_packages'].each do |pkg| platform['collector_packages'].each do |pkg|
package pkg do package pkg do
@ -37,20 +30,13 @@ platform['collector_packages'].each do |pkg|
end end
end end
# temp fix for collector init not installing properly ubuntu conf_switch = "--config-file #{node['openstack']['telemetry']['conf_file']}"
# See https://bugs.launchpad.net/cloud-archive/+bug/1221945 execute 'database migration' do
if node['platform'] == 'ubuntu' command "ceilometer-dbsync #{conf_switch}"
init_script = '/etc/init/ceilometer-collector.conf'
execute 'fix init script' do
command "cp #{init_script}.dpkg-new #{init_script}"
not_if { ::File.exist?(init_script) }
end
end end
service 'ceilometer-collector' do service 'ceilometer-collector' do
service_name platform['collector_service'] service_name platform['collector_service']
supports status: true, restart: true subscribes :restart, "template[#{node['openstack']['telemetry']['conf_file']}]"
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start] action [:enable, :start]
end end

View File

@ -44,70 +44,63 @@ platform['common_packages'].each do |pkg|
end end
end end
mq_service_type = node['openstack']['mq']['telemetry']['service_type'] if node['openstack']['telemetry']['conf']['DEFAULT']['rpc_backend'] == 'rabbit'
user = node['openstack']['mq']['telemetry']['rabbit']['userid']
if mq_service_type == 'rabbitmq' node.default['openstack']['telemetry']['conf_secrets']
node['openstack']['mq']['telemetry']['rabbit']['ha'] && (rabbit_hosts = rabbit_servers) .[]('oslo_messaging_rabbit')['rabbit_userid'] = user
mq_password = get_password 'user', node['openstack']['mq']['telemetry']['rabbit']['userid'] node.default['openstack']['telemetry']['conf_secrets']
elsif mq_service_type == 'qpid' .[]('oslo_messaging_rabbit')['rabbit_password'] =
mq_password = get_password 'user', node['openstack']['mq']['telemetry']['qpid']['username'] get_password 'user', user
end end
db_user = node['openstack']['db']['telemetry']['username'] db_user = node['openstack']['db']['telemetry']['username']
db_pass = get_password 'db', 'ceilometer' db_pass = get_password 'db', 'ceilometer'
db_uri = db_uri('telemetry', db_user, db_pass).to_s bind_service = node['openstack']['bind_service']['all']['telemetry']
bind_service_address = bind_address bind_service
service_user = node['openstack']['telemetry']['service_user'] # define secrets that are needed in the ceilometer.conf
service_pass = get_password 'service', 'openstack-ceilometer' node.default['openstack']['telemetry']['conf_secrets'].tap do |conf_secrets|
service_tenant = node['openstack']['telemetry']['service_tenant_name'] conf_secrets['database']['connection'] =
db_uri('telemetry', db_user, db_pass)
conf_secrets['service_credentials']['password'] =
get_password 'service', 'openstack-telemetry'
conf_secrets['keystone_authtoken']['password'] =
get_password 'service', 'openstack-telemetry'
end
identity_endpoint = internal_endpoint 'identity-internal' identity_public_endpoint = public_endpoint 'identity'
identity_admin_endpoint = admin_endpoint 'identity-admin' auth_url =
image_endpoint = internal_endpoint 'image-api' auth_uri_transform(
telemetry_api_bind = endpoint 'telemetry-api-bind' identity_public_endpoint.to_s,
node['openstack']['telemetry']['identity-api']['auth']['version']
)
auth_uri = auth_uri_transform identity_endpoint.to_s, node['openstack']['telemetry']['api']['auth']['version'] node.default['openstack']['telemetry']['conf'].tap do |conf|
identity_uri = identity_uri_transform(identity_admin_endpoint) conf['api']['host'] = bind_service_address
conf['api']['port'] = bind_service.port
Chef::Log.debug("openstack-telemetry::common:service_user|#{service_user}") conf['keystone_authtoken']['auth_url'] = auth_url
Chef::Log.debug("openstack-telemetry::common:service_tenant|#{service_tenant}") conf['service_credentials']['auth_url'] = auth_url
Chef::Log.debug("openstack-telemetry::common:identity_endpoint|#{identity_endpoint}") conf['dispatcher_gnocchi']['url'] = public_endpoint 'telemetry-metric'
conf['dispatcher_gnocchi']['filter_project'] = 'service'
metering_secret = get_password 'token', 'openstack_metering_secret' end
directory node['openstack']['telemetry']['conf_dir'] do directory node['openstack']['telemetry']['conf_dir'] do
owner node['openstack']['telemetry']['user'] owner node['openstack']['telemetry']['user']
group node['openstack']['telemetry']['group'] group node['openstack']['telemetry']['group']
mode 00750 mode 00750
action :create action :create
end end
if node['openstack']['telemetry']['hypervisor_inspector'] == 'vsphere' # merge all config options and secrets to be used in the ceilometer.conf
vmware_host_pass = get_password 'token', node['openstack']['compute']['vmware']['secret_name'] ceilometer_conf_options = merge_config_options 'telemetry'
end
template node['openstack']['telemetry']['conf'] do template node['openstack']['telemetry']['conf_file'] do
source 'ceilometer.conf.erb' source 'openstack-service.conf.erb'
cookbook 'openstack-common'
owner node['openstack']['telemetry']['user'] owner node['openstack']['telemetry']['user']
group node['openstack']['telemetry']['group'] group node['openstack']['telemetry']['group']
mode 00640 mode 00640
variables( variables(
auth_uri: auth_uri, service_config: ceilometer_conf_options
identity_uri: identity_uri,
database_connection: db_uri,
image_endpoint: image_endpoint,
identity_endpoint: identity_endpoint,
mq_service_type: mq_service_type,
mq_password: mq_password,
rabbit_hosts: rabbit_hosts,
service_pass: service_pass,
service_tenant_name: service_tenant,
service_user: service_user,
metering_secret: metering_secret,
api_bind_host: telemetry_api_bind.host,
api_bind_port: telemetry_api_bind.port,
vmware_host_pass: vmware_host_pass
) )
end end

View File

@ -0,0 +1,108 @@
# encoding: UTF-8
#
# Cookbook Name:: openstack-telemetry
# Recipe:: gnocchi_configure
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
platform = node['openstack']['telemetry']['platform']
db_user = node['openstack']['db']['telemetry-metric']['username']
db_pass = get_password 'db', 'gnocchi'
bind_service = node['openstack']['bind_service']['all']['telemetry-metric']
bind_service_address = bind_address bind_service
# define secrets that are needed in the gnocchi.conf
node.default['openstack']['telemetry-metric']['conf_secrets'].tap do |conf_secrets|
conf_secrets['database']['connection'] =
db_uri('telemetry-metric', db_user, db_pass)
conf_secrets['indexer']['url'] =
db_uri('telemetry-metric', db_user, db_pass)
conf_secrets['keystone_authtoken']['password'] =
get_password 'service', 'openstack-telemetry-metric'
end
identity_public_endpoint = public_endpoint 'identity'
auth_url =
auth_uri_transform(
identity_public_endpoint.to_s,
node['openstack']['telemetry-metric']['identity-api']['auth']['version']
)
node.default['openstack']['telemetry-metric']['conf'].tap do |conf|
conf['api']['host'] = bind_service_address
conf['api']['port'] = bind_service.port
conf['keystone_authtoken']['auth_url'] = auth_url
end
# merge all config options and secrets to be used in the gnocchi.conf
gnocchi_conf_options = merge_config_options 'telemetry-metric'
template node['openstack']['telemetry-metric']['conf_file'] do
source 'openstack-service.conf.erb'
cookbook 'openstack-common'
owner node['openstack']['telemetry-metric']['user']
group node['openstack']['telemetry-metric']['group']
mode 00640
variables(
service_config: gnocchi_conf_options
)
end
# drop gnocchi_resources.yaml to ceilometer folder (current workaround since not
# included in ubuntu package)
cookbook_file File.join(node['openstack']['telemetry']['conf_dir'], 'gnocchi_resources.yaml') do
source 'gnocchi_resources.yaml'
owner node['openstack']['telemetry']['user']
group node['openstack']['telemetry']['group']
mode 00640
end
# drop api-paste.ini to gnocchi folder (default ini will not use keystone auth)
cookbook_file File.join(node['openstack']['telemetry-metric']['conf_dir'], 'api-paste.ini') do
source 'api-paste.ini'
owner node['openstack']['telemetry-metric']['user']
group node['openstack']['telemetry-metric']['group']
mode 00640
end
if node['openstack']['telemetry-metric']['conf']['storage']['driver'] == 'file'
# default store is file, so create needed directories with correct permissions
# (on ubuntu they are created by the package, but owned by root and not writable
# for gnocchi)
store_path = node['openstack']['telemetry-metric']['conf']['storage']['file_basepath']
%w(tmp measure cache).each do |dir|
directory File.join(store_path, dir) do
owner node['openstack']['telemetry-metric']['user']
group node['openstack']['telemetry-metric']['group']
recursive true
mode 00750
end
end
end
# dbsync for gnocchi
execute 'gnocchi-upgrade' do
user node['openstack']['telemetry-metric']['user']
end
service 'gnocchi-api' do
service_name platform['gnocchi-api_service']
subscribes :restart, "template[#{node['openstack']['telemetry-metric']['conf_file']}]"
action [:enable, :start]
end
service 'gnocchi-metricd' do
service_name platform['gnocchi-metricd_service']
subscribes :restart, "template[#{node['openstack']['telemetry-metric']['conf_file']}]"
action [:enable, :start]
end

View File

@ -1,9 +1,7 @@
# encoding: UTF-8 # encoding: UTF-8
# #
# Cookbook Name:: openstack-telemetry # Cookbook Name:: openstack-telemetry
# Recipe:: alarm-notifier # Recipe:: gnocchi_install
#
# Copyright 2014, IBM Corp.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -21,17 +19,9 @@
include_recipe 'openstack-telemetry::common' include_recipe 'openstack-telemetry::common'
platform = node['openstack']['telemetry']['platform'] platform = node['openstack']['telemetry']['platform']
platform['alarm_notifier_packages'].each do |pkg| platform['gnocchi_packages'].each do |pkg|
package pkg do package pkg do
options platform['package_overrides'] options platform['package_overrides']
action :upgrade action :upgrade
end end
end end
service 'ceilometer-alarm-notifier' do
service_name platform['alarm_notifier_service']
supports status: true, restart: true
subscribes :restart, "template[#{node['openstack']['telemetry']['conf']}]"
action [:enable, :start]
end

View File

@ -24,67 +24,83 @@ class ::Chef::Recipe # rubocop:disable Documentation
include ::Openstack include ::Openstack
end end
admin_api_endpoint = admin_endpoint 'telemetry-api' identity_admin_endpoint = admin_endpoint 'identity'
internal_api_endpoint = internal_endpoint 'telemetry-api'
public_api_endpoint = public_endpoint 'telemetry-api'
identity_admin_endpoint = admin_endpoint 'identity-admin'
bootstrap_token = get_password 'token', 'openstack_identity_bootstrap_token' bootstrap_token = get_password 'token', 'openstack_identity_bootstrap_token'
auth_uri = ::URI.decode identity_admin_endpoint.to_s auth_uri = ::URI.decode identity_admin_endpoint.to_s
service_pass = get_password 'service', 'openstack-ceilometer'
service_user = node['openstack']['telemetry']['service_user']
service_role = node['openstack']['telemetry']['service_role']
service_tenant_name = node['openstack']['telemetry']['service_tenant_name']
# Register Service Tenant %w(telemetry telemetry-metric).each do |telemetry_service|
openstack_identity_register 'Register Service Tenant' do case telemetry_service
auth_uri auth_uri when 'telemetry'
bootstrap_token bootstrap_token service_name = 'ceilometer'
tenant_name service_tenant_name service_type = 'metering'
tenant_description 'Service Tenant' when 'telemetry-metric'
service_name = 'gnocchi'
service_type = 'metric'
end
action :create_tenant admin_api_endpoint = admin_endpoint telemetry_service
end internal_api_endpoint = internal_endpoint telemetry_service
public_api_endpoint = public_endpoint telemetry_service
# Register Service User
openstack_identity_register 'Register Service User' do service_pass = get_password 'service', "openstack-#{telemetry_service}"
auth_uri auth_uri service_role = node['openstack'][telemetry_service]['service_role']
bootstrap_token bootstrap_token service_user =
tenant_name service_tenant_name node['openstack'][telemetry_service]['conf']['keystone_authtoken']['username']
user_name service_user service_tenant_name =
user_pass service_pass node['openstack'][telemetry_service]['conf']['keystone_authtoken']['project_name']
action :create_user # Register Service Tenant
end openstack_identity_register "Register Service Tenant for #{telemetry_service}" do
auth_uri auth_uri
# Grant Admin role to Service User for Service Tenant bootstrap_token bootstrap_token
openstack_identity_register "Grant 'admin' Role to Service User for Service Tenant" do tenant_name service_tenant_name
auth_uri auth_uri tenant_description 'Service Tenant'
bootstrap_token bootstrap_token
tenant_name service_tenant_name action :create_tenant
user_name service_user end
role_name service_role
# Register Service User
action :grant_role openstack_identity_register "Register #{service_user} User" do
end auth_uri auth_uri
bootstrap_token bootstrap_token
openstack_identity_register 'Register Metering Service' do tenant_name service_tenant_name
auth_uri auth_uri user_name service_user
bootstrap_token bootstrap_token user_pass service_pass
service_name 'ceilometer'
service_type 'metering' action :create_user
service_description 'Ceilometer Service' end
action :create_service # Grant Admin role to Service User for Service Tenant
end openstack_identity_register "Grant 'admin' Role to #{service_user} User for Service Tenant" do
auth_uri auth_uri
openstack_identity_register 'Register Metering Endpoint' do bootstrap_token bootstrap_token
auth_uri auth_uri tenant_name service_tenant_name
bootstrap_token bootstrap_token user_name service_user
service_type 'metering' role_name service_role
endpoint_region node['openstack']['telemetry']['region']
endpoint_adminurl ::URI.decode admin_api_endpoint.to_s action :grant_role
endpoint_internalurl ::URI.decode internal_api_endpoint.to_s end
endpoint_publicurl ::URI.decode public_api_endpoint.to_s
openstack_identity_register "Register Service #{telemetry_service}" do
action :create_endpoint auth_uri auth_uri
bootstrap_token bootstrap_token
service_name service_name
service_type service_type
service_description 'Ceilometer Service'
action :create_service
end
openstack_identity_register "Register #{service_type} Endpoint" do
auth_uri auth_uri
bootstrap_token bootstrap_token
service_type service_type
endpoint_region node['openstack'][telemetry_service]['conf']['keystone_authtoken']['region_name']
endpoint_adminurl ::URI.decode admin_api_endpoint.to_s
endpoint_internalurl ::URI.decode internal_api_endpoint.to_s
endpoint_publicurl ::URI.decode public_api_endpoint.to_s
action :create_endpoint
end
end end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::agent-central' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the agent-central package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-agent-central'
end
it 'starts the agent-central service' do
expect(chef_run).to start_service 'openstack-ceilometer-agent-central'
end
end
end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::agent-compute' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the agent-compute package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-agent-compute'
end
it 'starts the agent-compute service' do
expect(chef_run).to start_service 'openstack-ceilometer-agent-compute'
end
end
end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::agent-notification' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the agent-notification package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-agent-notification'
end
it 'starts the agent-notification service' do
expect(chef_run).to start_service 'openstack-ceilometer-agent-notification'
end
end
end

View File

@ -1,22 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-evaluator' do
describe 'rhel' do
let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe'
it 'installs the alarm-evaluator package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-alarm'
end
it 'starts the alarm-evaluator service' do
expect(chef_run).to start_service 'openstack-ceilometer-alarm-evaluator'
end
end
end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-evaluator' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the alarm-evaluator package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-alarm-evaluator'
end
it 'starts the alarm-evaluator service' do
expect(chef_run).to start_service 'openstack-ceilometer-alarm-evaluator'
end
end
end

View File

@ -1,29 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-evaluator' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe'
it 'installs the alarm-evaluator package' do
expect(chef_run).to upgrade_package 'ceilometer-alarm-evaluator'
end
it 'starts and enables the alarm-evaluator service' do
expect(chef_run).to enable_service('ceilometer-alarm-evaluator')
expect(chef_run).to start_service('ceilometer-alarm-evaluator')
end
describe 'ceilometer-alarm-evaluator' do
it 'subscribes to its config file' do
expect(chef_run.service('ceilometer-alarm-evaluator')).to subscribe_to('template[/etc/ceilometer/ceilometer.conf]').delayed
end
end
end
end

View File

@ -1,22 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-notifier' do
describe 'rhel' do
let(:runner) { ChefSpec::SoloRunner.new(REDHAT_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe'
it 'installs the alarm-notifier package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-alarm'
end
it 'starts the alarm-notifier service' do
expect(chef_run).to start_service 'openstack-ceilometer-alarm-notifier'
end
end
end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-notifier' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the alarm-notifier package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-alarm-notifier'
end
it 'starts the alarm-notifier service' do
expect(chef_run).to start_service 'openstack-ceilometer-alarm-notifier'
end
end
end

View File

@ -1,29 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::alarm-notifier' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe'
it 'installs the alarm-notifier package' do
expect(chef_run).to upgrade_package 'ceilometer-alarm-notifier'
end
it 'starts and enables the alarm-notifier service' do
expect(chef_run).to enable_service('ceilometer-alarm-notifier')
expect(chef_run).to start_service('ceilometer-alarm-notifier')
end
describe 'ceilometer-alarm-notifier' do
it 'subscribes to its config file' do
expect(chef_run.service('ceilometer-alarm-notifier')).to subscribe_to('template[/etc/ceilometer/ceilometer.conf]').delayed
end
end
end
end

View File

@ -11,14 +11,6 @@ describe 'openstack-telemetry::api' do
include_context 'telemetry-stubs' include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe' include_examples 'expect-runs-common-recipe'
it 'creates the /var/cache/ceilometer directory' do
expect(chef_run).to create_directory('/var/cache/ceilometer').with(
user: 'ceilometer',
group: 'ceilometer',
mode: 0700
)
end
it 'installs the api package' do it 'installs the api package' do
expect(chef_run).to upgrade_package('openstack-ceilometer-api') expect(chef_run).to upgrade_package('openstack-ceilometer-api')
end end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::api' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the api package' do
expect(chef_run).to upgrade_package('openstack-ceilometer-api')
end
it 'starts api service' do
expect(chef_run).to start_service('openstack-ceilometer-api')
end
end
end

View File

@ -11,14 +11,6 @@ describe 'openstack-telemetry::api' do
include_context 'telemetry-stubs' include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe' include_examples 'expect-runs-common-recipe'
it 'creates the /var/cache/ceilometer directory' do
expect(chef_run).to create_directory('/var/cache/ceilometer').with(
user: 'ceilometer',
group: 'ceilometer',
mode: 0700
)
end
it 'installs the api package' do it 'installs the api package' do
expect(chef_run).to upgrade_package 'ceilometer-api' expect(chef_run).to upgrade_package 'ceilometer-api'
end end

View File

@ -8,8 +8,12 @@ describe 'openstack-telemetry::client' do
let(:node) { runner.node } let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) } let(:chef_run) { runner.converge(described_recipe) }
it 'installs packages' do it do
expect(chef_run).to upgrade_package('python-ceilometerclient') expect(chef_run).to upgrade_package('python-ceilometerclient')
end end
it do
expect(chef_run).to upgrade_package('python-gnocchiclient')
end
end end
end end

View File

@ -11,14 +11,6 @@ describe 'openstack-telemetry::collector' do
include_context 'telemetry-stubs' include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe' include_examples 'expect-runs-common-recipe'
it 'executes ceilometer dbsync' do
node.set['openstack']['telemetry']['dbsync_timeout'] = 36000
command = 'ceilometer-dbsync --config-file /etc/ceilometer/ceilometer.conf'
expect(chef_run).to run_execute(command).with(
timeout: 36000
)
end
it 'installs the collector package' do it 'installs the collector package' do
expect(chef_run).to upgrade_package('openstack-ceilometer-collector') expect(chef_run).to upgrade_package('openstack-ceilometer-collector')
end end

View File

@ -1,21 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::collector' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs the collector package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer-collector'
end
it 'starts the collector service' do
expect(chef_run).to start_service 'openstack-ceilometer-collector'
end
end
end

View File

@ -11,24 +11,25 @@ describe 'openstack-telemetry::collector' do
include_context 'telemetry-stubs' include_context 'telemetry-stubs'
include_examples 'expect-runs-common-recipe' include_examples 'expect-runs-common-recipe'
it 'installs the collector package' do it do
expect(chef_run).to upgrade_package 'ceilometer-collector' expect(chef_run).to upgrade_package 'ceilometer-collector'
end end
it 'executes ceilometer dbsync' do it do
node.set['openstack']['telemetry']['dbsync_timeout'] = 36000 expect(chef_run).to run_execute(
command = 'ceilometer-dbsync --config-file /etc/ceilometer/ceilometer.conf' 'ceilometer-dbsync --config-file /etc/ceilometer/ceilometer.conf'
expect(chef_run).to run_execute(command).with(
timeout: 36000
) )
end end
it 'installs python-mysqldb' do it do
expect(chef_run).to upgrade_package('python-mysqldb') expect(chef_run).to upgrade_package('python-mysqldb')
end end
it 'starts and enables the collector service' do it do
expect(chef_run).to enable_service('ceilometer-collector') expect(chef_run).to enable_service('ceilometer-collector')
end
it do
expect(chef_run).to start_service('ceilometer-collector') expect(chef_run).to start_service('ceilometer-collector')
end end

View File

@ -1,26 +0,0 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::common' do
describe 'suse' do
let(:runner) { ChefSpec::SoloRunner.new(SUSE_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it 'installs mysql python packages by default' do
expect(chef_run).to upgrade_package 'python-mysql'
end
it 'installs postgresql python packages if explicitly told' do
node.set['openstack']['db']['telemetry']['service_type'] = 'postgresql'
expect(chef_run).to upgrade_package 'python-psycopg2'
end
it 'installs the common package' do
expect(chef_run).to upgrade_package 'openstack-ceilometer'
end
end
end

View File

@ -56,352 +56,77 @@ describe 'openstack-telemetry::common' do
) )
end end
it 'has default values' do it do
node.set['openstack']['telemetry']['syslog']['use'] = true expect(chef_run).to render_config_file(file.name)
[%r{^os_auth_url = http://127.0.0.1:5000/v2.0$}, .with_section_content('DEFAULT', /^meter_dispatchers = gnocchi$/)
/^os_tenant_name = service$/,
/^os_password = ceilometer-pass$/,
/^os_username = ceilometer$/,
/^verbose = true$/,
/^debug = false$/,
%r{^log_config = /etc/openstack/logging.conf$},
/^glance_registry_host = 127.0.0.1$/,
/^periodic_interval = 600$/].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('DEFAULT', line)
end
end end
it 'has default sample_source set' do it do
expect(chef_run).to render_file(file.name).with_content(
/^sample_source = openstack$/)
end
it 'has default os_region_name set' do
expect(chef_run).to render_file(file.name).with_content(
/^os_region_name = RegionOne$/)
end
it 'has sample_source set' do
node.set['openstack']['telemetry']['sample_source'] = 'RegionOne'
expect(chef_run).to render_file(file.name).with_content(
/^sample_source = RegionOne$/)
end
context 'rabbit mq backend' do
before do
node.set['openstack']['mq']['telemetry']['service_type'] = 'rabbitmq'
end
it 'has default RPC/AMQP options set' do
[/^amqp_durable_queues=false$/,
/^amqp_auto_delete=false$/,
/^heartbeat_timeout_threshold=0$/,
/^heartbeat_rate=2$/].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
describe 'ha rabbit disabled' do
before do
node.override['openstack']['mq']['telemetry']['rabbit']['ha'] = false
end
it 'has default rabbit_* options set' do
[
/^rabbit_userid = guest$/,
/^rabbit_password = mq-pass$/,
/^rabbit_port = 5672$/,
/^rabbit_host = 127.0.0.1$/,
%r{^rabbit_virtual_host = /$},
/^rabbit_max_retries = 0$/,
/^rabbit_retry_interval = 1$/
].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'does not have ha rabbit options set' do
[/^rabbit_hosts = /,
/^rabbit_ha_queues = /].each do |line|
expect(chef_run).not_to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
end
describe 'ha rabbit enabled' do
before do
node.override['openstack']['mq']['telemetry']['rabbit']['ha'] = true
end
it 'sets ha rabbit options correctly' do
[
/^rabbit_userid = guest$/,
/^rabbit_password = mq-pass$/,
/^rabbit_hosts = 1.1.1.1:5672,2.2.2.2:5672$/,
/^rabbit_ha_queues = True$/,
%r{^rabbit_virtual_host = /$}
].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'does not have non-ha rabbit options set' do
[/^rabbit_host = /,
/^rabbit_port = /].each do |line|
expect(chef_run).not_to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
end
it 'does not have ssl config set' do
[/^rabbit_use_ssl=/,
/^kombu_ssl_version=/,
/^kombu_ssl_keyfile=/,
/^kombu_ssl_certfile=/,
/^kombu_ssl_ca_certs=/,
/^kombu_reconnect_delay=/,
/^kombu_reconnect_timeout=/].each do |line|
expect(chef_run).not_to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
it 'sets ssl config' do
node.set['openstack']['mq']['telemetry']['rabbit']['use_ssl'] = true
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_version'] = 'TLSv1.2'
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_keyfile'] = 'keyfile'
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_certfile'] = 'certfile'
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_ca_certs'] = 'certsfile'
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_reconnect_delay'] = 123.123
node.set['openstack']['mq']['telemetry']['rabbit']['kombu_reconnect_timeout'] = 123
[/^rabbit_use_ssl=true/,
/^kombu_ssl_version=TLSv1.2$/,
/^kombu_ssl_keyfile=keyfile$/,
/^kombu_ssl_certfile=certfile$/,
/^kombu_ssl_ca_certs=certsfile$/,
/^kombu_reconnect_delay=123.123$/,
/^kombu_reconnect_timeout=123$/].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_rabbit', line)
end
end
end
context 'qpid mq backend' do
before do
node.set['openstack']['mq']['telemetry']['service_type'] = 'qpid'
node.set['openstack']['mq']['telemetry']['qpid']['username'] = 'guest'
end
it 'has default RPC/AMQP options set' do
[/^amqp_durable_queues=false$/,
/^amqp_auto_delete=false$/].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_qpid', line)
end
end
it 'has default qpid_* options set' do
[
/^qpid_hostname=127.0.0.1$/,
/^qpid_port=5672$/,
/^qpid_username=guest$/,
/^qpid_password=mq-pass$/,
/^qpid_sasl_mechanisms=$/,
/^qpid_reconnect=true$/,
/^qpid_reconnect_timeout=0$/,
/^qpid_reconnect_limit=0$/,
/^qpid_reconnect_interval_min=0$/,
/^qpid_reconnect_interval_max=0$/,
/^qpid_reconnect_interval_max=0$/,
/^qpid_reconnect_interval=0$/,
/^qpid_heartbeat=60$/,
/^qpid_protocol=tcp$/,
/^qpid_tcp_nodelay=true$/,
/^qpid_topology_version=1$/
].each do |line|
expect(chef_run).to render_config_file(file.name).with_section_content('oslo_messaging_qpid', line)
end
end
end
context 'database' do
it 'has connection set' do
expect(chef_run).to render_config_file(file.name)\
.with_section_content('database', /^#{Regexp.quote('connection=mysql://ceilometer:@127.0.0.1:3306/ceilometer?charset=utf8')}$/)
end
it 'has time_to_live set' do
expect(chef_run).to render_config_file(file.name)\
.with_section_content('database', /^time_to_live=1800$/)
end
end
context 'service_credentials attributes with default values' do
it 'sets cafile' do
expect(chef_run).not_to render_file(file.name).with_content(/^os_cacert = $/)
end
it 'sets insecure' do
expect(chef_run).to render_file(file.name).with_content(/^insecure = false$/)
end
end
context 'service_credentials attributes' do
it 'sets cafile' do
node.set['openstack']['telemetry']['service-credentials']['cafile'] = 'dir/to/path'
expect(chef_run).to render_file(file.name).with_content(%r{^os_cacert = dir/to/path$})
end
it 'sets insecure' do
node.set['openstack']['telemetry']['service-credentials']['insecure'] = true
expect(chef_run).to render_file(file.name).with_content(/^insecure = true$/)
end
end
context 'keystone authtoken attributes with default values' do
it 'sets memcached server(s)' do
expect(chef_run).not_to render_file(file.name).with_content(/^memcached_servers = $/)
end
it 'sets memcache security strategy' do
expect(chef_run).not_to render_file(file.name).with_content(/^memcache_security_strategy = $/)
end
it 'sets memcache secret key' do
expect(chef_run).not_to render_file(file.name).with_content(/^memcache_secret_key = $/)
end
it 'sets cafile' do
expect(chef_run).not_to render_file(file.name).with_content(/^cafile = $/)
end
it 'sets token hash algorithms' do
expect(chef_run).to render_file(file.name).with_content(/^hash_algorithms = md5$/)
end
end
context 'has keystone authtoken configuration' do
it 'has auth_uri' do
expect(chef_run).to render_file(file.name).with_content(
/^#{Regexp.quote('auth_uri = http://127.0.0.1:5000/v2.0')}$/)
end
it 'has identity_uri' do
expect(chef_run).to render_file(file.name).with_content(
/^#{Regexp.quote('identity_uri = http://127.0.0.1:35357/')}$/)
end
it 'has no auth_version' do
expect(chef_run).not_to render_file(file.name).with_content(
/^auth_version = v2.0$/)
end
it 'has admin_tenant_name' do
expect(chef_run).to render_file(file.name).with_content(
/^admin_tenant_name = service$/)
end
it 'has admin_user' do
expect(chef_run).to render_file(file.name).with_content(
/^admin_user = ceilometer$/)
end
it 'has admin_password' do
expect(chef_run).to render_file(file.name).with_content(
/^admin_password = ceilometer-pass$/)
end
it 'has signing_dir' do
expect(chef_run).to render_file(file.name).with_content(
/^#{Regexp.quote('signing_dir = /var/cache/ceilometer/api')}$/)
end
it 'sets memcached server(s)' do
node.set['openstack']['telemetry']['api']['auth']['memcached_servers'] = 'localhost:11211'
expect(chef_run).to render_file(file.name).with_content(/^memcached_servers = localhost:11211$/)
end
it 'sets memcache security strategy' do
node.set['openstack']['telemetry']['api']['auth']['memcache_security_strategy'] = 'MAC'
expect(chef_run).to render_file(file.name).with_content(/^memcache_security_strategy = MAC$/)
end
it 'sets memcache secret key' do
node.set['openstack']['telemetry']['api']['auth']['memcache_secret_key'] = '0123456789ABCDEF'
expect(chef_run).to render_file(file.name).with_content(/^memcache_secret_key = 0123456789ABCDEF$/)
end
it 'sets cafile' do
node.set['openstack']['telemetry']['api']['auth']['cafile'] = 'dir/to/path'
expect(chef_run).to render_file(file.name).with_content(%r{^cafile = dir/to/path$})
end
it 'sets insecure' do
node.set['openstack']['telemetry']['api']['auth']['insecure'] = true
expect(chef_run).to render_file(file.name).with_content(/^insecure = true$/)
end
it 'sets token hash algorithm' do
node.set['openstack']['telemetry']['api']['auth']['hash_algorithms'] = 'sha2'
expect(chef_run).to render_file(file.name).with_content(/^hash_algorithms = sha2$/)
end
end
context 'set correct os_auth_url' do
it 'set default value for os_auth_url' do
node.set['openstack']['telemetry']['api']['auth']['version'] = 'v3.0'
expect(chef_run).to render_config_file(file.name)\
.with_section_content('DEFAULT', %r{^os_auth_url = http://127.0.0.1:5000/v2.0$})
end
it 'set customized os_auth_url' do
node.set['openstack']['endpoints']['identity-internal']['scheme'] = 'https'
node.set['openstack']['endpoints']['identity-internal']['host'] = 'fakehost'
node.set['openstack']['endpoints']['identity-internal']['port'] = '8888'
node.set['openstack']['endpoints']['identity-internal']['path'] = '/v3'
expect(chef_run).to render_config_file(file.name)\
.with_section_content('DEFAULT', %r{^os_auth_url = https://fakehost:8888/v3$})
end
end
it 'has metering secret' do
r = /^metering_secret = metering_secret$/
expect(chef_run).to render_file(file.name).with_content(r)
end
it 'has hypervisor inspector' do
r = /^hypervisor_inspector = libvirt$/
expect(chef_run).to render_file(file.name).with_content(r)
end
it 'has bind_host set' do
node.set['openstack']['endpoints']['telemetry-api-bind']['host'] = '1.1.1.1'
expect(chef_run).to render_file(file.name).with_content(
/^host = 1.1.1.1$/)
end
it 'has bind_port set' do
node.set['openstack']['endpoints']['telemetry-api-bind']['port'] = '9999'
expect(chef_run).to render_file(file.name).with_content(/^port = 9999$/)
end
it 'has vmware section' do
node.set['openstack']['compute']['driver'] = 'vmwareapi.VMwareVCDriver'
[ [
/^host_ip = $/, /^username = ceilometer$/,
/^host_username = $/, /^project_name = service$/,
/^host_password = vmware_secret_name$/, /^auth_type = password$/,
/^task_poll_interval = 0.5$/, /^region_name = RegionOne$/,
/^api_retry_count = 10$/ %r{auth_url = http://127\.0\.0\.1:5000/v2\.0},
/^password = ceilometer-pass$/
].each do |line| ].each do |line|
expect(chef_run).to render_file(file.name).with_content(line) expect(chef_run).to render_config_file(file.name)
.with_section_content('keystone_authtoken', line)
end end
end end
context 'notification' do it do
it 'has store_events option' do [
expect(chef_run).to render_config_file(file.name)\ /^username = ceilometer$/,
.with_section_content('notification', /^store_events = false$/) /^project_name = service$/,
/^auth_type = password$/,
/^interface = internal$/,
/^region_name = RegionOne$/,
%r{auth_url = http://127\.0\.0\.1:5000/v2\.0},
/^password = ceilometer-pass$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('service_credentials', line)
end end
end end
it do
[
/^host = 127\.0\.0\.1$/,
/^port = 8777$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('api', line)
end
end
it do
[
%r{url = http://127\.0\.0\.1:8041},
/^filter_project = service$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('dispatcher_gnocchi', line)
end
end
it do
[
/^rabbit_userid = guest$/,
/^rabbit_password = mq-pass$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('oslo_messaging_rabbit', line)
end
end
it do
expect(chef_run).to render_config_file(file.name)
.with_section_content(
'database',
%r{^connection = mysql://ceilometer:ceilometer-dbpass@127\.0\.0\.1:3306/ceilometer\?charset=utf8$}
)
end
end end
end end
end end

View File

@ -0,0 +1,125 @@
require_relative 'spec_helper'
describe 'openstack-telemetry::gnocchi_configure' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
describe 'gnocchi.conf' do
let(:file) { chef_run.template('/etc/gnocchi/gnocchi.conf') }
it do
expect(chef_run).to create_template(file.name).with(
user: 'gnocchi',
group: 'gnocchi',
mode: 0640
)
end
it do
[
/^username = gnocchi$/,
/^project_name = service$/,
/^auth_type = password$/,
/^region_name = RegionOne$/,
%r{auth_url = http://127\.0\.0\.1:5000/v2\.0},
/^password = gnocchi-pass$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('keystone_authtoken', line)
end
end
it do
[
/^host = 127\.0\.0\.1$/,
/^port = 8041$/
].each do |line|
expect(chef_run).to render_config_file(file.name)
.with_section_content('api', line)
end
end
it do
expect(chef_run).to render_config_file(file.name)
.with_section_content(
'database',
%r{^connection = mysql://gnocchi:gnocchi-dbpass@127\.0\.0\.1:3306/gnocchi\?charset=utf8$}
)
end
it do
expect(chef_run).to render_config_file(file.name)
.with_section_content(
'indexer',
%r{^url = mysql://gnocchi:gnocchi-dbpass@127\.0\.0\.1:3306/gnocchi\?charset=utf8$}
)
end
end
it do
expect(chef_run).to create_cookbook_file('/etc/ceilometer/gnocchi_resources.yaml')
.with(
source: 'gnocchi_resources.yaml',
owner: 'ceilometer',
group: 'ceilometer',
mode: 00640
)
end
it do
expect(chef_run).to create_cookbook_file('/etc/gnocchi/api-paste.ini')
.with(
source: 'api-paste.ini',
owner: 'gnocchi',
group: 'gnocchi',
mode: 00640
)
end
%w(tmp measure cache).each do |dir|
describe "gnocchi #{dir} dir" do
context 'file as storage backend' do
it do
expect(chef_run).to create_directory("/var/lib/gnocchi/#{dir}")
.with(
user: 'gnocchi',
group: 'gnocchi',
mode: 0750
)
end
end
context 'other storage backend' do
before do
node.set['openstack']['telemetry-metric']['conf']['storage']['driver'] = 'ceph'
end
it do
expect(chef_run).to_not create_directory("/var/lib/gnocchi/#{dir}")
.with(
user: 'gnocchi',
group: 'gnocchi',
mode: 0750
)
end
end
end
end
it do
expect(chef_run).to run_execute('gnocchi-upgrade')
.with(user: 'gnocchi')
end
%w(gnocchi-api gnocchi-metricd).each do |service|
it do
expect(chef_run).to enable_service(service)
end
it do
expect(chef_run).to start_service(service)
end
end
end
end

View File

@ -0,0 +1,21 @@
# encoding: UTF-8
require_relative 'spec_helper'
describe 'openstack-telemetry::gnocchi_install' do
describe 'ubuntu' do
let(:runner) { ChefSpec::SoloRunner.new(UBUNTU_OPTS) }
let(:node) { runner.node }
let(:chef_run) { runner.converge(described_recipe) }
include_context 'telemetry-stubs'
it do
expect(chef_run).to upgrade_package 'gnocchi-api'
end
it do
expect(chef_run).to upgrade_package 'gnocchi-metricd'
end
end
end

View File

@ -10,157 +10,80 @@ describe 'openstack-telemetry::identity_registration' do
include_context 'telemetry-stubs' include_context 'telemetry-stubs'
it 'registers service tenant' do %w(telemetry telemetry-metric).each do |telemetry_service|
expect(chef_run).to create_tenant_openstack_identity_register( case telemetry_service
'Register Service Tenant' when 'telemetry'
).with( service_name = 'ceilometer'
auth_uri: 'http://127.0.0.1:35357/v2.0', service_type = 'metering'
bootstrap_token: 'bootstrap-token', user_pass = 'ceilometer-pass'
tenant_name: 'service', port = 8777
tenant_description: 'Service Tenant' when 'telemetry-metric'
) service_name = 'gnocchi'
end service_type = 'metric'
user_pass = 'gnocchi-pass'
port = 8041
end
it 'registers service user' do it do
expect(chef_run).to create_user_openstack_identity_register( expect(chef_run).to create_tenant_openstack_identity_register(
'Register Service User' "Register Service Tenant for #{telemetry_service}"
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'service',
user_name: 'ceilometer',
user_pass: 'ceilometer-pass'
)
end
it 'grants admin role to service user for service tenant' do
expect(chef_run).to grant_role_openstack_identity_register(
"Grant 'admin' Role to Service User for Service Tenant"
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
tenant_name: 'service',
user_name: 'ceilometer',
role_name: 'admin'
)
end
it 'registers metering service' do
expect(chef_run).to create_service_openstack_identity_register(
'Register Metering Service'
).with(
auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token',
service_name: 'ceilometer',
service_type: 'metering'
)
end
context 'registers metering endpoint' do
it 'with default values' do
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Metering Endpoint'
).with( ).with(
auth_uri: 'http://127.0.0.1:35357/v2.0', auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token', bootstrap_token: 'bootstrap-token',
service_type: 'metering', tenant_name: 'service',
endpoint_region: 'RegionOne', tenant_description: 'Service Tenant'
endpoint_adminurl: 'http://127.0.0.1:8777',
endpoint_internalurl: 'http://127.0.0.1:8777',
endpoint_publicurl: 'http://127.0.0.1:8777'
) )
end end
it 'with different admin URL' do it do
admin_url = 'https://admin.host:123/admin_path' expect(chef_run).to create_user_openstack_identity_register(
general_url = 'http://general.host:456/general_path' "Register #{service_name} User"
# Set general endpoint
node.set['openstack']['endpoints']['telemetry-api']['uri'] = general_url
# Set the admin endpoint override
node.set['openstack']['endpoints']['admin']['telemetry-api']['uri'] = admin_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Metering Endpoint'
).with( ).with(
auth_uri: 'http://127.0.0.1:35357/v2.0', auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token', bootstrap_token: 'bootstrap-token',
service_type: 'metering', tenant_name: 'service',
endpoint_region: 'RegionOne', user_name: service_name,
endpoint_adminurl: admin_url, user_pass: user_pass
endpoint_internalurl: general_url,
endpoint_publicurl: general_url
) )
end end
it 'with different public URL' do it do
general_url = 'http://general.host:456/general_path' expect(chef_run).to grant_role_openstack_identity_register(
public_url = 'https://public.host:789/public_path' "Grant 'admin' Role to #{service_name} User for Service Tenant"
# Set general endpoint
node.set['openstack']['endpoints']['telemetry-api']['uri'] = general_url
# Set the public endpoint override
node.set['openstack']['endpoints']['public']['telemetry-api']['uri'] = public_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Metering Endpoint'
).with( ).with(
auth_uri: 'http://127.0.0.1:35357/v2.0', auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token', bootstrap_token: 'bootstrap-token',
service_type: 'metering', tenant_name: 'service',
endpoint_region: 'RegionOne', user_name: service_name,
endpoint_adminurl: general_url, role_name: 'admin'
endpoint_internalurl: general_url,
endpoint_publicurl: public_url
) )
end end
it 'with different internal URL' do it do
general_url = 'http://general.host:456/general_path' expect(chef_run).to create_service_openstack_identity_register(
internal_url = 'http://internal.host:456/internal_path' "Register Service #{telemetry_service}"
# Set general endpoint
node.set['openstack']['endpoints']['telemetry-api']['uri'] = general_url
# Set the internal endpoint override
node.set['openstack']['endpoints']['internal']['telemetry-api']['uri'] = internal_url
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Metering Endpoint'
).with( ).with(
auth_uri: 'http://127.0.0.1:35357/v2.0', auth_uri: 'http://127.0.0.1:35357/v2.0',
bootstrap_token: 'bootstrap-token', bootstrap_token: 'bootstrap-token',
service_type: 'metering', service_name: service_name,
endpoint_region: 'RegionOne', service_type: service_type
endpoint_adminurl: general_url,
endpoint_internalurl: internal_url,
endpoint_publicurl: general_url
) )
end end
it 'with all different URLs' do context "registers #{service_type} endpoint" do
admin_url = 'https://admin.host:123/admin_path' it do
internal_url = 'http://internal.host:456/internal_path' expect(chef_run).to create_endpoint_openstack_identity_register(
public_url = 'https://public.host:789/public_path' "Register #{service_type} Endpoint"
).with(
node.set['openstack']['endpoints']['admin']['telemetry-api']['uri'] = admin_url auth_uri: 'http://127.0.0.1:35357/v2.0',
node.set['openstack']['endpoints']['internal']['telemetry-api']['uri'] = internal_url bootstrap_token: 'bootstrap-token',
node.set['openstack']['endpoints']['public']['telemetry-api']['uri'] = public_url service_type: service_type,
expect(chef_run).to create_endpoint_openstack_identity_register( endpoint_region: 'RegionOne',
'Register Metering Endpoint' endpoint_adminurl: "http://127.0.0.1:#{port}",
).with( endpoint_internalurl: "http://127.0.0.1:#{port}",
auth_uri: 'http://127.0.0.1:35357/v2.0', endpoint_publicurl: "http://127.0.0.1:#{port}"
bootstrap_token: 'bootstrap-token', )
service_type: 'metering', end
endpoint_region: 'RegionOne',
endpoint_adminurl: admin_url,
endpoint_internalurl: internal_url,
endpoint_publicurl: public_url
)
end
it 'with custom region override' do
node.set['openstack']['telemetry']['region'] = 'meteringRegion'
expect(chef_run).to create_endpoint_openstack_identity_register(
'Register Metering Endpoint'
).with(endpoint_region: 'meteringRegion')
end end
end end
end end

View File

@ -7,11 +7,6 @@ ChefSpec::Coverage.start! { add_filter 'openstack-telemetry' }
require 'chef/application' require 'chef/application'
LOG_LEVEL = :fatal LOG_LEVEL = :fatal
SUSE_OPTS = {
platform: 'suse',
version: '11.3',
log_level: ::LOG_LEVEL
}
REDHAT_OPTS = { REDHAT_OPTS = {
platform: 'redhat', platform: 'redhat',
version: '7.1', version: '7.1',
@ -29,23 +24,23 @@ shared_context 'telemetry-stubs' do
.and_return '1.1.1.1:5672,2.2.2.2:5672' .and_return '1.1.1.1:5672,2.2.2.2:5672'
allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers).and_return([]) allow_any_instance_of(Chef::Recipe).to receive(:memcached_servers).and_return([])
allow_any_instance_of(Chef::Recipe).to receive(:get_password) allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('db', anything) .with('db', 'ceilometer')
.and_return('') .and_return('ceilometer-dbpass')
allow_any_instance_of(Chef::Recipe).to receive(:get_password) allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('service', 'openstack-ceilometer') .with('db', 'gnocchi')
.and_return('gnocchi-dbpass')
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('service', 'openstack-telemetry')
.and_return('ceilometer-pass') .and_return('ceilometer-pass')
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('service', 'openstack-telemetry-metric')
.and_return('gnocchi-pass')
allow_any_instance_of(Chef::Recipe).to receive(:get_password) allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('user', 'guest') .with('user', 'guest')
.and_return('mq-pass') .and_return('mq-pass')
allow_any_instance_of(Chef::Recipe).to receive(:get_password) allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('token', 'openstack_identity_bootstrap_token') .with('token', 'openstack_identity_bootstrap_token')
.and_return('bootstrap-token') .and_return('bootstrap-token')
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('token', 'openstack_metering_secret')
.and_return('metering_secret')
allow_any_instance_of(Chef::Recipe).to receive(:get_password)
.with('token', 'openstack_vmware_secret_name')
.and_return 'vmware_secret_name'
allow(Chef::Application).to receive(:fatal!) allow(Chef::Application).to receive(:fatal!)
end end
end end

View File

@ -1,198 +0,0 @@
[DEFAULT]
os_auth_url = <%= @identity_endpoint %>
os_tenant_name = <%= @service_tenant_name %>
os_password = <%= @service_pass %>
os_username = <%= @service_user %>
policy_file = /etc/ceilometer/policy.json
verbose = <%= node["openstack"]["telemetry"]["verbose"] %>
debug = <%= node["openstack"]["telemetry"]["debug"] %>
<% if node["openstack"]["telemetry"]["hypervisor_inspector"] %>
hypervisor_inspector = <%= node["openstack"]["telemetry"]["hypervisor_inspector"] %>
<% end %>
<% if node["openstack"]["telemetry"]["syslog"]["use"] %>
log_config = /etc/openstack/logging.conf
<% end %>
sample_source = <%= node["openstack"]["telemetry"]["sample_source"] %>
##### AMQP #####
notification_topics = notifications,glance_notifications
glance_registry_host = <%= @image_endpoint.host %>
periodic_interval = <%= node["openstack"]["telemetry"]["periodic_interval"] %>
[database]
connection=<%= @database_connection %>
time_to_live=<%= node["openstack"]["telemetry"]["database"]["time_to_live"] %>
[api]
host = <%= @api_bind_host %>
port = <%= @api_bind_port %>
[keystone_authtoken]
auth_uri = <%= @auth_uri %>
identity_uri = <%= @identity_uri %>
<% if node['openstack']['telemetry']['api']['auth']['version'] != 'v2.0' %>
auth_version = <%= node['openstack']['telemetry']['api']['auth']['version'] %>
<% end %>
admin_tenant_name = <%= @service_tenant_name %>
admin_user = <%= @service_user %>
admin_password = <%= @service_pass %>
signing_dir = <%= node["openstack"]["telemetry"]["api"]["auth"]["cache_dir"] %>
# A list of memcached server(s) to use for caching.
<% if node['openstack']['telemetry']['api']['auth']['memcached_servers'] %>
memcached_servers = <%= node['openstack']['telemetry']['api']['auth']['memcached_servers'] %>
<% end %>
# Whether token data should be authenticated or authenticated and encrypted. Acceptable values are MAC or ENCRYPT.
<% if node['openstack']['telemetry']['api']['auth']['memcache_security_strategy'] %>
memcache_security_strategy = <%= node['openstack']['telemetry']['api']['auth']['memcache_security_strategy'] %>
<% end %>
# This string is used for key derivation.
<% if node['openstack']['telemetry']['api']['auth']['memcache_secret_key'] %>
memcache_secret_key = <%= node['openstack']['telemetry']['api']['auth']['memcache_secret_key'] %>
<% end %>
# Hash algorithms to use for hashing PKI tokens.
hash_algorithms = <%= node['openstack']['telemetry']['api']['auth']['hash_algorithms'] %>
# A PEM encoded Certificate Authority to use when verifying HTTPs connections.
<% if node['openstack']['telemetry']['api']['auth']['cafile'] %>
cafile = <%= node['openstack']['telemetry']['api']['auth']['cafile'] %>
<% end %>
# Verify HTTPS connections. (boolean value)
insecure = <%= node['openstack']['telemetry']['api']['auth']['insecure'] %>
<% if @mq_service_type == "qpid" %>
[oslo_messaging_qpid]
#
# From oslo.messaging
#
# Use durable queues in AMQP. (boolean value)
amqp_durable_queues=<%= node["openstack"]["mq"]["telemetry"]["durable_queues"] %>
# Auto-delete queues in AMQP. (boolean value)
amqp_auto_delete=<%= node["openstack"]["mq"]["telemetry"]["auto_delete"] %>
##### QPID #####
rpc_backend=ceilometer.openstack.common.rpc.impl_qpid
qpid_hostname=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["host"] %>
qpid_port=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["port"] %>
qpid_password=<%= @mq_password %>
qpid_username=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["username"] %>
qpid_sasl_mechanisms=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["sasl_mechanisms"] %>
qpid_reconnect=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect"] %>
qpid_reconnect_timeout=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect_timeout"] %>
qpid_reconnect_limit=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect_limit"] %>
qpid_reconnect_interval_min=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect_interval_min"] %>
qpid_reconnect_interval_max=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect_interval_max"] %>
qpid_reconnect_interval=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["reconnect_interval"] %>
qpid_heartbeat=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["heartbeat"] %>
# qpid protocol. default 'tcp'. set to 'ssl' to enable SSL
qpid_protocol=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["protocol"] %>
qpid_tcp_nodelay=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["tcp_nodelay"] %>
qpid_topology_version=<%= node["openstack"]["mq"]["telemetry"]["qpid"]["topology_version"] %>
<% end %>
<% if @mq_service_type == "rabbitmq" %>
[oslo_messaging_rabbit]
#
# From oslo.messaging
#
# Number of seconds after which the Rabbit broker is considered down if heartbeat's keep-alive fails (0 disable the heartbeat)
heartbeat_timeout_threshold=<%= node['openstack']['mq']['telemetry']['rabbit']['heartbeat_timeout_threshold'] %>
# How often times during the heartbeat_timeout_threshold we check the heartbeat
heartbeat_rate=<%= node['openstack']['mq']['telemetry']['rabbit']['heartbeat_rate'] %>
# Use durable queues in AMQP. (boolean value)
amqp_durable_queues=<%= node["openstack"]["mq"]["telemetry"]["durable_queues"] %>
# Auto-delete queues in AMQP. (boolean value)
amqp_auto_delete=<%= node["openstack"]["mq"]["telemetry"]["auto_delete"] %>
<% if node['openstack']['mq']['telemetry']['rabbit']['use_ssl'] -%>
# Connect over SSL for RabbitMQ. (boolean value)
rabbit_use_ssl=true
<% if node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_version'] -%>
# SSL version to use (valid only if SSL enabled). valid values
# are TLSv1 and SSLv23. SSLv2 and SSLv3 may be available on
# some distributions. (string value)
kombu_ssl_version=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_version'] %>
<% end -%>
<% if node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_keyfile'] -%>
# SSL key file (valid only if SSL enabled)
kombu_ssl_keyfile=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_keyfile'] %>
<% end -%>
<% if node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_certfile'] -%>
# SSL cert file (valid only if SSL enabled)
kombu_ssl_certfile=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_certfile'] %>
<% end -%>
<% if node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_ca_certs'] -%>
# SSL certification authority file (valid only if SSL enabled)
kombu_ssl_ca_certs=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_ssl_ca_certs'] %>
<% end -%>
# How long to wait before reconnecting in response to an AMQP consumer cancel notification
kombu_reconnect_delay=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_reconnect_delay'] %>
# How long to wait before considering a reconnect attempt to have failed.
# This value should not be longer than rpc_response_timeout
kombu_reconnect_timeout=<%= node['openstack']['mq']['telemetry']['rabbit']['kombu_reconnect_timeout'] %>
<% end -%>
##### RABBITMQ #####
rabbit_userid = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["userid"] %>
rabbit_password = <%= @mq_password %>
<% if node["openstack"]["mq"]["telemetry"]["rabbit"]["ha"] %>
rabbit_hosts = <%= @rabbit_hosts %>
rabbit_ha_queues = True
<% else %>
rabbit_port = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["port"] %>
rabbit_host = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["host"] %>
<% end %>
rabbit_virtual_host = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["vhost"] %>
rpc_backend = ceilometer.openstack.common.rpc.impl_kombu
# Maximum retries with trying to connect to RabbitMQ
# (the default of 0 implies an infinite retry count)
rabbit_max_retries = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["rabbit_max_retries"] %>
# RabbitMQ connection retry interval
rabbit_retry_interval = <%= node["openstack"]["mq"]["telemetry"]["rabbit"]["rabbit_retry_interval"] %>
<% end %>
[publisher_rpc]
metering_secret = <%= @metering_secret %>
<% if node["openstack"]["telemetry"]["hypervisor_inspector"] == 'vsphere'%>
[vmware]
host_ip = <%= node['openstack']['compute']['vmware']['host_ip'] %>
host_username = <%= node['openstack']['compute']['vmware']['host_username'] %>
host_password = <%= @vmware_host_pass %>
task_poll_interval = <%= node['openstack']['compute']['vmware']['task_poll_interval'] %>
api_retry_count = <%= node['openstack']['compute']['vmware']['api_retry_count'] %>
<% if node['openstack']['compute']['vmware']['wsdl_location'] %>
wsdl_location = <%= node['openstack']['compute']['vmware']['wsdl_location'] %>
<% end %>
<% end %>
[service_credentials]
os_region_name = <%= node['openstack']['telemetry']['region'] %>
# A PEM encoded Certificate Authority to use when verifying HTTPs connections. (for service polling authentication)
<% if node['openstack']['telemetry']['service-credentials']['cafile'] %>
os_cacert = <%= node['openstack']['telemetry']['service-credentials']['cafile'] %>
<% end %>
# Verify HTTPS connections. (boolean value, for service polling authentication)
insecure = <%= node['openstack']['telemetry']['service-credentials']['insecure'] %>
[notification]
store_events = <%= node['openstack']['telemetry']['notification']['store_events'] %>