Initial commit for puppet-ec2api

Change-Id: Ied75d3c234eae5533bd6393b4ca2259fbaefa9e4
This commit is contained in:
Marcos Fermin Lobo 2016-02-04 10:04:48 +01:00
parent ae25d3d74c
commit d3820a64f1
30 changed files with 1889 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
pkg/
Gemfile.lock
vendor/
spec/fixtures/
.vagrant/
.bundle/
coverage/
.idea/
*.swp
*.iml
openstack/

40
Gemfile Normal file
View File

@ -0,0 +1,40 @@
source ENV['GEM_SOURCE'] || "https://rubygems.org"
group :development, :test do
gem 'puppetlabs_spec_helper', :require => 'false'
gem 'rspec-puppet', '~> 2.2.0', :require => 'false'
gem 'rspec-puppet-facts', :require => 'false'
gem 'metadata-json-lint', :require => 'false'
gem 'puppet-lint-param-docs', :require => 'false'
gem 'puppet-lint-absolute_classname-check', :require => 'false'
gem 'puppet-lint-absolute_template_path', :require => 'false'
gem 'puppet-lint-trailing_newline-check', :require => 'false'
gem 'puppet-lint-unquoted_string-check', :require => 'false'
gem 'puppet-lint-leading_zero-check', :require => 'false'
gem 'puppet-lint-variable_contains_upcase', :require => 'false'
gem 'puppet-lint-numericvariable', :require => 'false'
gem 'json', :require => 'false'
gem 'puppet-openstack_spec_helper',
:git => 'https://git.openstack.org/openstack/puppet-openstack_spec_helper',
:require => false
end
group :system_tests do
gem 'beaker-rspec', :require => 'false'
gem 'beaker-puppet_install_helper', :require => 'false'
gem 'r10k', :require => 'false'
end
if facterversion = ENV['FACTER_GEM_VERSION']
gem 'facter', facterversion, :require => false
else
gem 'facter', :require => false
end
if puppetversion = ENV['PUPPET_GEM_VERSION']
gem 'puppet', puppetversion, :require => false
else
gem 'puppet', :require => false
end
# vim:ft=ruby

13
LICENSE Normal file
View File

@ -0,0 +1,13 @@
Copyright 2015 OpenStack Foundation
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.

33
README.md Normal file
View File

@ -0,0 +1,33 @@
ec2api
=======
#### Table of Contents
1. [Overview - What is the ec2api module?](#overview)
2. [Module Description - What does the module do?](#module-description)
3. [Development - Guide for contributing to the module](#development)
4. [Contributors](#contributors)
Overview
--------
The puppet-ec2api is the puppet module for module [OpenStack EC2 API](https://github.com/openstack/ec2-api) project.
Please note that this is WIP and this puppet module is not ready for production environments yet.
Module Description
------------------
The ec2api module is a thorough attempt to make Puppet capable of managing the entirety of OpenStack EC2 API project. This includes manifests to provision region specific endpoint and database connections. Types are shipped as part of the ec2api module to assist in manipulation of configuration files.
Development
-----------
Developer documentation for the entire puppet-openstack project.
* https://wiki.openstack.org/wiki/Puppet#Developer_documentation
Contributors
------------
* https://github.com/openstack/puppet-ec2api/graphs/contributors

1
Rakefile Normal file
View File

@ -0,0 +1 @@
require 'puppet-openstack_spec_helper/rake_tasks'

View File

@ -0,0 +1,27 @@
Puppet::Type.type(:ec2api_api_paste_ini).provide(
:ini_setting,
:parent => Puppet::Type.type(:ini_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def self.file_path
'/etc/ec2api/api-paste.ini'
end
# added for backwards compatibility with older versions of inifile
def file_path
self.class.file_path
end
end

View File

@ -0,0 +1,22 @@
Puppet::Type.type(:ec2api_config).provide(
:ini_setting,
:parent => Puppet::Type.type(:ni_setting).provider(:ruby)
) do
def section
resource[:name].split('/', 2).first
end
def setting
resource[:name].split('/', 2).last
end
def separator
'='
end
def self.file_path
'/etc/ec2api/ec2api.conf'
end
end

View File

@ -0,0 +1,9 @@
Puppet::Type.newtype(:ec2api_api_paste_ini) do
ensurable
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from /etc/ec2api/api-paste.ini'
newvalues(/\S+\/\S+/)
end
end

View File

@ -0,0 +1,12 @@
Puppet::Type.newtype(:ec2api_config) do
ensurable do
defaultvalues
defaultto :present
end
newparam(:name, :namevar => true) do
desc 'Section/setting name to manage from ec2api.conf'
newvalues(/\S+\/\S+/)
end
end

605
manifests/api.pp Normal file
View File

@ -0,0 +1,605 @@
# == Class: ec2api::api
#
# EC2 API class to configure the API service via puppet.
#
# === Parameters
#
# [*manage_service*]
# Grant to manage enable/disable services. Defaults to true
#
# [*enabled*]
# Enable/disable the services. Defaults to true
#
# [*debug*]
# Print debugging output (set logging level to DEBUG instead of default
# WARNING level). Defaults to false
#
# [*verbose*]
# Print more verbose output (set logging level to INFO instead of default
# WARNING level). Defaults to false
#
# [*admin_user*]
# The user does not need admin credentials into the project
# Admin use. Defaults to undef
#
# [*admin_password*]
# Admin password. Defaults to undef
#
# [*admin_tenant_name*]
# Admin tenant name. Defaults to undef
#
# [*fatal_exception_format_errors*]
# Make exception message format errors fatal. Defaults false
#
# [*ec2api_listen*]
# The IP address on which the EC2 API will listen. Default '0.0.0.0'
#
# [*ec2api_listen_port*]
# The port on which the EC2 API will listen. Default 8788
#
# [*ec2api_use_ssl*]
# Enable ssl connections or not for EC2 API. Default false
#
# [*ec2api_workers*]
# Number of workers for EC2 API service. The default will be equal to the
# number of CPUs available. Default undef
#
# [*metadata_listen*]
# The IP address on which the metadata API will listen. Default '0.0.0.0'
#
# [*metadata_listen_port*]
# The port on which the metadata API will listen. Default 8789
#
# [*metadata_use_ssl*]
# Enable ssl connections or not for EC2 API Metadata. Default false
#
# [*metadata_workers*]
# Number of workers for metadata service. The default will be the number of
# CPUs available. Default undef
#
# [*service_down_time*]
# Maximum time since last check-in for up service. Default 60
#
# [*api_paste_config*]
# File name for the paste.deploy config for ec2api (string
# value). Defaults to 'api-paste.ini'
#
# [*log_dir*]
# Directory to save the logs. Defaults '/var/log/ec2api'
#
# [*use_ssl*]
# Server will work under SSL. Defaults false
#
# [*wsgi_ssl_ca_file*]
# (optional) CA certificate file to use to verify connecting clients
# Defaults to false, not set
#
# [*wsgi_ssl_cert_file*]
# (optinal) Certificate file to use when starting API server securely
# Defaults to false, not set
#
# [*wsgi_ssl_key_file*]
# (optional) Private key file to use when starting API server securely
# Defaults to false, not set
#
# [*database_use_tpool*]
# (optional) Use of thread pooling for all DB API calls.
# Defaults to false
#
# [*keystone_url*]
# URL to get token from ec2 request. (string value).
# Defaults to 'http://localhost:5000/v2.0'#
#
# [*keystone_ec2_tokens_url*]
# URL to get token from ec2 request.(string value).
# Defaults to '$keystone_url/ec2tokens'
#
# [*ec2_timestamp_expiry*]
# Time in seconds before ec2 timestamp expires
# Defaults 300
#
# [*api_rate_limit*]
# Whether to use per-user rate limiting for the api.
# Defaults false, not set
#
# [*use_forwarded_for*]
# Treat X-Forwarded-For as the canonical remote address. Only enable this if
# you have a sanitizing proxy.
# Defaults false, not set
#
# [*internal_service_availability_zone*]
# The availability_zone to show internal services under
# Defaults internal
#
# [*my_ip*]
# IP address of this host
# Defaults '10.0.0.1'
#
# [*ec2_host*]
# The IP address of the EC2 API server
# Defaults $my_ip
#
# [*ec2_port*]
# The port of the EC2 API server
# Defaults 8788
#
# [*ec2_scheme*]
# The protocol to use when connecting to the EC2 API server (http, https)
# Defaults 'http'
#
# [*ec2_path*]
# The path prefix used to call the ec2 API server
# Defaults '/'
#
# [*region_list*]
# List of region=fqdn pairs separated by commas
# Defaults undef
#
# [*full_vpc_support*]
# True if server supports Neutron for full VPC access
# Defaults true
#
# [*network_device_mtu*]
# MTU size to set by DHCP for instances. Corresponds with the
# network_device_mtu in ec2api.conf.
# Defaults 1500
#
# [*cert_topic*]
# The topic cert nodes listen on
# Defaulst 'cert'
#
# [*image_decryption_dir*]
# Parent directory for tempdir used for image decryption
# Defaults '/tmp'
#
# [*s3_host*]
# Hostname or IP for OpenStack to use when accessing the S3
# Defaults '10.0.0.1'
#
# [*s3_port*]
# Port used when accessing the S3 api
# Defaults 3334
#
# [*s3_use_ssl*]
# Whether to use SSL when talking to S3
# Defaults false, not set
#
# [*s3_affix_tenant*]
# Whether to affix the tenant id to the access key when downloading from S3
# Defaults false, not set
#
# [*ec2_private_dns_show_ip*]
# Return the IP address as private dns hostname in describe instances
# Defaults false, not set
#
# [*external_network*]
# Name of the external network, which is used to connectVPCs to Internet and
# to allocate Elastic IPs
# Defaults undef
#
# [*s3_listen*]
# IP address for S3 API to listen
# Defaults '0.0.0.0'
#
# [*s3_listen_port*]
# Port for S3 API to listen
# Defaults 3334
#
# [*database_connection*]
# (optional) The SQLAlchemy connection string to use to connect to the
# database. By default is SQLite backend and is installed in:
# /usr/lib/python2.7/site-packages/
# Defaults to 'sqlite:////var/lib/ec2api/ec2api.sqlite'
#
# [*auth_uri*]
# Complete public Identity API endpoint
# Defaults 'http://localhost:5000/'
#
# [*identity_uri*]
# Complete admin Identity API endpoint. This should specify the unversioned
# root endpoint
# Defaults 'http://localhost:35357/'
#
# [*auth_version*]
# API version of the admin Identity API endpoint
# Defaults 'v2.0'
#
# [*delay_auth_decision*]
# Do not handle authorization requests within the middleware, but delegate
# the authorization decision to downstream WSGI components
# Defaults false, not set
#
# [*http_connect_timeout*]
# Request timeout value for communicating with Identity API server
# Defaults undef
#
# [*http_request_max_retries*]
# How many times are we trying to reconnect when communicating with
# Identity API Server
# Defaults 3
#
# [*admin_token*]
# This option is deprecated and may be removed in a future release. Single
# shared secret with the Keystone configuration used for bootstrapping a
# Keystone installation, or otherwise bypassing the normal authentication
# process. This option should not be used, use `admin_user` and
# `admin_password` instead
# Defaults undef
#
# [*keystone_admin_user*]
# Keystone account username
# Defaults 'ec2api'
#
# [*keystone_admin_password*]
# Keystone account password
# Defaults undef
#
# [*keystone_admin_tenant_name*]
# Keystone service account tenant name to validate user tokens
# Defaults 'services'
#
# [*keystone_certfile*]
# Required if Keystone server requires client certificate
# Defaults undef
#
# [*keystone_keyfile*]
# Required if Keystone server requires client certificate
# Defaults undef
#
# [*keystone_cafile*]
# A PEM encoded Certificate Authority to use when verifying HTTPs
# connections. Defaults to system CAs.
# Defaults undef
#
# [*insecure*]
# Verify HTTPS connections
# Defaults false
#
# [*signing_dir*]
# Directory used to cache files related to PKI tokens
# Defaults undef
#
# [*memcached_servers*]
# Optionally specify a list of memcached server(s) to use for caching. If
# left undefined, tokens will instead be cached in-process.
# Defaults undef
#
# [*token_cache_time*]
# In order to prevent excessive effort spent validating tokens, the
# middleware caches previously-seen tokens for a configurable duration
# (in seconds). Set to -1 to disable caching completely
# Defaults 300
#
# [*revocation_cache_time*]
# Determines the frequency at which the list of revoked tokens is retrieved
# from the Identity service (in seconds). A high number of revocation events
# combined with a low cache duration may significantly reduce performance
# Defaults 10
#
# [*memcache_security_strategy*]
# (optional) if defined, indicate whether token data should be
# authenticated or authenticated and encrypted. Acceptable values are MAC
# or ENCRYPT. If MAC, token data is authenticated (with HMAC) in the
# cache. If ENCRYPT, token data is encrypted and authenticated in the
# cache. If the value is not one of these options or empty, auth_token will
# raise an exception on initialization
# Defaults undef
#
# [*memcache_secret_key*]
# (optional, mandatory if memcache_security_strategy is defined) this string
# is used for key derivation
# Defaults undef
#
# [*include_service_catalog*]
# (optional) indicate whether to set the X-Service-Catalog header. If False,
# middleware will not ask for service catalog on token validation and
# will not set the X-Service-Catalog header
# Defaults true
#
# [*enforce_token_bind*]
# Used to control the use and type of token binding. Can be set to:
# "disabled" to not check token binding. "permissive" (default) to
# validate binding information if the bind type is of a form known to the
# server and ignore it if not. "strict" like "permissive" but if the bind
# type is unknown the token will be rejected. "required" any form of token
# binding is needed to be allowed. Finally the name of a binding method that
# must be present in tokens
# Defaults 'permissive'
#
# [*check_revocations_for_cached*]
# Used to control the use and type of token binding. Can be set to:
# "disabled" to not check token binding. "permissive" (default) to validate
# binding information if the bind type is of a form known to the server and
# ignore it if not. "strict" like "permissive" but if the bind type is
# unknown the token will be rejected. "required" any form of token binding
# is needed to be allowed. Finally the name of a binding method that must
# be present in tokens
# Defaults false
#
# [*hash_algorithms*]
# Hash algorithms to use for hashing PKI tokens. This may be a single
# algorithm or multiple. The algorithms are those supported by Python
# standard hashlib.new(). The hashes will be tried in the order given, so
# put the preferred one first for performance. The result of the first hash
# will be stored in the cache. This will typically be set to multiple values
# only while migrating from a less secure algorithm to a more secure one.
# Once all the old tokens are expired this option should be set to a single
# value for better performance
# Defaults 'md5'
#
# [*nova_metadata_ip*]
# IP address used by Nova metadata server
# Defaults '127.0.0.1'
#
# [*nova_metadata_port*]
# TCP Port used by Nova metadata server
# Defaults 8775
#
# [*nova_metadata_protocol*]
# Protocol to access nova metadata, http or https
# Defaults 'http'
#
# [*nova_metadata_insecure*]
# Allow to perform insecure SSL (https) requests to nova metadata
# Defaults false
#
# [*auth_ca_cert*]
# Certificate Authority public key (CA cert) file for ssl
# Defaults undef
#
# [*nova_client_cert*]
# Client certificate for nova metadata api server
# Defaults undef
#
# [*nova_client_priv_key*]
# Private key of client certificate
# Defaults undef
#
# [*metadata_proxy_shared_secret*]
# Shared secret to sign instance-id request
# Defaults undef
#
class ec2api::api (
$manage_service = true,
$enabled = true,
$debug = false,
$verbose = false,
$admin_user = undef,
$admin_password = undef,
$admin_tenant_name = undef,
$fatal_exception_format_errors = false,
$ec2api_listen = '0.0.0.0',
$ec2api_listen_port = 8788,
$ec2api_use_ssl = false,
$ec2api_workers = undef,
$metadata_listen = '0.0.0.0',
$metadata_listen_port = 8789,
$metadata_use_ssl = false,
$metadata_workers = undef,
$service_down_time = 60,
$api_paste_config = 'api-paste.ini',
$use_ssl = false,
$wsgi_ssl_ca_file = undef,
$wsgi_ssl_cert_file = undef,
$wsgi_ssl_key_file = undef,
$database_use_tpool = false,
$keystone_url = 'http://localhost:5000/v2.0',
$keystone_ec2_tokens_url = 'http://localhost:5000/v2.0/ec2tokens',
$ec2_timestamp_expiry = 300,
$api_rate_limit = false,
$use_forwarded_for = false,
$internal_service_availability_zone = internal,
$my_ip = '10.0.0.1',
$ec2_host = $my_ip,
$ec2_port = 8788,
$ec2_scheme = 'http',
$ec2_path = '/',
$region_list = undef,
$full_vpc_support = true,
$network_device_mtu = 1500,
$cert_topic = 'cert',
$image_decryption_dir = '/tmp',
$s3_host = '10.0.0.1',
$s3_port = 3334,
$s3_use_ssl = false,
$s3_affix_tenant = false,
$ec2_private_dns_show_ip = false,
$external_network = undef,
$s3_listen = '0.0.0.0',
$s3_listen_port = 3334,
$log_dir = '/var/log/ec2api',
# [database]
$database_connection = 'sqlite:////var/lib/ec2api/ec2api.sqlite',
# [keystone_authtoken]
$auth_uri = 'http://localhost:5000/',
$identity_uri = 'http://localhost:35357/',
$auth_version = 'v2.0',
$delay_auth_decision = false,
$http_connect_timeout = undef,
$http_request_max_retries = 3,
$admin_token = undef,
$keystone_admin_user = 'ec2api',
$keystone_admin_password = undef,
$keystone_admin_tenant_name = 'services',
$keystone_certfile = undef,
$keystone_keyfile = undef,
$keystone_cafile = undef,
$insecure = false,
$signing_dir = undef,
$memcached_servers = undef,
$token_cache_time = 300,
$revocation_cache_time = 10,
$memcache_security_strategy = undef,
$memcache_secret_key = undef,
$include_service_catalog = true,
$enforce_token_bind = 'permissive',
$check_revocations_for_cached = false,
$hash_algorithms = 'md5',
# [metadata]
$nova_metadata_ip = '127.0.0.1',
$nova_metadata_port = 8775,
$nova_metadata_protocol = 'http',
$nova_metadata_insecure = false,
$auth_ca_cert = undef,
$nova_client_cert = undef,
$nova_client_priv_key = undef,
$metadata_proxy_shared_secret = undef
) inherits ec2api {
Package[$ec2api::params::package_name] -> Ec2api_config<||>
Package[$ec2api::params::package_name] -> Ec2api_api_paste_ini<||>
if $use_ssl {
if !$wsgi_ssl_cert_file {
fail("The wsgi_ssl_cert_file parameter is required when use_ssl is \
set to true")
}
if !$wsgi_ssl_key_file {
fail("The wsgi_ssl_key_file parameter is required when use_ssl is \
set to true")
}
}
# Set values to ec2api.conf file
ec2api_config {
'DEFAULT/debug': value => $debug;
'DEFAULT/verbose': value => $verbose;
'DEFAULT/admin_user': value => $admin_user;
'DEFAULT/admin_password':
value => $admin_password;
'DEFAULT/admin_tenant_name': value => $admin_tenant_name;
'DEFAULT/fatal_exception_format_errors':
value => $fatal_exception_format_errors;
'DEFAULT/ec2api_listen': value => $ec2api_listen;
'DEFAULT/ec2api_listen_port': value => $ec2api_listen_port;
'DEFAULT/ec2api_use_ssl': value => $ec2api_use_ssl;
'DEFAULT/ec2api_workers': value => $ec2api_workers;
'DEFAULT/metadata_listen': value => $metadata_listen;
'DEFAULT/metadata_listen_port': value => $metadata_listen_port;
'DEFAULT/metadata_use_ssl': value => $metadata_use_ssl;
'DEFAULT/metadata_workers': value => $metadata_workers;
'DEFAULT/service_down_time': value => $service_down_time;
'DEFAULT/api_paste_config': value => $api_paste_config;
'database/use_tpool': value => $database_use_tpool;
'database/connection': value => $database_connection;
'DEFAULT/keystone_url': value => $keystone_url;
'DEFAULT/keystone_ec2_tokens_url':
value => $keystone_ec2_tokens_url;
'DEFAULT/ec2_timestamp_expiry':
value => $ec2_timestamp_expiry;
'DEFAULT/api_rate_limit': value => $api_rate_limit;
'DEFAULT/use_forwarded_for': value => $use_forwarded_for;
'DEFAULT/internal_service_availability_zone':
value => $internal_service_availability_zone;
'DEFAULT/my_ip': value => $my_ip;
#'DEFAULT/ec2_host': value => $ec2_host;
'DEFAULT/ec2_port': value => $ec2_port;
'DEFAULT/ec2_scheme': value => $ec2_scheme;
'DEFAULT/ec2_path': value => $ec2_path;
'DEFAULT/region_list': value => $region_list;
'DEFAULT/full_vpc_support': value => $full_vpc_support;
'DEFAULT/network_device_mtu': value => $network_device_mtu;
'DEFAULT/cert_topic': value => $cert_topic;
'DEFAULT/image_decryption_dir':
value => $image_decryption_dir;
'DEFAULT/s3_host': value => $s3_host;
'DEFAULT/s3_port': value => $s3_port;
'DEFAULT/s3_listen': value => $s3_listen;
'DEFAULT/s3_use_ssl': value => $s3_use_ssl;
'DEFAULT/s3_affix_tenant': value => $s3_affix_tenant;
'DEFAULT/ec2_private_dns_show_ip':
value => $ec2_private_dns_show_ip;
'DEFAULT/external_network': value => $external_network;
'keystone_authtoken/auth_uri': value => $auth_uri;
'keystone_authtoken/identity_uri': value => $identity_uri;
'keystone_authtoken/auth_version': value => $auth_version;
'keystone_authtoken/delay_auth_decision': value => $delay_auth_decision;
'keystone_authtoken/http_connect_timeout':
value => $http_connect_timeout;
'keystone_authtoken/http_request_max_retries':
value => $http_request_max_retries;
'keystone_authtoken/admin_token': value =>$admin_token;
'keystone_authtoken/admin_user': value => $keystone_admin_user;
'keystone_authtoken/admin_tenant':
value => $keystone_admin_tenant_name;
'keystone_authtoken/admin_password':
value => $keystone_admin_password;
'keystone_authtoken/certfile': value => $keystone_certfile;
'keystone_authtoken/keyfile': value => $keystone_keyfile;
'keystone_authtoken/cafile': value => $keystone_cafile;
'keystone_authtoken/insecure': value => $insecure;
'keystone_authtoken/signing_dir': value => $signing_dir;
'keystone_authtoken/memcached_servers': value => $memcached_servers;
'keystone_authtoken/token_cache_time': value => $token_cache_time;
'keystone_authtoken/revocation_cache_time':
value => $revocation_cache_time;
'keystone_authtoken/memcache_security_strategy':
value => $memcache_security_strategy;
'keystone_authtoken/memcache_secret_key':
value => $memcache_secret_key;
'keystone_authtoken/include_service_catalog':
value => $include_service_catalog;
'keystone_authtoken/enforce_token_bind': value => $enforce_token_bind;
'keystone_authtoken/check_revocations_for_cached':
value => $check_revocations_for_cached;
'keystone_authtoken/hash_algorithms': value => $hash_algorithms;
'metadata/nova_metadata_ip':
value => $nova_metadata_ip;
'metadata/nova_metadata_port':
value => $nova_metadata_port;
'metadata/nova_metadata_protocol':
value => $nova_metadata_protocol;
'metadata/nova_metadata_insecure':
value => $nova_metadata_insecure;
'metadata/auth_ca_cert':
value => $auth_ca_cert;
'metadata/nova_client_cert':
value => $nova_client_cert;
'metadata/nova_client_priv_key':
value => $nova_client_priv_key;
'metadata/metadata_proxy_shared_secret':
value => $metadata_proxy_shared_secret;
}
# SSL options
if $use_ssl {
ec2api_config {
'DEFAULT/ssl_ca_file': value => $wsgi_ssl_ca_file;
'DEFAULT/ssl_cert_file': value => $wsgi_ssl_cert_file;
'DEFAULT/ssl_key_file': value => $wsgi_ssl_key_file;
}
if $wsgi_ssl_ca_file {
ec2api_config {
'DEFAULT/ssl_ca_file' : value => $wsgi_ssl_ca_file,
}
} else {
ec2api_config {
'DEFAULT/ssl_ca_file' : ensure => absent,
}
}
} else {
ec2api_config {
'DEFAULT/ssl_cert_file' : ensure => absent;
'DEFAULT/ssl_key_file' : ensure => absent;
'DEFAULT/ssl_ca_file' : ensure => absent;
}
}
$service_ensure = 'running'
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { 'ec2api-api-service':
ensure => $service_ensure,
name => $::ec2api::params::api_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
}
}

39
manifests/config.pp Normal file
View File

@ -0,0 +1,39 @@
# == Class: ec2api::config
#
# This class is used to manage arbitrary ec2api configurations.
#
# === Parameters
#
# [*ec2api_config*]
# (optional) Allow configuration of arbitrary ec2api configurations.
# The value is an hash of ec2api_config resources. Example:
# { 'DEFAULT/foo' => { value => 'fooValue'},
# 'DEFAULT/bar' => { value => 'barValue'}
# }
# In yaml format, Example:
# ec2api_config:
# DEFAULT/foo:
# value: fooValue
# DEFAULT/bar:
# value: barValue
#
# [**ec2api_config**]
# (optional) Allow configuration of ec2api.conf configurations.
#
# [**api_paste_ini_config**]
# (optional) Allow configuration of /etc/ec2api/api-paste.ini configurations.
#
# NOTE: The configuration MUST NOT be already handled by this module
# or Puppet catalog compilation will fail with duplicate resources.
#
class ec2api::config (
$ec2api_config = {},
$api_paste_ini_config = {},
) {
validate_hash($ec2api_config)
validate_hash($api_paste_ini_config)
create_resources('ec2api_config', $ec2api_config)
create_resources('ec2api_api_paste_ini', $api_paste_ini_config)
}

70
manifests/db/mysql.pp Normal file
View File

@ -0,0 +1,70 @@
# The ec2api::db::mysql class implements mysql backend for ec2api
#
# This class can be used to create tables, users and grant
# privelege for a mysql ec2api database.
#
# == parameters
#
# [*password*]
# (Mandatory) Password to connect to the database.
# Defaults to 'false'.
#
# [*dbname*]
# (Optional) Name of the database.
# Defaults to 'ec2api'.
#
# [*user*]
# (Optional) User to connect to the database.
# Defaults to 'ec2api'.
#
# [*host*]
# (Optional) The default source host user is allowed to connect from.
# Defaults to '127.0.0.1'
#
# [*allowed_hosts*]
# (Optional) Other hosts the user is allowed to connect from.
# Defaults to 'undef'.
#
# [*charset*]
# (Optional) The database charset.
# Defaults to 'utf8'
#
# [*collate*]
# (Optional) The database collate.
# Only used with mysql modules >= 2.2.
# Defaults to 'utf8_general_ci'
#
# == Dependencies
# Class['mysql::server']
#
# == Examples
#
# == Authors
#
# == Copyright
#
class ec2api::db::mysql(
$password,
$dbname = 'ec2api',
$user = 'ec2api',
$host = '127.0.0.1',
$charset = 'utf8',
$collate = 'utf8_general_ci',
$allowed_hosts = undef
) {
validate_string($password)
::openstacklib::db::mysql { 'ec2api':
user => $user,
password_hash => mysql_password($password),
dbname => $dbname,
host => $host,
charset => $charset,
collate => $collate,
allowed_hosts => $allowed_hosts,
}
::Openstacklib::Db::Mysql['ec2api'] ~>
Exec<| title == 'ec2-api-manage db_sync' |>
}

View File

@ -0,0 +1,56 @@
# == Class: ec2api::db::postgresql
#
# Class that configures postgresql for ec2api
# Requires the Puppetlabs postgresql module.
#
# === Parameters
#
# [*password*]
# (Required) Password to connect to the database.
#
# [*dbname*]
# (Optional) Name of the database.
# Defaults to 'ec2api'.
#
# [*user*]
# (Optional) User to connect to the database.
# Defaults to 'ec2api'.
#
# [*encoding*]
# (Optional) The charset to use for the database.
# Default to undef.
#
# [*privileges*]
# (Optional) Privileges given to the database user.
# Default to 'ALL'
#
# == Dependencies
#
# == Examples
#
# == Authors
#
# == Copyright
#
class ec2api::db::postgresql(
$password,
$dbname = 'ec2api',
$user = 'ec2api',
$encoding = undef,
$privileges = 'ALL',
) {
Class['ec2api::db::postgresql'] -> Service<| title == 'ec2api' |>
::openstacklib::db::postgresql { 'ec2api':
password_hash => postgresql_password($user, $password),
dbname => $dbname,
user => $user,
encoding => $encoding,
privileges => $privileges,
}
::Openstacklib::Db::Postgresql['ec2api'] ~>
Exec<| title == 'ec2-api-manage db_sync' |>
}

14
manifests/db/sync.pp Normal file
View File

@ -0,0 +1,14 @@
#
# Class to execute "ec2api-manage db_sync
#
class ec2api::db::sync {
exec { 'ec2api-manage db_sync':
path => '/usr/bin',
user => 'ec2api',
refreshonly => true,
subscribe => [Package['ec2api'], Ec2api_config['database/connection']],
require => User['ec2api'],
}
Exec['ec2-api-manage db_sync'] ~> Service<| title == 'ec2api' |>
}

33
manifests/init.pp Normal file
View File

@ -0,0 +1,33 @@
# == Class: ec2api
#
# Main EC2 API class to configure the service via puppet.
#
class ec2api {
include ec2api::params
# Install the package
package { 'ec2api':
ensure => present,
name => $ec2api::params::package_name,
}
# Chanage onwer, group and permissions to config files
file { $ec2api::params::ec2api_config:
ensure => present,
owner => 'ec2api',
group => 'ec2api',
mode => '0644',
require => Package['ec2api'],
}
file { $ec2api::params::ec2api_api_paste_ini:
ensure => present,
owner => 'ec2api',
group => 'ec2api',
mode => '0644',
require => Package['ec2api'],
}
}

118
manifests/keystone/auth.pp Normal file
View File

@ -0,0 +1,118 @@
# == Class: ec2api::keystone::auth
#
# Configures ec2api user, service and endpoint in Keystone.
#
# === Parameters
#
# [*password*]
# (required) Password for ec2api user.
#
# [*auth_name*]
# Username for ec2api service. Defaults to 'ec2api'.
#
# [*email*]
# Email for ec2api user. Defaults to 'ec2api@localhost'.
#
# [*tenant*]
# Tenant for ec2api user. Defaults to 'services'.
#
# [*configure_endpoint*]
# Should ec2api endpoint be configured? Defaults to 'true'.
#
# [*configure_user*]
# (Optional) Should the service user be configured?
# Defaults to 'true'.
#
# [*configure_user_role*]
# (Optional) Should the admin role be configured for the service user?
# Defaults to 'true'.
#
# [*service_type*]
# Type of service. Defaults to 'FIXME'.
#
# [*public_protocol*]
# Protocol for public endpoint. Defaults to 'http'.
#
# [*public_address*]
# Public address for endpoint. Defaults to '127.0.0.1'.
#
# [*admin_protocol*]
# Protocol for admin endpoint. Defaults to 'http'.
#
# [*admin_address*]
# Admin address for endpoint. Defaults to '127.0.0.1'.
#
# [*internal_protocol*]
# Protocol for internal endpoint. Defaults to 'http'.
#
# [*internal_address*]
# Internal address for endpoint. Defaults to '127.0.0.1'.
#
# [*port*]
# Port for endpoint. Defaults to 'FIXME'.
#
# [*public_port*]
# Port for public endpoint. Defaults to $port.
#
# [*region*]
# Region for endpoint. Defaults to 'RegionOne'.
#
# [*service_name*]
# (optional) Name of the service.
# Defaults to the value of auth_name.
#
#
class ec2api::keystone::auth (
$password,
$auth_name = 'ec2api',
$email = 'ec2api@localhost',
$tenant = 'services',
$configure_endpoint = true,
$configure_user = true,
$configure_user_role = true,
$service_name = undef,
$service_type = 'FIXME',
$public_protocol = 'http',
$public_address = '127.0.0.1',
$admin_protocol = 'http',
$admin_address = '127.0.0.1',
$internal_protocol = 'http',
$internal_address = '127.0.0.1',
$port = 'FIXME',
$public_port = undef,
$region = 'RegionOne'
) {
$real_service_name = pick($service_name, $auth_name)
if $configure_user_role {
Keystone_user_role["${auth_name}@${tenant}"] ~>
Service <| name == 'ec2api-server' |>
}
Keystone_endpoint["${region}/${real_service_name}"] ~>
Service <| name == 'ec2api-server' |>
if ! $public_port {
$real_public_port = $port
} else {
$real_public_port = $public_port
}
keystone::resource::service_identity { 'ec2api':
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 => 'ec2api FIXME Service',
region => $region,
auth_name => $auth_name,
password => $password,
email => $email,
tenant => $tenant,
public_url => "${public_protocol}://${public_address}:${real_public_port}/",
internal_url => "${internal_protocol}://${internal_address}:${port}/",
admin_url => "${admin_protocol}://${admin_address}:${port}/",
}
}

211
manifests/logging.pp Normal file
View File

@ -0,0 +1,211 @@
# Class ec2api::logging
#
# ec2api extended logging configuration
#
# == parameters
#
# [*logging_context_format_string*]
# (optional) Format string to use for log messages with context.
# Defaults to undef.
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
# [%(request_id)s %(user_identity)s] %(instance)s%(message)s'
#
# [*logging_default_format_string*]
# (optional) Format string to use for log messages without context.
# Defaults to undef.
# Example: '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s\
# [-] %(instance)s%(message)s'
#
# [*logging_debug_format_suffix*]
# (optional) Formatted data to append to log format when level is DEBUG.
# Defaults to undef.
# Example: '%(funcName)s %(pathname)s:%(lineno)d'
#
# [*logging_exception_prefix*]
# (optional) Prefix each line of exception output with this format.
# Defaults to undef.
# Example: '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s'
#
# [*log_config_append*]
# The name of an additional logging configuration file.
# Defaults to undef.
# See https://docs.python.org/2/howto/logging.html
#
# [*default_log_levels*]
# (optional) Hash of logger (keys) and level (values) pairs.
# Defaults to undef.
# Example:
# { 'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN',
# 'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO',
# 'oslo.messaging' => 'INFO', 'iso8601' => 'WARN',
# 'requests.packages.urllib3.connectionpool' => 'WARN',
# 'urllib3.connectionpool' => 'WARN',
# 'websocket' => 'WARN', 'ec2apimiddleware' => 'WARN',
# 'routes.middleware' => 'WARN', stevedore => 'WARN' }
#
# [*publish_errors*]
# (optional) Publish error events (boolean value).
# Defaults to undef (false if unconfigured).
#
# [*fatal_deprecations*]
# (optional) Make deprecations fatal (boolean value)
# Defaults to undef (false if unconfigured).
#
# [*instance_format*]
# (optional) If an instance is passed with the log message, format it
# like this (string value).
# Defaults to undef.
# Example: '[instance: %(uuid)s] '
#
# [*instance_uuid_format*]
# (optional) If an instance UUID is passed with the log message, format
# it like this (string value).
# Defaults to undef.
# Example: instance_uuid_format='[instance: %(uuid)s] '
# [*log_date_format*]
# (optional) Format string for %%(asctime)s in log records.
# Defaults to undef.
# Example: 'Y-%m-%d %H:%M:%S'
class ec2api::logging(
$logging_context_format_string = undef,
$logging_default_format_string = undef,
$logging_debug_format_suffix = undef,
$logging_exception_prefix = undef,
$log_config_append = undef,
$default_log_levels = undef,
$publish_errors = undef,
$fatal_deprecations = undef,
$instance_format = undef,
$instance_uuid_format = undef,
$log_date_format = undef,
) {
if $logging_context_format_string {
ec2api_config {
'DEFAULT/logging_context_format_string' :
value => $logging_context_format_string;
}
}
else {
ec2api_config {
'DEFAULT/logging_context_format_string' : ensure => absent;
}
}
if $logging_default_format_string {
ec2api_config {
'DEFAULT/logging_default_format_string' :
value => $logging_default_format_string;
}
}
else {
ec2api_config {
'DEFAULT/logging_default_format_string' : ensure => absent;
}
}
if $logging_debug_format_suffix {
ec2api_config {
'DEFAULT/logging_debug_format_suffix' :
value => $logging_debug_format_suffix;
}
}
else {
ec2api_config {
'DEFAULT/logging_debug_format_suffix' : ensure => absent;
}
}
if $logging_exception_prefix {
ec2api_config {
'DEFAULT/logging_exception_prefix' : value => $logging_exception_prefix;
}
}
else {
ec2api_config {
'DEFAULT/logging_exception_prefix' : ensure => absent;
}
}
if $log_config_append {
ec2api_config {
'DEFAULT/log_config_append' : value => $log_config_append;
}
}
else {
ec2api_config {
'DEFAULT/log_config_append' : ensure => absent;
}
}
if $default_log_levels {
ec2api_config {
'DEFAULT/default_log_levels' :
value => join(sort(join_keys_to_values($default_log_levels, '=')), ',');
}
}
else {
ec2api_config {
'DEFAULT/default_log_levels' : ensure => absent;
}
}
if $publish_errors {
ec2api_config {
'DEFAULT/publish_errors' : value => $publish_errors;
}
}
else {
ec2api_config {
'DEFAULT/publish_errors' : ensure => absent;
}
}
if $fatal_deprecations {
ec2api_config {
'DEFAULT/fatal_deprecations' : value => $fatal_deprecations;
}
}
else {
ec2api_config {
'DEFAULT/fatal_deprecations' : ensure => absent;
}
}
if $instance_format {
ec2api_config {
'DEFAULT/instance_format' : value => $instance_format;
}
}
else {
ec2api_config {
'DEFAULT/instance_format' : ensure => absent;
}
}
if $instance_uuid_format {
ec2api_config {
'DEFAULT/instance_uuid_format' : value => $instance_uuid_format;
}
}
else {
ec2api_config {
'DEFAULT/instance_uuid_format' : ensure => absent;
}
}
if $log_date_format {
ec2api_config {
'DEFAULT/log_date_format' : value => $log_date_format;
}
}
else {
ec2api_config {
'DEFAULT/log_date_format' : ensure => absent;
}
}
}

32
manifests/metadata.pp Normal file
View File

@ -0,0 +1,32 @@
# === Parameters
#
#
class ec2api::metadata (
$manage_service = true,
$enabled = true,
$nova_metadata_ip = '127.0.0.1',
$nova_metadata_port = 8775,
$nova_metadata_protocol = 'http',
$nova_metadata_insecure = false,
$auth_ca_cert = unset,
$nova_client_cert = unset,
$nova_client_priv_key = unset,
$metadata_proxy_shared_secret = unset,
) inherits ec2api {
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { 'openstack-ec2-api-metadata':
ensure => $service_ensure,
name => $::ec2api::params::metadata_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
}
}

12
manifests/params.pp Normal file
View File

@ -0,0 +1,12 @@
# == Class: ec2api::params
#
# These parameters need to be accessed from several locations and
# should be considered to be constant
class ec2api::params {
$package_name = 'openstack-ec2-api'
$api_service_name = 'openstack-ec2-api'
$ec2api_config = '/etc/ec2api/ec2api.conf'
$ec2api_api_paste_ini = '/etc/ec2api/api-paste.ini'
$s3_service_name = 'openstack-ec2-api-s3'
$metadata_service_name = 'openstack-ec2-api-metadata'
}

34
manifests/s3.pp Normal file
View File

@ -0,0 +1,34 @@
# === Parameters
#
#
class ec2api::s3 (
$manage_service = true,
$enabled = true,
$buckets_path = undef,
$s3_listen = '0.0.0.0',
$s3_listen_port = 3334,
) inherits ec2api {
# Configuration
ec2api_config {
'DEFAULT/buckets_path': value => $buckets_path;
'DEFAULT/s3_listen': value => $s3_listen;
'DEFAULT/s3_listen_port': value => $s3_listen_port;
}
if $manage_service {
if $enabled {
$service_ensure = 'running'
} else {
$service_ensure = 'stopped'
}
}
service { 'openstack-ec2-api-s3':
ensure => $service_ensure,
name => $::ec2api::params::s3_service_name,
enable => $enabled,
hasstatus => true,
hasrestart => true,
}
}

34
metadata.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "puppet-ec2api",
"version": "0.0.1",
"author": "OpenStack Contributors",
"summary": "Puppet module for OpenStack Ec2api",
"license": "Apache-2.0",
"source": "git://github.com/openstack/puppet-ec2api.git",
"project_page": "https://launchpad.net/puppet-ec2api",
"issues_url": "https://bugs.launchpad.net/puppet-ec2api",
"description": "Installs and configures OpenStack Ec2api.",
"operatingsystem_support": [
{
"operatingsystem": "Debian",
"operatingsystemrelease": ["8"]
},
{
"operatingsystem": "Fedora",
"operatingsystemrelease": ["21","22"]
},
{
"operatingsystem": "RedHat",
"operatingsystemrelease": ["7"]
},
{
"operatingsystem": "Ubuntu",
"operatingsystemrelease": ["14.04"]
}
],
"dependencies": [
{ "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" },
{ "name": "puppetlabs/stdlib", "version_requirement": ">= 4.0.0 <5.0.0" },
{ "name": "stackforge/openstacklib", "version_requirement": ">=5.0.0 <6.0.0" }
]
}

View File

@ -0,0 +1,62 @@
require 'spec_helper'
describe 'ec2api::db::mysql' do
let :pre_condition do
[
'include mysql::server',
'include ec2api::db::sync'
]
end
let :facts do
{ :osfamily => 'Debian' }
end
let :params do
{
'password' => 'pwd',
}
end
describe 'with only required params' do
it { is_expected.to contain_openstacklib__db__mysql('ec2api').with(
'user' => 'ec2api',
'password_hash' => '*0000000',
'dbname' => 'ec2api',
'host' => '127.0.0.1',
'charset' => 'utf8',
:collate => 'utf8_general_ci',
)}
end
describe "overriding allowed_hosts param to array" do
let :params do
{
:password => 'pwd',
:allowed_hosts => ['127.0.0.1','%']
}
end
end
describe "overriding allowed_hosts param to string" do
let :params do
{
:password => 'pwd',
:allowed_hosts => '192.168.1.1'
}
end
end
describe "overriding allowed_hosts param equals to host param " do
let :params do
{
:password => 'pwd',
:allowed_hosts => '127.0.0.1'
}
end
end
end

View File

@ -0,0 +1,58 @@
require 'spec_helper'
describe 'ec2api::db::postgresql' do
let :req_params do
{ :password => 'pw' }
end
let :pre_condition do
'include postgresql::server'
end
context 'on a RedHat osfamily' do
let :facts do
{
:osfamily => 'RedHat',
:operatingsystemrelease => '7.0',
:concat_basedir => '/var/lib/puppet/concat'
}
end
context 'with only required parameters' do
let :params do
req_params
end
it { is_expected.to contain_postgresql__server__db('ec2api').with(
:user => 'ec2api',
:password => 'pwd'
)}
end
end
context 'on a Debian osfamily' do
let :facts do
{
:operatingsystemrelease => '7.8',
:operatingsystem => 'Debian',
:osfamily => 'Debian',
:concat_basedir => '/var/lib/puppet/concat'
}
end
context 'with only required parameters' do
let :params do
req_params
end
it { is_expected.to contain_postgresql__server__db('ec2api').with(
:user => 'ec2api',
:password => 'pwd'
)}
end
end
end

View File

@ -0,0 +1,127 @@
#
# Unit tests for ec2api::keystone::auth
#
require 'spec_helper'
describe 'ec2api::keystone::auth' do
let :facts do
{ :osfamily => 'Debian' }
end
describe 'with default class parameters' do
let :params do
{ :password => 'pwd',
:tenant => 'services' }
end
it { is_expected.to contain_keystone_user('ec2api').with(
:ensure => 'present',
:password => 'pwd',
:tenant => 'services'
) }
it { is_expected.to contain_keystone_user_role('ec2api@services').with(
:ensure => 'present',
:roles => ['admin']
)}
it { is_expected.to contain_keystone_service('ec2api').with(
:ensure => 'present',
:type => 'ec2',
:description => 'ec2api Service'
) }
it { is_expected.to contain_keystone_endpoint('RegionOne/ec2api').with(
:ensure => 'present',
:public_url => "http://127.0.0.1:8788/",
:admin_url => "http://127.0.0.1:8788/",
:internal_url => "http://127.0.0.1:8788/"
) }
end
describe 'when overriding public_protocol, public_port and public address' do
let :params do
{ :password => 'pwd',
:public_protocol => 'https',
:public_port => '80',
:public_address => '10.10.10.10',
:port => '81',
:internal_address => '10.10.10.11',
:admin_address => '10.10.10.12' }
end
it { is_expected.to contain_keystone_endpoint('RegionOne/ec2api').with(
:ensure => 'present',
:public_url => "https://10.10.10.10:80/",
:internal_url => "http://10.10.10.11:81/",
:admin_url => "http://10.10.10.12:81/"
) }
end
describe 'when overriding auth name' do
let :params do
{ :password => 'foo',
:auth_name => 'ec2apiy' }
end
it { is_expected.to contain_keystone_user('ec2apiy') }
it { is_expected.to contain_keystone_user_role('ec2apiy@services') }
it { is_expected.to contain_keystone_service('ec2apiy') }
it { is_expected.to contain_keystone_endpoint('RegionOne/ec2apiy') }
end
describe 'when overriding service name' do
let :params do
{ :service_name => 'ec2api_service',
:auth_name => 'ec2api',
:password => 'pwd' }
end
it { is_expected.to contain_keystone_user('ec2api') }
it { is_expected.to contain_keystone_user_role('ec2api@services') }
it { is_expected.to contain_keystone_service('ec2api_service') }
it { is_expected.to contain_keystone_endpoint('RegionOne/ec2api_service') }
end
describe 'when disabling user configuration' do
let :params do
{
:password => 'ec2api_password',
:configure_user => false
}
end
it { is_expected.not_to contain_keystone_user('ec2api') }
it { is_expected.to contain_keystone_user_role('ec2api@services') }
it { is_expected.to contain_keystone_service('ec2api').with(
:ensure => 'present',
:type => 'ec2',
:description => 'ec2api Service'
) }
end
describe 'when disabling user and user role configuration' do
let :params do
{
:password => 'ec2api_password',
:configure_user => false,
:configure_user_role => false
}
end
it { is_expected.not_to contain_keystone_user('ec2api') }
it { is_expected.not_to contain_keystone_user_role('ec2api@services') }
it { is_expected.to contain_keystone_service('ec2api').with(
:ensure => 'present',
:type => 'ec2',
:description => 'ec2api Service'
) }
end
end

View File

@ -0,0 +1,107 @@
require 'spec_helper'
describe 'ec2api::logging' do
let :params do
{
}
end
let :log_params do
{
:logging_context_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s',
:logging_default_format_string => '%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s',
:logging_debug_format_suffix => '%(funcName)s %(pathname)s:%(lineno)d',
:logging_exception_prefix => '%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s',
:log_config_append => '/etc/ec2api/logging.conf',
:publish_errors => true,
:default_log_levels => {
'amqp' => 'WARN', 'amqplib' => 'WARN', 'boto' => 'WARN',
'qpid' => 'WARN', 'sqlalchemy' => 'WARN', 'suds' => 'INFO',
'iso8601' => 'WARN',
'requests.packages.urllib3.connectionpool' => 'WARN' },
:fatal_deprecations => true,
:instance_format => '[instance: %(uuid)s] ',
:instance_uuid_format => '[instance: %(uuid)s] ',
:log_date_format => '%Y-%m-%d %H:%M:%S',
}
end
shared_examples_for 'ec2api-logging' do
context 'with extended logging options' do
before { params.merge!( log_params ) }
it_configures 'logging params set'
end
context 'without extended logging options' do
it_configures 'logging params unset'
end
end
shared_examples_for 'logging params set' do
it 'enables logging params' do
is_expected.to contain_ec2api_config('DEFAULT/logging_context_format_string').with_value(
'%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s')
is_expected.to contain_ec2api_config('DEFAULT/logging_default_format_string').with_value(
'%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s')
is_expected.to contain_ec2api_config('DEFAULT/logging_debug_format_suffix').with_value(
'%(funcName)s %(pathname)s:%(lineno)d')
is_expected.to contain_ec2api_config('DEFAULT/logging_exception_prefix').with_value(
'%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s')
is_expected.to contain_ec2api_config('DEFAULT/log_config_append').with_value(
'/etc/ec2api/logging.conf')
is_expected.to contain_ec2api_config('DEFAULT/publish_errors').with_value(
true)
is_expected.to contain_ec2api_config('DEFAULT/default_log_levels').with_value(
'amqp=WARN,amqplib=WARN,boto=WARN,iso8601=WARN,qpid=WARN,requests.packages.urllib3.connectionpool=WARN,sqlalchemy=WARN,suds=INFO')
is_expected.to contain_ec2api_config('DEFAULT/fatal_deprecations').with_value(
true)
is_expected.to contain_ec2api_config('DEFAULT/instance_format').with_value(
'[instance: %(uuid)s] ')
is_expected.to contain_ec2api_config('DEFAULT/instance_uuid_format').with_value(
'[instance: %(uuid)s] ')
is_expected.to contain_ec2api_config('DEFAULT/log_date_format').with_value(
'%Y-%m-%d %H:%M:%S')
end
end
shared_examples_for 'logging params unset' do
[ :logging_context_format_string, :logging_default_format_string,
:logging_debug_format_suffix, :logging_exception_prefix,
:log_config_append, :publish_errors,
:default_log_levels, :fatal_deprecations,
:instance_format, :instance_uuid_format,
:log_date_format, ].each { |param|
it { is_expected.to contain_ec2api_config("DEFAULT/#{param}").with_ensure('absent') }
}
end
context 'on Debian platforms' do
let :facts do
{ :osfamily => 'Debian' }
end
it_configures 'ec2api-logging'
end
context 'on RedHat platforms' do
let :facts do
{ :osfamily => 'RedHat' }
end
it_configures 'ec2api-logging'
end
end

5
spec/shared_examples.rb Normal file
View File

@ -0,0 +1,5 @@
shared_examples_for "a Puppet::Error" do |description|
it "with message matching #{description.inspect}" do
expect { is_expected.to have_class_count(1) }.to raise_error(Puppet::Error, description)
end
end

View File

@ -0,0 +1,37 @@
# these tests are a little concerning b/c they are hacking around the
# modulepath, so these tests will not catch issues that may eventually arise
# related to loading these plugins.
# I could not, for the life of me, figure out how to programatcally set the modulepath
$LOAD_PATH.push(
File.join(
File.dirname(__FILE__),
'..',
'..',
'..',
'fixtures',
'modules',
'inifile',
'lib')
)
require 'spec_helper'
provider_class = Puppet::Type.type(:ec2api_config).provider(:ini_setting)
describe provider_class do
it 'should default to the default setting when no other one is specified' do
resource = Puppet::Type::Ec2api_config.new(
{:name => 'DEFAULT/foo', :value => 'bar'}
)
provider = provider_class.new(resource)
expect(provider.section).to eq('DEFAULT')
expect(provider.setting).to eq('foo')
end
it 'should allow setting to be set explicitly' do
resource = Puppet::Type::Ec2api_config.new(
{:name => 'dude/foo', :value => 'bar'}
)
provider = provider_class.new(resource)
expect(provider.section).to eq('dude')
expect(provider.setting).to eq('foo')
end
end

View File

@ -0,0 +1,52 @@
require 'puppet'
require 'puppet/type/ec2api_config'
describe 'Puppet::Type.type(:ec2api_config)' do
before :each do
@ec2api_config = Puppet::Type.type(:ec2api_config).new(:name => 'DEFAULT/foo', :value => 'bar')
end
it 'should require a name' do
expect {
Puppet::Type.type(:ec2api_config).new({})
}.to raise_error(Puppet::Error, 'Title or name must be provided')
end
it 'should not expect a name with whitespace' do
expect {
Puppet::Type.type(:ec2api_config).new(:name => 'f oo')
}.to raise_error(Puppet::Error, /Parameter name failed/)
end
it 'should fail when there is no section' do
expect {
Puppet::Type.type(:ec2api_config).new(:name => 'foo')
}.to raise_error(Puppet::Error, /Parameter name failed/)
end
it 'should not require a value when ensure is absent' do
Puppet::Type.type(:ec2api_config).new(:name => 'DEFAULT/foo', :ensure => :absent)
end
it 'should accept a valid value' do
@ec2api_config[:value] = 'bar'
expect(@ec2api_config[:value]).to eq('bar')
end
it 'should not accept a value with whitespace' do
@ec2api_config[:value] = 'b ar'
expect(@ec2api_config[:value]).to eq('b ar')
end
it 'should accept valid ensure values' do
@ec2api_config[:ensure] = :present
expect(@ec2api_config[:ensure]).to eq(:present)
@ec2api_config[:ensure] = :absent
expect(@ec2api_config[:ensure]).to eq(:absent)
end
it 'should not accept invalid ensure values' do
expect {
@ec2api_config[:ensure] = :latest
}.to raise_error(Puppet::Error, /Invalid value/)
end
end

3
templates/example.erb Normal file
View File

@ -0,0 +1,3 @@
<% if @myvar %>
myvar has <%= @myvar %> value
<% end %>

12
tests/init.pp Normal file
View File

@ -0,0 +1,12 @@
# The baseline for module testing used by Puppet Labs is that each manifest
# should have a corresponding test manifest that declares that class or defined
# type.
#
# Tests are then run by using puppet apply --noop (to check for compilation
# errors and view a log of events) or by fully applying the test in a virtual
# environment (to compare the resulting system state to the desired state).
#
# Learn more about module testing here:
# http://docs.puppetlabs.com/guides/tests_smoke.html
#
include ::ec2api