Implement API service & dependencies

This patch rewrite puppet-gnocchi to be compliant with other modules.
It takes example at how puppet-aodh was written.

* Update init.pp to match Gnocchi requirements
* Update config.pp
* Add policy.pp
* Add storage.pp for carbonara
* Update db configuration
* Update keystone/auth.pp
* Add acceptance for API service for Centos only (not packaged on Ubuntu)
* Update unit tests

Change-Id: I82400b1e30f3700ab7a3d006b6bb143351bcc830
changes/11/238811/15
Emilien Macchi 7 years ago
parent cfdcdd2249
commit feee911823
  1. 240
      manifests/api.pp
  2. 6
      manifests/config.pp
  3. 58
      manifests/db.pp
  4. 64
      manifests/db/mysql.pp
  5. 36
      manifests/db/sync.pp
  6. 93
      manifests/generic_service.pp
  7. 99
      manifests/init.pp
  8. 120
      manifests/keystone/auth.pp
  9. 20
      manifests/logging.pp
  10. 22
      manifests/params.pp
  11. 39
      manifests/policy.pp
  12. 33
      manifests/storage.pp
  13. 128
      manifests/wsgi/apache.pp
  14. 115
      spec/acceptance/basic_gnocchi_spec.rb
  15. 192
      spec/classes/gnocchi_api_spec.rb
  16. 103
      spec/classes/gnocchi_db_mysql_spec.rb
  17. 42
      spec/classes/gnocchi_db_spec.rb
  18. 39
      spec/classes/gnocchi_init_spec.rb
  19. 94
      spec/classes/gnocchi_keystone_auth_spec.rb
  20. 5
      spec/classes/gnocchi_logging_spec.rb
  21. 41
      spec/classes/gnocchi_policy_spec.rb
  22. 47
      spec/classes/gnocchi_storage_spec.rb
  23. 124
      spec/classes/gnocchi_wsgi_apache_spec.rb

@ -1,141 +1,151 @@
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# == Class gnocchi::api
#
# Configure API service in gnocchi
# Installs & configure the gnocchi api service
#
# == Parameters
#
# [*manage_service*]
# (optional) Whether to start/stop the service
# [*enabled*]
# (optional) Should the service be enabled.
# Defaults to true
#
# [*ensure_package*]
# (optional) Whether the gnocchi api package will be installed
# Defaults to 'present'
#
# [*keystone_password*]
# (required) Password used to authentication.
#
# [*verbose*]
# (optional) Rather to log the gnocchi api service at verbose level.
# Defaults to undef
#
# [*debug*]
# (optional) Rather to log the gnocchi api service at debug level.
# Defaults to undef
#
# [*log_file*]
# (optional) The path of file used for logging
# If set to boolean false, it will not log to any file.
# Defaults to undef
# [*manage_service*]
# (optional) Whether the service should be managed by Puppet.
# Defaults to true.
#
# [*use_syslog*]
# (Optional) Use syslog for logging.
# Defaults to undef
# [*keystone_user*]
# (optional) The name of the auth user
# Defaults to gnocchi
#
# [*use_stderr*]
# (optional) Use stderr for logging
# Defaults to undef
# [*keystone_tenant*]
# (optional) Tenant to authenticate with.
# Defaults to 'services'.
#
# [*log_facility*]
# (Optional) Syslog facility to receive log lines.
# Defaults to undef
# [*keystone_password*]
# Password to authenticate with.
# Mandatory.
#
# [*log_dir*]
# (optional) directory to which gnocchi logs are sent.
# If set to boolean false, it will not log to any directory.
# Defaults to undef
# [*keystone_auth_uri*]
# (optional) Public Identity API endpoint.
# Defaults to 'false'.
#
# [*keystone_tenant*]
# (optional) Tenant to authenticate to.
# Defaults to services.
# [*keystone_identity_uri*]
# (optional) Complete admin Identity API endpoint.
# Defaults to: false
#
# [*keystone_user*]
# (optional) User to authenticate as with keystone.
# Defaults to 'gnocchi'.
# [*enabled*]
# (optional) Whether to enable services.
# Defaults to true.
# [*host*]
# (optional) The gnocchi api bind address.
# Defaults to 0.0.0.0
#
# [*use_syslog*]
# (optional) Use syslog for logging.
# Defaults to false.
# [*port*]
# (optional) The gnocchi api port.
# Defaults to 8041
#
# [*log_facility*]
# (optional) Syslog facility to receive log lines.
# Defaults to 'LOG_USER'.
# [*workers*]
# (optional) Number of workers for Gnocchi API server.
# Defaults to $::processorcount
#
# [*purge_config*]
# (optional) Whether to set only the specified config options
# in the api config.
# Defaults to false.
# [*max_limit*]
# (optional) The maximum number of items returned in a
# single response from a collection resource.
# Defaults to 1000
#
# [*identity_uri*]
# (optional) Complete admin Identity API endpoint.
# Defaults to 'http://127.0.0.1:35357'.
# [*package_ensure*]
# (optional) ensure state for package.
# Defaults to 'present'
#
class gnocchi::api(
$keystone_password,
$verbose = undef,
$debug = undef,
$use_syslog = undef,
$use_stderr = undef,
$log_facility = undef,
$log_dir = undef,
$log_file = undef,
$keystone_tenant = 'services',
$keystone_user = 'gnocchi',
$identity_uri = 'http://127.0.0.1:35357',
$enabled = true,
$use_syslog = false,
$log_facility = 'LOG_USER',
$purge_config = false,
$manage_service = true,
$ensure_package = 'present',
) inherits gnocchi {
# [*service_name*]
# (optional) Name of the service that will be providing the
# server functionality of gnocchi-api.
# If the value is 'httpd', this means gnocchi-api will be a web
# service, and you must use another class to configure that
# web service. For example, use class { 'gnocchi::wsgi::apache'...}
# to make gnocchi-api be a web app using apache mod_wsgi.
# Defaults to '$::gnocchi::params::api_service_name'
#
class gnocchi::api (
$manage_service = true,
$enabled = true,
$package_ensure = 'present',
$keystone_user = 'gnocchi',
$keystone_tenant = 'services',
$keystone_password = false,
$keystone_auth_uri = false,
$keystone_identity_uri = false,
$host = '0.0.0.0',
$port = '8041',
$workers = $::processorcount,
$max_limit = 1000,
$service_name = $::gnocchi::params::api_service_name,
) inherits gnocchi::params {
require ::keystone::python
include ::gnocchi::logging
include ::gnocchi::db
include ::gnocchi::params
include ::gnocchi::policy
Gnocchi_config<||> ~> Exec['post-gnocchi_config']
Gnocchi_config<||> ~> Service['gnocchi-api']
validate_string($keystone_password)
# basic service config
gnocchi_config {
'keystone_authtoken/identity_uri': value => $identity_uri;
'keystone_authtoken/admin_user': value => $keystone_user;
'keystone_authtoken/admin_password': value => $keystone_password, secret => true;
'keystone_authtoken/admin_tenant_name': value => $keystone_tenant;
Gnocchi_config<||> ~> Service[$service_name]
Class['gnocchi::policy'] ~> Service[$service_name]
Package['gnocchi-api'] -> Service[$service_name]
Package['gnocchi-api'] -> Service['gnocchi-api']
Package['gnocchi-api'] -> Class['gnocchi::policy']
package { 'gnocchi-api':
ensure => $package_ensure,
name => $::gnocchi::params::api_package_name,
tag => ['openstack', 'gnocchi-package'],
}
resources { 'gnocchi_config':
purge => $purge_config,
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
gnocchi::generic_service { 'api':
enabled => $enabled,
manage_service => $manage_service,
ensure_package => $ensure_package,
package_name => $::gnocchi::params::api_package_name,
service_name => $::gnocchi::params::api_service_name,
if $service_name == $::gnocchi::params::api_service_name {
service { 'gnocchi-api':
ensure => $service_ensure,
name => $::gnocchi::params::api_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
require => Class['gnocchi::db'],
tag => ['gnocchi-service', 'gnocchi-db-sync-service'],
}
} elsif $service_name == 'httpd' {
include ::apache::params
service { 'gnocchi-api':
ensure => 'stopped',
name => $::gnocchi::params::api_service_name,
enable => false,
tag => ['gnocchi-service', 'gnocchi-db-sync-service'],
}
Class['gnocchi::db'] -> Service[$service_name]
# we need to make sure gnocchi-api/eventlet is stopped before trying to start apache
Service['gnocchi-api'] -> Service[$service_name]
} else {
fail('Invalid service_name. Either gnocchi/openstack-gnocchi-api for running as a standalone service, or httpd for being run by a httpd server')
}
gnocchi_config {
'keystone_authtoken/auth_uri' : value => $keystone_auth_uri;
'keystone_authtoken/admin_tenant_name' : value => $keystone_tenant;
'keystone_authtoken/admin_user' : value => $keystone_user;
'keystone_authtoken/admin_password' : value => $keystone_password, secret => true;
'api/host' : value => $host;
'api/port' : value => $port;
'api/workers' : value => $workers;
'api/max_limit' : value => $max_limit;
}
if $keystone_identity_uri {
gnocchi_config {
'keystone_authtoken/identity_uri': value => $keystone_identity_uri;
}
} else {
gnocchi_config {
'keystone_authtoken/identity_uri': ensure => absent;
}
}
}

@ -1,11 +1,11 @@
# == Class: gnocchi::config
#
# This class is used to manage arbitrary Gnocchi configurations.
# This class is used to manage arbitrary gnocchi configurations.
#
# === Parameters
#
# [*gnocchi_config*]
# (optional) Allow configuration of arbitrary Gnocchi configurations.
# (optional) Allow configuration of arbitrary gnocchi configurations.
# The value is an hash of gnocchi_config resources. Example:
# { 'DEFAULT/foo' => { value => 'fooValue'},
# 'DEFAULT/bar' => { value => 'barValue'}
@ -21,7 +21,7 @@
# or Puppet catalog compilation will fail with duplicate resources.
#
class gnocchi::config (
$gnocchi_config = {},
$gnocchi_config = {},
) {
validate_hash($gnocchi_config)

@ -8,50 +8,18 @@
# Url used to connect to database.
# (Optional) Defaults to 'sqlite:////var/lib/gnocchi/gnocchi.sqlite'.
#
# [*database_idle_timeout*]
# Timeout when db connections should be reaped.
# (Optional) Defaults to 3600.
#
# [*database_max_retries*]
# Maximum number of database connection retries during startup.
# Setting -1 implies an infinite retry count.
# (Optional) Defaults to 10.
#
# [*database_retry_interval*]
# Interval between retries of opening a database connection.
# (Optional) Defaults to 10.
#
# [*database_min_pool_size*]
# Minimum number of SQL connections to keep open in a pool.
# (Optional) Defaults to 1.
#
# [*database_max_pool_size*]
# Maximum number of SQL connections to keep open in a pool.
# (Optional) Defaults to 10.
#
# [*database_max_overflow*]
# If set, use this value for max_overflow with sqlalchemy.
# (Optional) Defaults to 20.
# [*ensure_package*]
# (optional) The state of gnocchi packages
# Defaults to 'present'
#
class gnocchi::db (
$database_connection = 'sqlite:////var/lib/gnocchi/gnocchi.sqlite',
$database_idle_timeout = 3600,
$database_min_pool_size = 1,
$database_max_pool_size = 10,
$database_max_retries = 10,
$database_retry_interval = 10,
$database_max_overflow = 20,
) {
$database_connection = 'sqlite:////var/lib/gnocchi/gnocchi.sqlite',
$ensure_package = 'present',
) inherits gnocchi::params {
# NOTE(spredzy): In order to keep backward compatibility we rely on the pick function
# to use gnocchi::<myparam> if gnocchi::db::<myparam> isn't specified.
$database_connection_real = pick($::gnocchi::database_connection, $database_connection)
$database_idle_timeout_real = pick($::gnocchi::database_idle_timeout, $database_idle_timeout)
$database_min_pool_size_real = pick($::gnocchi::database_min_pool_size, $database_min_pool_size)
$database_max_pool_size_real = pick($::gnocchi::database_max_pool_size, $database_max_pool_size)
$database_max_retries_real = pick($::gnocchi::database_max_retries, $database_max_retries)
$database_retry_interval_real = pick($::gnocchi::database_retry_interval, $database_retry_interval)
$database_max_overflow_real = pick($::gnocchi::database_max_overflow, $database_max_overflow)
validate_re($database_connection_real,
'(sqlite|mysql|postgresql):\/\/(\S+:\S+@\S+\/\S+)?')
@ -84,13 +52,13 @@ class gnocchi::db (
}
gnocchi_config {
'database/connection': value => $database_connection_real, secret => true;
'database/idle_timeout': value => $database_idle_timeout_real;
'database/min_pool_size': value => $database_min_pool_size_real;
'database/max_retries': value => $database_max_retries_real;
'database/retry_interval': value => $database_retry_interval_real;
'database/max_pool_size': value => $database_max_pool_size_real;
'database/max_overflow': value => $database_max_overflow_real;
'indexer/url': value => $database_connection_real, secret => true;
}
package { 'gnocchi-indexer-sqlalchemy':
ensure => $ensure_package,
name => $::gnocchi::params::indexer_package_name,
tag => ['openstack', 'gnocchi-package'],
}
}

@ -1,62 +1,56 @@
# The gnocchi::db::mysql class implements mysql backend for gnocchi
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
# This class can be used to create tables, users and grant
# privelege for a mysql gnocchi database.
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# == Class: gnocchi::db::mysql
#
# The gnocchi::db::mysql class creates a MySQL database for gnocchi.
# It must be used on the MySQL server
#
# === Parameters
# == parameters
#
# [*password*]
# (required) Password that will be used for the gnocchi db user.
# (Mandatory) Password to connect to the database.
# Defaults to 'false'.
#
# [*dbname*]
# (optional) Name of gnocchi database.
# Defaults to gnocchi
# (Optional) Name of the database.
# Defaults to 'gnocchi'.
#
# [*user*]
# (optional) Name of gnocchi user.
# Defaults to gnocchi
# (Optional) User to connect to the database.
# Defaults to 'gnocchi'.
#
# [*host*]
# (optional) Host where user should be allowed all privileges for database.
# Defaults to 127.0.0.1
# (Optional) The default source host user is allowed to connect from.
# Defaults to '127.0.0.1'
#
# [*allowed_hosts*]
# (optional) Hosts allowed to use the database
# Defaults to undef.
# (Optional) Other hosts the user is allowed to connect from.
# Defaults to 'undef'.
#
# [*charset*]
# (optional) Charset of gnocchi database
# Defaults 'utf8'.
# (Optional) The database charset.
# Defaults to 'utf8'
#
# [*collate*]
# (optional) Charset collate of gnocchi database
# Defaults 'utf8_general_ci'.
# (Optional) The database collate.
# Only used with mysql modules >= 2.2.
# Defaults to 'utf8_general_ci'
#
# == Dependencies
# Class['mysql::server']
#
# == Examples
#
# == Authors
#
# == Copyright
#
class gnocchi::db::mysql(
$password,
$dbname = 'gnocchi',
$user = 'gnocchi',
$host = '127.0.0.1',
$allowed_hosts = undef,
$charset = 'utf8',
$collate = 'utf8_general_ci',
$allowed_hosts = undef
) {
validate_string($password)

@ -1,27 +1,23 @@
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# Class to execute "gnocchi-dbsync"
#
class gnocchi::db::sync {
exec { 'gnocchi-dbsync':
# [*user*]
# (optional) User to run dbsync command.
# Defaults to 'gnocchi'
#
class gnocchi::db::sync (
$user = 'gnocchi',
){
exec { 'gnocchi-db-sync':
command => 'gnocchi-dbsync --config-file /etc/gnocchi/gnocchi.conf',
path => '/usr/bin',
user => 'gnocchi',
refreshonly => true,
subscribe => [Package['gnocchi-api'], Gnocchi_config['database/connection']],
user => $user,
logoutput => on_failure,
}
Package<| tag == 'gnocchi-package' |> ~> Exec['gnocchi-db-sync']
Exec['gnocchi-db-sync'] ~> Service<| tag == 'gnocchi-db-sync-service' |>
Gnocchi_config<||> ~> Exec['gnocchi-db-sync']
Gnocchi_config<| title == 'indexer/url' |> ~> Exec['gnocchi-db-sync']
}

@ -1,93 +0,0 @@
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# == Define: gnocchi::generic_service
#
# This defined type implements basic gnocchi services.
# It is introduced to attempt to consolidate
# common code.
#
# It also allows users to specify ad-hoc services
# as needed
#
# This define creates a service resource with title gnocchi-${name} and
# conditionally creates a package resource with title gnocchi-${name}
#
# === Parameters:
#
# [*package_name*]
# (mandatory) The package name (for the generic_service)
#
# [*service_name*]
# (mandatory) The service name (for the generic_service)
#
# [*enabled*]
# (optional) Define if the service must be enabled or not
# Defaults to false.
#
# [*manage_service*]
# (optional) Manage or not the service (if a service_name is provided).
# Defaults to true.
#
# [*ensure_package*]
# (optional) Control the ensure parameter for the package ressource.
# Defaults to 'present'.
#
define gnocchi::generic_service(
$package_name,
$service_name,
$enabled = false,
$manage_service = true,
$ensure_package = 'present'
) {
include ::gnocchi::params
include ::gnocchi::db::sync
$gnocchi_title = "gnocchi-${name}"
Exec['post-gnocchi_config'] ~> Service<| title == $gnocchi_title |>
Exec<| title == 'gnocchi-dbsync' |> ~> Service<| title == $gnocchi_title |>
if ($package_name) {
if !defined(Package[$package_name]) {
package { $gnocchi_title:
ensure => $ensure_package,
name => $package_name,
notify => Service[$gnocchi_title],
tag => ['openstack', 'gnocchi-package'],
}
}
}
if $service_name {
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { $gnocchi_title:
ensure => $service_ensure,
name => $service_name,
enable => $enabled,
hasstatus => true,
tag => 'gnocchi-service',
}
}
}

@ -1,69 +1,68 @@
# == Class: gnocchi
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
# Full description of class gnocchi here.
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
# === Parameters
#
# 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
# [*ensure_package*]
# (optional) The state of gnocchi packages
# Defaults to 'present'
#
# 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.
# gnocchi::init
# [*log_dir*]
# (optional) Directory where logs should be stored.
# If set to boolean false, it will not log to any directory.
# Defaults to undef
#
# Gnocchi base config
# [*state_path*]
# (optional) Directory for storing state.
# Defaults to '/var/lib/gnocchi'
#
# == Parameters
# [*lock_path*]
# (optional) Directory for lock files.
# On RHEL will be '/var/lib/gnocchi/tmp' and on Debian '/var/lock/gnocchi'
# Defaults to $::gnocchi::params::lock_path
#
# [*database_connection*]
# (optional) Connection url to connect to gnocchi database.
# [*verbose*]
# (optional) Set log output to verbose output.
# Defaults to undef
#
# [*database_idle_timeout*]
# (optional) Timeout before idle db connections are reaped.
# [*debug*]
# (optional) Set log output to debug output.
# Defaults to undef
#
# [*database_max_retries*]
# (optional) Maximum number of database connection retries during startup.
# Setting -1 implies an infinite retry count.
# (Defaults to undef)
#
# [*database_retry_interval*]
# (optional) Interval between retries of opening a database connection.
# (Defaults to undef)
# [*use_syslog*]
# (optional) Use syslog for logging
# Defaults to undef
#
# [*database_min_pool_size*]
# (optional) Minimum number of SQL connections to keep open in a pool.
# Defaults to: undef
# [*use_stderr*]
# (optional) Use stderr for logging
# Defaults to undef
#
# [*database_max_pool_size*]
# (optional) Maximum number of SQL connections to keep open in a pool.
# Defaults to: undef
# [*log_facility*]
# (optional) Syslog facility to receive log lines.
# Defaults to undef
#
# [*database_max_overflow*]
# (optional) If set, use this value for max_overflow with sqlalchemy.
# Defaults to: undef
# [*database_connection*]
# (optional) Connection url for the gnocchi database.
# Defaults to undef.
#
class gnocchi(
$database_connection = undef,
$database_idle_timeout = undef,
$database_max_retries = undef,
$database_retry_interval = undef,
$database_min_pool_size = undef,
$database_max_pool_size = undef,
$database_max_overflow = undef,
) {
include ::gnocchi::params
class gnocchi (
$ensure_package = 'present',
$verbose = undef,
$debug = undef,
$use_syslog = undef,
$use_stderr = undef,
$log_facility = undef,
$database_connection = undef,
) inherits gnocchi::params {
include ::gnocchi::db
include ::gnocchi::logging
exec { 'post-gnocchi_config':
command => '/bin/echo "Gnocchi config has changed"',
refreshonly => true,
package { 'gnocchi':
ensure => $ensure_package,
name => $::gnocchi::params::common_package_name,
tag => ['openstack', 'gnocchi-package'],
}
}

@ -1,86 +1,53 @@
#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# gnocchi::keystone::auth
# == Class: gnocchi::keystone::auth
#
# Configures Gnocchi user, service and endpoint in Keystone.
#
# === Parameters
#
# [*password*]
# (required) Password for Gnocchi user.
# (required) Password for gnocchi user.
#
# [*auth_name*]
# Username for Gnocchi service. Defaults to 'gnocchi'.
# Username for gnocchi service. Defaults to 'gnocchi'.
#
# [*email*]
# Email for Gnocchi user. Defaults to 'gnocchi@localhost'.
# Email for gnocchi user. Defaults to 'gnocchi@localhost'.
#
# [*tenant*]
# Tenant for Gnocchi user. Defaults to 'services'.
# Tenant for gnocchi user. Defaults to 'services'.
#
# [*configure_endpoint*]
# Should Gnocchi endpoint be configured? Defaults to 'true'.
# Should gnocchi endpoint be configured? Defaults to 'true'.
#
# [*configure_user*]
# Should Gnocchi user be configured? Defaults to 'true'.
# (Optional) Should the service user be configured?
# Defaults to 'true'.
#
# [*configure_user_role*]
# Should Gnocchi user/role association be configured? Defaults to 'true'.
# (Optional) Should the admin role be configured for the service user?
# Defaults to 'true'.
#
# [*service_type*]
# Type of service. Defaults to 'gnocchi'.
#
# [*service_description*]
# Description for keystone service. Optional. Defaults to 'OpenStack Datapoint Service'.
#
# [*public_protocol*]
# Protocol for public endpoint. Defaults to 'http'.
#
# [*public_address*]
# Public address for endpoint. Defaults to '127.0.0.1'.
# Type of service. Defaults to 'key-manager'.
#
# [*public_port*]
# Port for public endpoint.
# Defaults to '8041'.
#
# [*admin_protocol*]
# Protocol for admin endpoint. Defaults to 'http'.
#
# [*admin_address*]
# Admin address for endpoint. Defaults to '127.0.0.1'.
#
# [*admin_port*]
# Port for admin endpoint.
# Defaults to '8041'.
#
# [*internal_protocol*]
# Protocol for internal endpoint. Defaults to 'http'.
# [*region*]
# Region for endpoint. Defaults to 'RegionOne'.
#
# [*internal_address*]
# Internal address for endpoint. Defaults to '127.0.0.1'.
# [*service_name*]
# (optional) Name of the service.
# Defaults to the value of auth_name.
#
# [*internal_port*]
# Port for internal endpoint.
# Defaults to '8041'.
# [*public_url*]
# (optional) The endpoint's public url. (Defaults to 'http://127.0.0.1:8041')
# This url should *not* contain any trailing '/'.
#
# [*region*]
# Region for endpoint. Defaults to 'RegionOne'.
# [*admin_url*]
# (optional) The endpoint's admin url. (Defaults to 'http://127.0.0.1:8041')
# This url should *not* contain any trailing '/'.
#
# [*internal_url*]
# (optional) The endpoint's internal url. (Defaults to 'http://127.0.0.1:8041')
# This url should *not* contain any trailing '/'.
#
class gnocchi::keystone::auth (
$password,
@ -90,36 +57,31 @@ class gnocchi::keystone::auth (
$configure_endpoint = true,
$configure_user = true,
$configure_user_role = true,
$service_type = 'gnocchi',
$service_description = 'OpenStack Datapoint Service',
$public_protocol = 'http',
$public_address = '127.0.0.1',
$public_port = '8041',
$admin_protocol = 'http',
$admin_address = '127.0.0.1',
$admin_port = '8041',
$internal_protocol = 'http',
$internal_address = '127.0.0.1',
$internal_port = '8041',
$region = 'RegionOne'
$service_name = undef,
$service_type = 'metric',
$region = 'RegionOne',
$public_url = 'http://127.0.0.1:8041',
$internal_url = 'http://127.0.0.1:8041',
$admin_url = 'http://127.0.0.1:8041',
) {
Keystone_user_role["${auth_name}@${tenant}"] ~> Service <| name == 'gnocchi-api' |>
Keystone_endpoint["${region}/${auth_name}"] ~> Service <| name == 'gnocchi-api' |>
$real_service_name = pick($service_name, $auth_name)
keystone::resource::service_identity { $auth_name:
configure_user => true,
configure_user_role => true,
keystone::resource::service_identity { 'gnocchi':
configure_user => $configure_user,
configure_user_role => $configure_user_role,
configure_endpoint => $configure_endpoint,
service_name => $real_service_name,
service_type => $service_type,
service_description => $service_description,
service_description => 'OpenStack Metric Service',
region => $region,
auth_name => $auth_name,
password => $password,
email => $email,
tenant => $tenant,
public_url => "${public_protocol}://${public_address}:${public_port}",
internal_url => "${internal_protocol}://${internal_address}:${internal_port}",
admin_url => "${admin_protocol}://${admin_address}:${admin_port}",
public_url => $public_url,
internal_url => $internal_url,
admin_url => $admin_url,
}
}

@ -29,11 +29,6 @@
# If set to boolean false, it will not log to any directory.
# Defaults to '/var/log/gnocchi'
#
# [*log_file*]
# (optional) The path of file used for logging
# If set to boolean false, it will not log to any file.
# Default to '/var/log/gnocchi-api.log'
#
# [*logging_context_format_string*]
# (optional) Format string to use for log messages with context.
# Defaults to undef.
@ -100,7 +95,6 @@ class gnocchi::logging(
$use_stderr = true,
$log_facility = 'LOG_USER',
$log_dir = '/var/log/gnocchi',
$log_file = '/var/log/gnocchi/gnocchi-api.log',
$verbose = false,
$debug = false,
$logging_context_format_string = undef,
@ -118,13 +112,12 @@ class gnocchi::logging(
# NOTE(spredzy): In order to keep backward compatibility we rely on the pick function
# to use gnocchi::<myparam> first then gnocchi::logging::<myparam>.
$use_syslog_real = pick($::gnocchi::api::use_syslog,$use_syslog)
$use_stderr_real = pick($::gnocchi::api::use_stderr,$use_stderr)
$log_facility_real = pick($::gnocchi::api::log_facility,$log_facility)
$log_dir_real = pick($::gnocchi::api::log_dir,$log_dir)
$log_file_real = pick($::gnocchi::api::log_file,$log_file)
$verbose_real = pick($::gnocchi::api::verbose,$verbose)
$debug_real = pick($::gnocchi::api::debug,$debug)
$use_syslog_real = pick($::gnocchi::use_syslog,$use_syslog)
$use_stderr_real = pick($::gnocchi::use_stderr,$use_stderr)
$log_facility_real = pick($::gnocchi::log_facility,$log_facility)
$log_dir_real = pick($::gnocchi::log_dir,$log_dir)
$verbose_real = pick($::gnocchi::verbose,$verbose)
$debug_real = pick($::gnocchi::debug,$debug)
gnocchi_config {
'DEFAULT/debug' : value => $debug_real;
@ -132,7 +125,6 @@ class gnocchi::logging(
'DEFAULT/use_stderr' : value => $use_stderr_real;
'DEFAULT/use_syslog' : value => $use_syslog_real;
'DEFAULT/log_dir' : value => $log_dir_real;
'DEFAULT/log_file' : value => $log_file_real;
'DEFAULT/syslog_log_facility': value => $log_facility_real;
}

@ -4,14 +4,24 @@ class gnocchi::params {
case $::osfamily {
'RedHat': {
$api_package_name = 'openstack-gnocchi-api'
$api_service_name = 'openstack-gnocchi-api'
$sqlite_package_name = undef
$sqlite_package_name = undef
$common_package_name = 'openstack-gnocchi-common'
$api_package_name = 'openstack-gnocchi-api'
$api_service_name = 'openstack-gnocchi-api'
$indexer_package_name = 'openstack-gnocchi-indexer-sqlalchemy'
$carbonara_package_name = 'openstack-gnocchi-carbonara'
$gnocchi_wsgi_script_path = '/var/www/cgi-bin/gnocchi'
$gnocchi_wsgi_script_source = '/usr/lib/python2.7/site-packages/gnocchi/rest/app.wsgi'
}
'Debian': {
$api_package_name = 'gnocchi-api'
$api_service_name = 'gnocchi-api'
$sqlite_package_name = 'python-pysqlite2'
$sqlite_package_name = 'python-pysqlite2'
$common_package_name = 'gnocchi-common'
$api_package_name = 'gnocchi-api'
$api_service_name = 'gnocchi-api'
$indexer_package_name = 'gnocchi-indexer-sqlalchemy'
$carbonara_package_name = 'gnocchi-carbonara'
$gnocchi_wsgi_script_path = '/usr/lib/cgi-bin/gnocchi'
$gnocchi_wsgi_script_source = '/usr/share/gnocchi-common/app.wsgi'
}
default: {
fail("Unsupported osfamily: ${::osfamily} operatingsystem")

@ -0,0 +1,39 @@
# == Class: gnocchi::policy
#
# Configure the gnocchi policies
#
# === Parameters
#
# [*policies*]
# (optional) Set of policies to configure for gnocchi
# Example :
# {
# 'gnocchi-context_is_admin' => {
# 'key' => 'context_is_admin',
# 'value' => 'true'
# },
# 'gnocchi-default' => {
# 'key' => 'default',
# 'value' => 'rule:admin_or_owner'
# }
# }
# Defaults to empty hash.
#
# [*policy_path*]
# (optional) Path to the nova policy.json file
# Defaults to /etc/gnocchi/policy.json
#
class gnocchi::policy (
$policies = {},
$policy_path = '/etc/gnocchi/policy.json',
) {
validate_hash($policies)
Openstacklib::Policy::Base {
file_path => $policy_path,
}
create_resources('openstacklib::policy::base', $policies)
}

@ -0,0 +1,33 @@
# 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.
# gnocchi::storage
#
# Storage backend for Gnocchi
#
# == Parameters
#
# [*package_ensure*]
# (optional) ensure state for package.
# Defaults to 'present'
#
class gnocchi::storage(
$package_ensure = 'present',
) inherits gnocchi::params {
package { 'gnocchi-carbonara':
ensure => $package_ensure,
name => $::gnocchi::params::carbonara_package_name,
tag => ['openstack', 'gnocchi-package'],
}
}

@ -0,0 +1,128 @@
#
# Copyright (C) 2015 eNovance SAS <licensing@enovance.com>
#
# Author: Emilien Macchi <emilien.macchi@enovance.com>
#
# 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.
#
# Class to serve gnocchi API with apache mod_wsgi in place of gnocchi-api service.
#
# Serving gnocchi API from apache is the recommended way to go for production
# because of limited performance for concurrent accesses when running eventlet.
#
# When using this class you should disable your gnocchi-api service.
#
# == Parameters
#
# [*servername*]
# The servername for the virtualhost.
# Optional. Defaults to $::fqdn
#
# [*port*]
# The port.
# Optional. Defaults to 8041
#
# [*bind_host*]
# The host/ip address Apache will listen on.
# Optional. Defaults to undef (listen on all ip addresses).
#
# [*path*]
# The prefix for the endpoint.
# Optional. Defaults to '/'
#
# [*ssl*]
# Use ssl ? (boolean)
# Optional. Defaults to true
#
# [*workers*]
# Number of WSGI workers to spawn.
# Optional. Defaults to 1
#
# [*priority*]
# (optional) The priority for the vhost.
# Defaults to '10'
#
# [*threads*]
# (optional) The number of threads for the vhost.
# Defaults to $::processorcount
#
# [*ssl_cert*]
# [*ssl_key*]
# [*ssl_chain*]
# [*ssl_ca*]
# [*ssl_crl_path*]
# [*ssl_crl*]
# [*ssl_certs_dir*]
# apache::vhost ssl parameters.
# Optional. Default to apache::vhost 'ssl_*' defaults.
#
# == Dependencies
#
# requires Class['apache'] & Class['gnocchi']
#
# == Examples
#
# include apache
#
# class { 'gnocchi::wsgi::apache': }
#
class gnocchi::wsgi::apache (
$servername = $::fqdn,
$port = 8041,
$bind_host = undef,
$path = '/',
$ssl = true,
$workers = 1,
$ssl_cert = undef,
$ssl_key = undef,
$ssl_chain = undef,
$ssl_ca = undef,
$ssl_crl_path = undef,
$ssl_crl = undef,
$ssl_certs_dir = undef,
$threads = $::processorcount,
$priority = '10',
) {
include ::gnocchi::params
include ::apache
include ::apache::mod::wsgi
if $ssl {
include ::apache::mod::ssl
}
::openstacklib::wsgi::apache { 'gnocchi_wsgi':
bind_host => $bind_host,
bind_port => $port,
group => 'gnocchi',
path => $path,
priority => $priority,
servername => $servername,
ssl => $ssl,
ssl_ca => $ssl_ca,
ssl_cert => $ssl_cert,
ssl_certs_dir => $ssl_certs_dir,
ssl_chain => $ssl_chain,
ssl_crl => $ssl_crl,
ssl_crl_path => $ssl_crl_path,
ssl_key => $ssl_key,
threads => $threads,
user => 'gnocchi',
workers => $workers,
wsgi_daemon_process => 'gnocchi',
wsgi_process_group => 'gnocchi',
wsgi_script_dir => $::gnocchi::params::gnocchi_wsgi_script_path,
wsgi_script_file => 'app',
wsgi_script_source => $::gnocchi::params::gnocchi_wsgi_script_source,
}
}

@ -1 +1,116 @@
require 'spec_helper_acceptance'
describe 'basic gnocchi' do
context 'default parameters' do
it 'should work with no errors' do
pp= <<-EOS
Exec { logoutput => 'on_failure' }
# Common resources
case $::osfamily {
'Debian': {
include ::apt
class { '::openstack_extras::repo::debian::ubuntu':
release => 'liberty',
repo => 'proposed',
package_require => true,
}
}
'RedHat': {
class { '::openstack_extras::repo::redhat::redhat':
manage_rdo => false,
repo_hash => {
'openstack-common-testing' => {
'baseurl' => 'http://cbs.centos.org/repos/cloud7-openstack-common-testing/x86_64/os/',
'descr' => 'openstack-common-testing',
'gpgcheck' => 'no',
},
'openstack-liberty-testing' => {
'baseurl' => 'http://cbs.centos.org/repos/cloud7-openstack-liberty-testing/x86_64/os/',
'descr' => 'openstack-liberty-testing',
'gpgcheck' => 'no',
},
'openstack-liberty-trunk' => {
'baseurl' => 'http://trunk.rdoproject.org/centos7-liberty/current-passed-ci/',
'descr' => 'openstack-liberty-trunk',
'gpgcheck' => 'no',
},
},
}
package { 'openstack-selinux': ensure => 'latest' }
}
default: {
fail("Unsupported osfamily (${::osfamily})")
}
}
class { '::mysql::server': }
# Keystone resources, needed by Gnocchi to run
class { '::keystone::db::mysql':
password => 'keystone',
}
class { '::keystone':
verbose => true,
debug => true,
database_connection => 'mysql://keystone:keystone@127.0.0.1/keystone',
admin_token => 'admin_token',
enabled => true,
}
class { '::keystone::roles::admin':
email => 'test@example.tld',
password => 'a_big_secret',
}
class { '::keystone::endpoint':
public_url => "https://${::fqdn}:5000/",
admin_url => "https://${::fqdn}:35357/",
}
class { '::gnocchi::db::mysql':
password => 'a_big_secret',
}
class { '::gnocchi::keystone::auth':
password => 'a_big_secret',
}
case $::osfamily {
'Debian': {
warning('Gnocchi is not yet packaged on Ubuntu systems.')
}
'RedHat': {
class { '::gnocchi':
verbose => true,
debug => true,
database_connection => 'mysql://gnocchi:a_big_secret@127.0.0.1/gnocchi?charset=utf8',
}
class { '::gnocchi::api':
enabled => true,
keystone_password => 'a_big_secret',
keystone_identity_uri => 'http://127.0.0.1:35357/',
service_name => 'httpd',
}
class { '::gnocchi::db::sync': }
class { '::gnocchi::storage': }
class { '::gnocchi::storage::file': }
include ::apache
class { '::gnocchi::wsgi::apache':
ssl => false,
}
}
}
EOS
# Run it twice and test for idempotency
apply_manifest(pp, :catch_failures => true)
apply_manifest(pp, :catch_changes => true)
end
if os[:family].casecmp('RedHat') == 0
describe port(8041) do
it { is_expected.to be_listening }
end
end
end
end

@ -1,56 +1,137 @@
#
# Unit tests for gnocchi::api
#
require 'spec_helper'
describe 'gnocchi::api' do
let :pre_condition do
"class { 'gnocchi': }
include ::gnocchi::db"
end
let :params do
{ :keystone_password => 'passw0rd',
:keystone_user => 'gnocchi',
:identity_uri => 'https://identity.os.net:5000',
:keystone_tenant => '_services_',
{ :enabled => true,
:manage_service => true,
:keystone_password => 'gnocchi-passw0rd',
:keystone_tenant => 'services',
:keystone_user => 'gnocchi',
:package_ensure => 'latest',
:port => '8041',
:max_limit => '1000',
:host => '0.0.0.0',
}
end
shared_examples 'gnocchi-api' do
shared_examples_for 'gnocchi-api' do
context 'without required parameter keystone_password' do
before { params.delete(:keystone_password) }
it { expect { is_expected.to raise_error(Puppet::Error) } }
end
it { is_expected.to contain_class('gnocchi::params') }
it { is_expected.to contain_class('gnocchi::policy') }
context 'with default parameters' do
it 'installs gnocchi-api package' do
is_expected.to contain_package('gnocchi-api').with(
:ensure => 'latest',
:name => platform_params[:api_package_name],
:tag => ['openstack', 'gnocchi-package'],
)
end
it 'contains the logging class' do
is_expected.to contain_class('gnocchi::logging')
it 'configures keystone authentication middleware' do
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_tenant_name').with_value( params[:keystone_tenant] )
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_user').with_value( params[:keystone_user] )
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_password').with_value( params[:keystone_password] )
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_password').with_value( params[:keystone_password] ).with_secret(true)
is_expected.to contain_gnocchi_config('api/host').with_value( params[:host] )
is_expected.to contain_gnocchi_config('api/port').with_value( params[:port] )
is_expected.to contain_gnocchi_config('api/max_limit').with_value( params[:max_limit] )
is_expected.to contain_gnocchi_config('api/workers').with_value('2')
end
[{:enabled => true}, {:enabled => false}].each do |param_hash|
context "when service should be #{param_hash[:enabled] ? 'enabled' : 'disabled'}" do
before do
params.merge!(param_hash)
end
it 'configures gnocchi-api service' do
is_expected.to contain_service('gnocchi-api').with(
:ensure => (params[:manage_service] && params[:enabled]) ? 'running' : 'stopped',
:name => platform_params[:api_service_name],
:enable => params[:enabled],
:hasstatus => true,
:hasrestart => true,
:require => 'Class[Gnocchi::Db]',
:tag => ['gnocchi-service', 'gnocchi-db-sync-service'],
)
end
end
end
it 'installs gnocchi-api package and service' do
context 'with disabled service managing' do
before do
params.merge!({
:manage_service => false,
:enabled => false })
end
it 'configures gnocchi-api service' do
is_expected.to contain_service('gnocchi-api').with(
:name => platform_params[:api_service_name],
:ensure => 'running',
:hasstatus => true,
:enable => true
:ensure => nil,
:name => platform_params[:api_service_name],
:enable => false,
:hasstatus => true,
:hasrestart => true,
:tag => ['gnocchi-service', 'gnocchi-db-sync-service'],
)
is_expected.to contain_package('gnocchi-api').with(
:name => platform_params[:api_package_name],
:ensure => 'present',
:notify => 'Service[gnocchi-api]'
end
end
context 'when running gnocchi-api in wsgi' do
before do
params.merge!({ :service_name => 'httpd' })
end
let :pre_condition do
"include ::apache
include ::gnocchi::db
class { 'gnocchi': }"
end
it 'configures gnocchi-api service with Apache' do
is_expected.to contain_service('gnocchi-api').with(
:ensure => 'stopped',
:name => platform_params[:api_service_name],
:enable => false,
:tag => ['gnocchi-service', 'gnocchi-db-sync-service'],
)
end
end
it 'configures gnocchi-api with default parameters' do
is_expected.to contain_gnocchi_config('keystone_authtoken/identity_uri').with_value(params[:identity_uri])
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_tenant_name').with_value(params[:keystone_tenant])
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_user').with_value(params[:keystone_user])
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_password').with_value(params[:keystone_password])
is_expected.to contain_gnocchi_config('keystone_authtoken/admin_password').with_value(params[:keystone_password]).with_secret(true)
context 'when service_name is not valid' do
before do
params.merge!({ :service_name => 'foobar' })
end
let :pre_condition do
"include ::apache
include ::gnocchi::db
class { 'gnocchi': }"
end
it_raises 'a Puppet::Error', /Invalid service_name/
end
end
context 'on Debian platforms' do
let :facts do
{
:osfamily => 'Debian'
}
{ :osfamily => 'Debian',
:operatingsystem => 'Debian',
:operatingsystemrelease => '8.0',
:concat_basedir => '/var/lib/puppet/concat',
:fqdn => 'some.host.tld',
:processorcount => 2 }
end
let :platform_params do
@ -63,9 +144,12 @@ describe 'gnocchi::api' do
context 'on RedHat platforms' do