Merge "Sync horizon module with upstream"

This commit is contained in:
Jenkins 2015-01-15 13:08:58 +00:00 committed by Gerrit Code Review
commit 1e7b825756
32 changed files with 1699 additions and 1086 deletions

View File

@ -1,3 +1,8 @@
fixtures:
repositories:
"apache": "git://github.com/puppetlabs/puppetlabs-apache.git"
"concat": "git://github.com/ripienaar/puppet-concat.git"
"firewall": "git://github.com/puppetlabs/puppetlabs-firewall.git"
"stdlib": "git://github.com/puppetlabs/puppetlabs-stdlib.git"
symlinks:
"horizon": "#{source_dir}"

View File

@ -1,5 +0,0 @@
source :rubygems
puppetversion = ENV.key?('PUPPET_VERSION') ? "= #{ENV['PUPPET_VERSION']}" : ['>= 2.7']
gem 'puppet', puppetversion
gem 'puppetlabs_spec_helper', '>= 0.1.0'

View File

@ -1,6 +1,5 @@
Gemfile.lock
spec/fixtures/modules/*
spec/fixtures/manifests/site.pp
*.swp
pkg/
.DS_Store
metadata.json
coverage/
.project
pkg

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>horizon</name>
<comment></comment>
<projects>
<project>stdlib</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.cloudsmith.geppetto.pp.dsl.ui.modulefileBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.cloudsmith.geppetto.pp.dsl.ui.puppetNature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>

View File

@ -1,5 +0,0 @@
* 2012-10-08 0.2.0
- better rspec tests
- adds more params for settings config file
* 2012-06-12 0.1.0
- Initial release

View File

@ -0,0 +1,18 @@
source 'https://rubygems.org'
group :development, :test do
gem 'puppetlabs_spec_helper', :require => false
gem 'puppet-lint', '~> 0.3.2'
gem 'rake', '10.1.1'
gem 'rspec', '< 2.99'
gem 'json'
gem 'webmock'
end
if puppetversion = ENV['PUPPET_GEM_VERSION']
gem 'puppet', puppetversion, :require => false
else
gem 'puppet', :require => false
end
# vim:ft=ruby

View File

@ -1,9 +0,0 @@
name 'puppetlabs-horizon'
version '0.2.0'
source 'https://github.com/puppetlabs/puppetlabs-horizon'
author 'Puppet Labs'
license 'Apache License 2.0'
summary 'Horizon Dashboard Module for Puppet'
project_page 'https://github.com/puppetlabs/puppetlabs-horizon'
dependency 'saz/memcached', '>= 2.0.2'

View File

@ -1,4 +1,165 @@
OpenStack Dashboard
===================
horizon
=======
5.0.0 - 2014.2.0 - Juno
#### Table of Contents
1. [Overview - What is the horizon module?](#overview)
2. [Module Description - What does the module do?](#module-description)
3. [Setup - The basics of getting started with horizon](#setup)
4. [Implementation - An under-the-hood peek at what the module is doing](#implementation)
5. [Limitations - OS compatibility, etc.](#limitations)
6. [Development - Guide for contributing to the module](#development)
7. [Contributors - Those with commits](#contributors)
8. [Release Notes - Notes on the most recent updates to the module](#release-notes)
Overview
--------
The horizon module is a part of [Stackforge](https://github.com/stackforge), an effort by the Openstack infrastructure team to provide continuous integration testing and code review for Openstack and Openstack community projects not part of the core software. The module its self is used to flexibly configure and manage the dashboard service for Openstack.
Module Description
------------------
The horizon module is a thorough attempt to make Puppet capable of managing the entirety of horizon. Horizon is a fairly classic django application, which results in a fairly simply Puppet module.
This module is tested in combination with other modules needed to build and leverage an entire Openstack software stack. These modules can be found, all pulled together in the [openstack module](https://github.com/stackforge/puppet-openstack).
Setup
-----
**What the horizon module affects**
* horizon, the dashboard service for Openstack.
### Installing horizon
example% puppet module install puppetlabs/horizon
### Beginning with horizon
To utilize the horizon module's functionality you will need to declare multiple resources but you'll find that doing so is much less complicated than the other OpenStack component modules. The following is a modified excerpt from the [openstack module](https://github.com/stackforge/puppet-openstack). We recommend you consult and understand the [openstack module](https://github.com/stackforge/puppet-openstack) and the [core openstack](http://docs.openstack.org) documentation.
**Define a horizon dashboard**
```puppet
class { 'memcached':
listen_ip => '127.0.0.1',
tcp_port => '11211',
udp_port => '11211',
}
class { '::horizon':
cache_server_ip => '127.0.0.1',
cache_server_port => '11211',
secret_key => '12345',
swift => false,
django_debug => 'True',
api_result_limit => '2000',
}
```
Implementation
--------------
### horizon
Horizon is a simple module using the combination of a package, template, and the file_line type. Most all the configuration lives inside the included local_settings template and the file_line type is for selectively inserting needed lines into configuration files that aren't explicitly managed by the horizon module.
Limitations
------------
* Only supports Apache using mod_wsgi.
Development
-----------
Developer documentation for the entire puppet-openstack project.
* https://wiki.openstack.org/wiki/Puppet-openstack#Developer_documentation
Contributors
------------
* https://github.com/stackforge/puppet-horizon/graphs/contributors
Release Notes
-------------
**5.0.0**
* Stable Juno release
* Fixed the default value of compress_offline parameter
* Always manages local_settings.py
* Added parameters to configure policy files in horizon class
* Fixed Apache config file default
* Added parameter django_session_engine to horizon class
* Stops setting wsgi_socket_prefix since the apache module takes care of it
* Adds workaround for puppet's handling of undef for setting the vhost bind address
* Changes cache_server_ip in horizon class to accept arrays
* Switched the default log level to INFO from DEBUG
* Fixed the default MSSQL port in security group rules
**4.2.0**
* Added parameters to configure ALLOWED_HOSTS in settings_local.y and
ServerAlias in apache, no longer requiring these values to be the fqdn
* Fixed removal of vhost conf file
* Added support for secure cookies
**4.1.0**
* Added option to set temporary upload directory for images.
* Ensure ssl wsgi_process_group is the same as wsgi_daemon_process.
* Pined major gems.
**4.0.0**
* Stable Icehouse release.
* Added support to pass extra parameters to vhost.
* Added support to ensure online cache is present and can be refreshed.
* Added support to configure OPENSTACK_HYPERVISOR_FEATURES settings, AVAILABLE_REGIONS, OPENSTACK_NEUTRON_NETWORK.
* Added support to disable configuration of Apache.
* Fixed log ownership and WSGIProcess* settings for Red Hat releases.
* Fixed overriding of policy files in local settings.
* Fixed SSL bugs.
* Improved WSGI configuration.
**3.1.0**
* Added option parameterize OPENSTACK_NEUTRON_NETWORK settings.
**3.0.1**
* Adds COMPRESS_OFFLINE option to local_settings to fix broken Ubuntu installation.
**3.0.0**
* Major release for OpenStack Havana.
* Updated user and group for Debian family OSes.
* Updated policy files for RedHat family OSes.
* Enabled SSL support with cert/key.
* Improved default logging configuration.
* Fixed bug to set LOGOUT_URL properly.
* Introduced new parameters: keystone_url, help_url, endpoint type.
* Fixed user/group regression for Debian.
* Changed keystone_default_role to _member_.
**2.2.0**
* Fixed apache 0.9.0 incompatability.
* Various lint fixes.
**2.1.0**
* Updated local_settings.py.
* Pinned Apache module version.
* Various lint fixes.
**2.0.0**
* Upstream is now part of stackforge.
* httpd config now managed on every platform.
* Provides option to enable Horizon's display of block device mount points.
Puppet module for [Horizon](http://horizon.openstack.org/), ([OpenStack Dashboard](http://wiki.openstack.org/OpenStackDashboard))

View File

@ -1 +1,6 @@
require 'puppetlabs_spec_helper/rake_tasks'
require 'puppet-lint/tasks/puppet-lint'
PuppetLint.configuration.fail_on_warnings = true
PuppetLint.configuration.send('disable_80chars')
PuppetLint.configuration.send('disable_class_parameter_defaults')

View File

@ -0,0 +1,34 @@
#
# os_any2array.rb
#
# TODO: Remove this function when puppetlabs-stdlib 4.0.0 is in wider use
module Puppet::Parser::Functions
newfunction(:os_any2array, :type => :rvalue, :doc => <<-EOS
This converts any object to an array containing that object. Empty argument
lists are converted to an empty array. Arrays are left untouched. Hashes are
converted to arrays of alternating keys and values.
EOS
) do |arguments|
if arguments.empty?
return []
end
if arguments.length == 1
if arguments[0].kind_of?(Array)
return arguments[0]
elsif arguments[0].kind_of?(Hash)
result = []
arguments[0].each do |key, value|
result << key << value
end
return result
end
end
return arguments
end
end
# vim: set ts=2 sw=2 et :

View File

@ -1,22 +0,0 @@
Puppet::Type.type(:a2mod).provide(:a2mod) do
desc "Manage Apache 2 modules on Debian and Ubuntu"
optional_commands :encmd => "a2enmod"
optional_commands :discmd => "a2dismod"
confine :osfamily => :debian
defaultfor :operatingsystem => [:debian, :ubuntu]
def create
encmd resource[:name]
end
def destroy
discmd resource[:name]
end
def exists?
mod= "/etc/apache2/mods-enabled/" + resource[:name] + ".load"
File.exists?(mod)
end
end

View File

@ -1,116 +0,0 @@
require 'puppet/util/filetype'
Puppet::Type.type(:a2mod).provide(:gentoo, :parent => Puppet::Provider) do
desc "Manage Apache 2 modules on Gentoo"
confine :operatingsystem => :gentoo
defaultfor :operatingsystem => :gentoo
attr_accessor :property_hash
def create
@property_hash[:ensure] = :present
end
def exists?
(!(@property_hash[:ensure].nil?) and @property_hash[:ensure] == :present)
end
def destroy
@property_hash[:ensure] = :absent
end
def flush
self.class.flush
end
class << self
attr_reader :conf_file
end
def self.clear
@mod_resources = []
@modules = []
@other_args = ""
end
def self.initvars
@conf_file = "/etc/conf.d/apache2"
@filetype = Puppet::Util::FileType.filetype(:flat).new(conf_file)
@mod_resources = []
@modules = []
@other_args = ""
end
self.initvars
# Retrieve an array of all existing modules
def self.modules
if @modules.length <= 0
# Locate the APACHE_OPTS variable
records = filetype.read.split(/\n/)
apache2_opts = records.grep(/^\s*APACHE2_OPTS=/).first
# Extract all defines
while apache2_opts.sub!(/-D\s+(\w+)/, '')
@modules << $1.downcase
end
# Hang on to any remaining options.
if apache2_opts.match(/APACHE2_OPTS="(.+)"/)
@other_args = $1.strip
end
@modules.sort!.uniq!
end
@modules
end
def self.prefetch(resources={})
# Match resources with existing providers
instances.each do |provider|
if resource = resources[provider.name]
resource.provider = provider
end
end
# Store all resources using this provider for flushing
resources.each do |name, resource|
@mod_resources << resource
end
end
def self.instances
modules.map {|mod| new(:name => mod, :provider => :gentoo, :ensure => :present)}
end
def self.flush
mod_list = modules
mods_to_remove = @mod_resources.select {|mod| mod.should(:ensure) == :absent}.map {|mod| mod[:name]}
mods_to_add = @mod_resources.select {|mod| mod.should(:ensure) == :present}.map {|mod| mod[:name]}
mod_list -= mods_to_remove
mod_list += mods_to_add
mod_list.sort!.uniq!
if modules != mod_list
opts = @other_args + " "
opts << mod_list.map {|mod| "-D #{mod.upcase}"}.join(" ")
opts.strip!
opts.gsub!(/\s+/, ' ')
apache2_opts = %Q{APACHE2_OPTS="#{opts}"}
Puppet.debug("Writing back \"#{apache2_opts}\" to #{conf_file}")
records = filetype.read.split(/\n/)
opts_index = records.find_index {|i| i.match(/^\s*APACHE2_OPTS/)}
records[opts_index] = apache2_opts
filetype.backup
filetype.write(records.join("\n"))
@modules = mod_list
end
end
end

View File

@ -1,12 +0,0 @@
Puppet::Type.type(:a2mod).provide :modfix do
desc "Dummy provider for A2mod.
Fake nil resources when there is no crontab binary available. Allows
puppetd to run on a bootstrapped machine before a Cron package has been
installed. Workaround for: http://projects.puppetlabs.com/issues/2384
"
def self.instances
[]
end
end

View File

@ -1,61 +0,0 @@
Puppet::Type.type(:a2mod).provide(:redhat) do
desc "Manage Apache 2 modules on RedHat family OSs"
confine :osfamily => :redhat
defaultfor :osfamily => :redhat
require 'pathname'
# modpath: Path to default apache modules directory /etc/httpd/mod.d
# modfile: Path to module load configuration file; Default: resides under modpath directory
# libfile: Path to actual apache module library. Added in modfile LoadModule
attr_accessor :modfile, :libfile
class << self
attr_accessor :modpath
def preinit
@modpath = "/etc/httpd/mod.d"
end
end
self.preinit
def create
File.open(modfile,'w') do |f|
f.puts "LoadModule #{resource[:identifier]} #{libfile}"
end
end
def destroy
File.delete(modfile)
end
def exists?
File.exists?(modfile) and File.read(modfile).match(libfile)
end
def self.instances
modules = []
Dir.glob("#{modpath}/*.load").each do |file|
m = file.match(/(\w+)\.load$/)
modules << m[1] if m
end
modules.map do |mod|
new(
:name => mod,
:ensure => :present,
:provider => :redhat
)
end
end
def modfile
modfile ||= "#{self.class.modpath}/#{resource[:name]}.load"
end
# Set libfile path: If absolute path is passed, then maintain it. Else, make it default from 'modules' dir.
def libfile
libfile = Pathname.new(resource[:lib]).absolute? ? resource[:lib] : "modules/#{resource[:lib]}"
end
end

View File

@ -1,29 +0,0 @@
Puppet::Type.newtype(:a2mod) do
@doc = "Manage Apache 2 modules"
ensurable
newparam(:name) do
desc "The name of the module to be managed"
isnamevar
end
newparam(:lib) do
desc "The name of the .so library to be loaded"
defaultto { "mod_#{@resource[:name]}.so" }
end
newparam(:identifier) do
desc "Module identifier string used by LoadModule. Default: module-name_module"
# http://httpd.apache.org/docs/2.2/mod/module-dict.html#ModuleIdentifier
defaultto { "#{resource[:name]}_module" }
end
autorequire(:package) { catalog.resource(:package, 'httpd')}
end

View File

@ -1,298 +1,347 @@
# == Class: horizon
#
# installs a horizon server
# Installs Horizon dashboard with Apache
#
# === Parameters
#
# - Parameters
# $secret_key the application secret key (used to crypt cookies, etc. ). mandatory
# $cache_server_ip memcached ip address (or VIP)
# $cache_server_port memcached port
# $swift (bool) is swift installed
# $quantum (bool) is quantum installed
# The next is an array of arrays, that can be used to add call-out links to the dashboard for other apps.
# There is no specific requirement for these apps to be for monitoring, that's just the defacto purpose.
# Each app is defined in two parts, the display name, and the URI
# [horizon_app_links] array as in '[ ["Nagios","http://nagios_addr:port/path"],["Ganglia","http://ganglia_addr"] ]'
# $keystone_host ip address/hostname of the keystone service
# $keystone_port public port of the keystone service
# $keystone_scheme http or https
# $keystone_default_role default keystone role for new users
# $django_debug True/False. enable/disables debugging (debug level). defaults to false
# $django_verbose True/False. enable/disables verbose logging (info level). defaults to false
# $log_level Syslog level would be used for logging. If Verbose -> INFO, Debug -> DEBUG, otherwise -> the value given
# $api_result_limit max number of Swift containers/objects to display on a single page
# $use_syslog Redirect all apache logging to syslog. Required for FUEL-UI. Defaults to false.
# [*secret_key*]
# (required) Secret key. This is used by Django to provide cryptographic
# signing, and should be set to a unique, unpredictable value.
#
# [*fqdn*]
# (optional) DEPRECATED, use allowed_hosts and server_aliases instead.
# FQDN(s) used to access Horizon. This is used by Django for
# security reasons. Can be set to * in environments where security is
# deemed unimportant. Also used for Server Aliases in web configs.
# Defaults to ::fqdn
#
# [*servername*]
# (optional) FQDN used for the Server Name directives
# Defaults to ::fqdn.
#
# [*allowed_hosts*]
# (optional) List of hosts which will be set as value of ALLOWED_HOSTS
# parameter in settings_local.py. This is used by Django for
# security reasons. Can be set to * in environments where security is
# deemed unimportant.
# Defaults to ::fqdn.
#
# [*server_aliases*]
# (optional) List of names which should be defined as ServerAlias directives
# in vhost.conf.
# Defaults to ::fqdn.
#
# [*package_ensure*]
# (optional) Package ensure state. Defaults to 'present'.
#
# [*cache_server_ip*]
# (optional) Memcached IP address. Can be a string, or an array.
# Defaults to '127.0.0.1'.
#
# [*cache_server_port*]
# (optional) Memcached port. Defaults to '11211'.
#
# [*swift*]
# (optional) Enable Swift interface extension. Defaults to false.
#
# [*horizon_app_links*]
# (optional) Array of arrays that can be used to add call-out links
# to the dashboard for other apps. There is no specific requirement
# for these apps to be for monitoring, that's just the defacto purpose.
# Each app is defined in two parts, the display name, and
# the URIDefaults to false. Defaults to false. (no app links)
#
# [*keystone_url*]
# (optional) Full url of keystone public endpoint. (Defaults to 'http://127.0.0.1:5000/v2.0')
# Use this parameter in favor of keystone_host, keystone_port and keystone_scheme.
#
# [*keystone_scheme*]
# (optional) DEPRECATED: Use keystone_url instead.
# Scheme of the Keystone service. (Defaults to 'http')
# Setting this parameter overrides keystone_url parameter.
#
# [*keystone_host*]
# (optional) DEPRECATED: Use keystone_url instead.
# IP address of the Keystone service. (Defaults to '127.0.0.1')
# Setting this parameter overrides keystone_url parameter.
#
# [*keystone_port*]
# (optional) DEPRECATED: Use keystone_url instead.
# Port of the Keystone service. (Defaults to 5000)
# Setting this parameter overrides keystone_url parameter.
#
# [*keystone_default_role*]
# (optional) Default Keystone role for new users. Defaults to '_member_'.
#
# [*django_debug*]
# (optional) Enable or disable Django debugging. Defaults to 'False'.
#
# [*openstack_endpoint_type*]
# (optional) endpoint type to use for the endpoints in the Keystone
# service catalog. Defaults to 'undef'.
#
# [*secondary_endpoint_type*]
# (optional) secondary endpoint type to use for the endpoints in the
# Keystone service catalog. Defaults to 'undef'.
#
# [*available_regions*]
# (optional) List of available regions. Value should be a list of tuple:
# [ ['urlOne', 'RegionOne'], ['urlTwo', 'RegionTwo'] ]
# Defaults to undef.
#
# [*api_result_limit*]
# (optional) Maximum number of Swift containers/objects to display
# on a single page. Defaults to 1000.
#
# [*log_level*]
# (optional) Log level. Defaults to 'INFO'. WARNING: Setting this to
# DEBUG will let plaintext passwords be logged in the Horizon log file.
#
# [*local_settings_template*]
# (optional) Location of template to use for local_settings.py generation.
# Defaults to 'horizon/local_settings.py.erb'.
#
# [*help_url*]
# (optional) Location where the documentation should point.
# Defaults to 'http://docs.openstack.org'.
#
# [*compress_offline*]
# (optional) Boolean to enable offline compress of assets.
# Defaults to True
#
# [*hypervisor_options*]
# (optional) A hash of parameters to enable features specific to
# Hypervisors. These include:
# 'can_set_mount_point': Boolean to enable or disable mount point setting
# Defaults to 'True'.
# 'can_set_password': Boolean to enable or disable VM password setting.
# Works only with Xen Hypervisor.
# Defaults to 'False'.
#
# [*neutron_options*]
# (optional) A hash of parameters to enable features specific to
# Neutron. These include:
# 'enable_lb': Boolean to enable or disable Neutron's LBaaS feature.
# Defaults to False.
# 'enable_firewall': Boolean to enable or disable Neutron's FWaaS feature.
# Defaults to False.
# 'enable_quotas': Boolean to enable or disable Neutron quotas.
# Defaults to True.
# 'enable_security_group': Boolean to enable or disable Neutron
# security groups. Defaults to True.
# 'enable_vpn': Boolean to enable or disable Neutron's VPNaaS feature.
# Defaults to False.
# 'profile_support': A string indiciating which plugin-specific
# profiles to enable. Defaults to 'None', other options include
# 'cisco'.
#
# [*configure_apache*]
# (optional) Configure Apache for Horizon. (Defaults to true)
#
# [*bind_address*]
# (optional) Bind address in Apache for Horizon. (Defaults to undef)
#
# [*listen_ssl*]
# (optional) Enable SSL support in Apache. (Defaults to false)
#
# [*ssl_redirect*]
# (optional) Whether to redirect http to https
# Defaults to True
#
# [*horizon_cert*]
# (required with listen_ssl) Certificate to use for SSL support.
#
# [*horizon_key*]
# (required with listen_ssl) Private key to use for SSL support.
#
# [*horizon_ca*]
# (required with listen_ssl) CA certificate to use for SSL support.
#
# [*vhost_extra_params*]
# (optionnal) extra parameter to pass to the apache::vhost class
# Defaults to undef
#
# [*file_upload_temp_dir*]
# (optional) Location to use for temporary storage of images uploaded
# You must ensure that the path leading to the directory is created
# already, only the last level directory is created by this manifest.
# Specify an absolute pathname.
# Defaults to /tmp
#
# [*secure_cookies*]
# (optional) Enables security settings for cookies. Useful when using
# https on public sites. See: http://docs.openstack.org/developer/horizon/topics/deployment.html#secure-site-recommendations
# Defaults to false
#
# [*django_session_engine*]
# (optional) Selects the session engine for Django to use.
# Defaults to undefined - will not add entry to local settings.
#
# === Deprecation notes
#
# If any value is provided for keystone_scheme, keystone_host, or
# keystone_port parameters; keystone_url will be completely ignored. Also
# can_set_mount_point is deprecated.
#
# === Examples
#
# class { 'horizon':
# secret => 's3cr3t',
# keystone_url => 'https://10.0.0.10:5000/v2.0',
# available_regions => [
# ['http://region-1.example.com:5000/v2.0', 'Region-1'],
# ['http://region-2.example.com:5000/v2.0', 'Region-2']
# ]
# }
#
class horizon(
$secret_key,
$bind_address = '127.0.0.1',
$cache_server_ip = '127.0.0.1',
$cache_server_port = '11211',
$swift = false,
$quantum = false,
$package_ensure = present,
$horizon_app_links = false,
$keystone_host = '127.0.0.1',
$keystone_port = 5000,
$keystone_scheme = 'http',
$keystone_default_role = '_member_',
$django_debug = false,
$django_verbose = false,
$api_result_limit = 1000,
$http_port = 80,
$https_port = 443,
$use_ssl = false,
$log_level = 'WARNING',
$use_syslog = false,
$fqdn = undef,
$package_ensure = 'present',
$cache_server_ip = '127.0.0.1',
$cache_server_port = '11211',
$swift = false,
$horizon_app_links = false,
$keystone_url = 'http://127.0.0.1:5000/v2.0',
$keystone_default_role = '_member_',
$django_debug = 'False',
$openstack_endpoint_type = undef,
$secondary_endpoint_type = undef,
$available_regions = undef,
$api_result_limit = 1000,
$log_level = 'INFO',
$help_url = 'http://docs.openstack.org',
$local_settings_template = 'horizon/local_settings.py.erb',
$configure_apache = true,
$bind_address = undef,
$servername = $::fqdn,
$server_aliases = $::fqdn,
$allowed_hosts = $::fqdn,
$listen_ssl = false,
$ssl_redirect = true,
$horizon_cert = undef,
$horizon_key = undef,
$horizon_ca = undef,
$compress_offline = true,
$hypervisor_options = {},
$neutron_options = {},
$file_upload_temp_dir = '/tmp',
$policy_files_path = undef,
$policy_files = undef,
# DEPRECATED PARAMETERS
$can_set_mount_point = undef,
$keystone_host = undef,
$keystone_port = undef,
$keystone_scheme = undef,
$vhost_extra_params = undef,
$secure_cookies = false,
$django_session_engine = undef,
) {
include horizon::params
include ::horizon::params
$root_url = $::horizon::params::root_url
$wsgi_user = $::horizon::params::apache_user
$wsgi_group = $::horizon::params::apache_group
package { [$::horizon::params::http_service,
$::horizon::params::http_modwsgi]:
ensure => present,
if $swift {
warning('swift parameter is deprecated and has no effect.')
}
package { 'dashboard':
name => $::horizon::params::package_name,
ensure => $package_ensure,
require => Package[$::horizon::params::http_service],
if $keystone_scheme {
warning('The keystone_scheme parameter is deprecated, use keystone_url instead.')
}
define horizon_safe_package(){
if ! defined(Package[$name]){
@package { $name : }
if $keystone_host {
warning('The keystone_host parameter is deprecated, use keystone_url instead.')
}
if $keystone_port {
warning('The keystone_port parameter is deprecated, use keystone_url instead.')
}
# Default options for the OPENSTACK_HYPERVISOR_FEATURES section. These will
# be merged with user-provided options when the local_settings.py.erb
# template is interpolated. Also deprecates can_set_mount_point.
if $can_set_mount_point {
warning('The can_set_mount_point parameter is deprecated, use hypervisor_options instead.')
$hypervisor_defaults = {
'can_set_mount_point' => $can_set_mount_point,
'can_set_password' => false
}
}
File {
require => Package['dashboard'],
owner => $wsgi_user,
group => $wsgi_group,
}
file { $::horizon::params::local_settings_path:
content => template('horizon/local_settings.py.erb'),
mode => '0644',
}
$dashboard_directory = '/usr/share/openstack-dashboard/'
file { $dashboard_directory :
ensure => directory,
}
exec { 'chown_dashboard' :
command => "chown -R ${wsgi_user}:${wsgi_group} ${dashboard_directory}",
path => [ '/usr/sbin', '/usr/bin', '/sbin', '/bin' ],
refreshonly => true,
provider => 'shell',
}
Package['dashboard'] -> File[$dashboard_directory] ~> Exec['chown_dashboard']
Exec['horizon_compress_styles'] -> Exec['chown_dashboard']
case $use_ssl {
'exist': { # SSL certificate already exists
$generate_sslcert_names = true
$inject_certs = false
}
'custom': { # custom signed certificate
$generate_sslcert_names = true
$inject_certs = true
}
'default': { # use default package certificate
$generate_sslcert_names = false
$inject_certs = false
}
}
if $generate_sslcert_names {
$sslcert_pair = regsubst([$::horizon::params::ssl_cert_file,
$::horizon::params::ssl_key_file],
'(.+\/).+(\..+)', "\\1${::domain}\\2")
$ssl_cert_file = $sslcert_pair[0]
$ssl_key_file = $sslcert_pair[1]
} else {
$ssl_cert_file = $::horizon::params::ssl_cert_file
$ssl_key_file = $::horizon::params::ssl_key_file
}
# inject signed certificate
if $inject_certs {
file { $ssl_cert_file:
ensure => present,
mode => '0644',
owner => 'root',
group => 'root',
source => "puppet:///ssl_certs/${::domain}.${::horizon::params::ssl_cert_type}",
}
file { $ssl_key_file:
ensure => present,
mode => '0640',
owner => 'root',
group => $::horizon::params::ssl_key_group,
source => "puppet:///ssl_certs/${::domain}.key",
$hypervisor_defaults = {
'can_set_mount_point' => true,
'can_set_password' => false
}
}
file { $horizon::params::logdir:
ensure => directory,
mode => '0750',
owner => $wsgi_user,
group => $wsgi_group,
} ->
file { "${horizon::params::logdir}/horizon.log":
ensure => present,
mode => '0640',
owner => $wsgi_user,
group => $wsgi_group,
if $fqdn {
warning('Parameter fqdn is deprecated. Please use parameter allowed_hosts for setting ALLOWED_HOSTS in settings_local.py and parameter server_aliases for setting ServerAlias directives in vhost.conf.')
$final_allowed_hosts = $fqdn
$final_server_aliases = $fqdn
} else {
$final_allowed_hosts = $allowed_hosts
$final_server_aliases = $server_aliases
}
Package["dashboard"] -> File[$horizon::params::logdir]
File["${horizon::params::logdir}/horizon.log"] -> Service['httpd']
file { $::horizon::params::vhosts_file:
content => template('horizon/vhosts.erb'),
# Default options for the OPENSTACK_NEUTRON_NETWORK section. These will
# be merged with user-provided options when the local_settings.py.erb
# template is interpolated.
$neutron_defaults = {
'enable_lb' => false,
'enable_firewall' => false,
'enable_quotas' => true,
'enable_security_group' => true,
'enable_vpn' => false,
'profile_support' => 'None'
}
Service <| title == 'memcached' |> -> Class['horizon']
package { 'horizon':
ensure => $package_ensure,
name => $::horizon::params::package_name,
}
file { $::horizon::params::config_file:
content => template($local_settings_template),
mode => '0644',
require => Package['dashboard'],
notify => Service['httpd']
require => Package['horizon'],
}
file { $::horizon::params::dashboard_http_conf_file:
content => template('horizon/openstack-dashboard.conf.erb'),
mode => '0644',
notify => Service['httpd'],
require => [
Package['dashboard'],
File[$::horizon::params::apache_confdir]
]
package { 'python-lesscpy':
ensure => $package_ensure,
}
file { $::horizon::params::apache_tuning_file:
content => template('horizon/zzz_performance_tuning.conf.erb'),
mode => '0644',
notify => Service['httpd'],
require => [
Package['dashboard'],
File[$::horizon::params::apache_confdir]
]
exec { 'refresh_horizon_django_cache':
command => "${::horizon::params::manage_py} compress",
refreshonly => true,
require => [Package['python-lesscpy'], Package['horizon']],
}
file { 'httpd_listen_config_file':
path => $::horizon::params::httpd_listen_config_file,
content => template('horizon/ports.conf.erb'),
owner => 'root',
group => 'root',
notify => Service['httpd'],
before => Package[$::horizon::params::http_service],
require => File[$::horizon::params::apache_confdir]
if $compress_offline {
File[$::horizon::params::config_file] ~> Exec['refresh_horizon_django_cache']
}
file { $::horizon::params::apache_confdir:
ensure => directory,
owner => 'root',
group => 'root',
require => []
}
case $::osfamily {
'RedHat': {
package { $::horizon::params::horizon_additional_packages : ensure => present }
file { '/etc/httpd/conf.d/wsgi.conf':
mode => 644,
owner => root,
group => root,
content => "LoadModule wsgi_module modules/mod_wsgi.so\n",
require => Package[$::horizon::params::http_service,
$::horizon::params::http_modwsgi],
before => Package['dashboard'],
} # ensure there is a HTTP redirect from / to /dashboard
if $use_ssl =~ /^(default|exist|custom)$/ {
package { 'mod_ssl':
ensure => present,
before => Service['httpd'],
}
}
file { '/etc/sysconfig/httpd':
mode => 0644,
owner => root,
group => root,
content => template('horizon/redhat_sysconfig_httpd.erb'),
require => Package[$::horizon::params::http_service],
notify => Service['httpd'],
}
augeas { 'remove_listen_directive':
context => "/files/etc/httpd/conf/httpd.conf",
changes => [
"rm directive[. = 'Listen']"
],
before => Service['httpd'],
}
Package[$::horizon::params::horizon_additional_packages] -> Exec['horizon_compress_styles']
}
'Debian': {
A2mod {
ensure => present,
require => Package[$::horizon::params::http_service],
before => Package['dashboard'],
notify => Service['httpd'],
}
a2mod { 'wsgi':
require => Package[$::horizon::params::http_modwsgi]
}
if $use_ssl =~ /^(default|exist|custom)$/ {
a2mod { ['rewrite', 'ssl']: }
}
file { '/etc/apache2/sites-enabled/openstack-dashboard':
ensure => link,
target => $::horizon::params::vhosts_file,
}
file { '/etc/apache2/sites-enabled/000-default':
ensure => absent,
before => Service['httpd'],
}
if $configure_apache {
class { 'horizon::wsgi::apache':
bind_address => $bind_address,
servername => $servername,
server_aliases => $final_server_aliases,
listen_ssl => $listen_ssl,
ssl_redirect => $ssl_redirect,
horizon_cert => $horizon_cert,
horizon_key => $horizon_key,
horizon_ca => $horizon_ca,
extra_params => $vhost_extra_params,
}
}
Package['dashboard'] -> Exec['horizon_compress_styles']
Package['dashboard'] ~> Exec['horizon_compress_styles']
File[$::horizon::params::local_settings_path] -> Exec['horizon_compress_styles']
exec { 'horizon_compress_styles':
path => '/bin:/usr/bin:/sbin:/usr/sbin',
cwd => '/usr/share/openstack-dashboard',
command => 'python manage.py compress',
refreshonly => true
}
Exec['horizon_compress_styles'] ~> Service['httpd']
service { 'httpd':
name => $::horizon::params::http_service,
ensure => 'running',
enable => true
}
File[$::horizon::params::local_settings_path, $::horizon::params::logdir] ~> Service['httpd']
Package[$::horizon::params::http_service, $::horizon::params::http_modwsgi] -> Service['httpd']
Package<| title == $::horizon::params::http_service or title == $::horizon::params::http_modwsgi|> ~>
Service<| title == 'httpd'|>
if !defined(Service['httpd']) {
notify{ "Module ${module_name} cannot notify service httpd on packages update": }
if ! ($file_upload_temp_dir in ['/tmp','/var/tmp']) {
file { $file_upload_temp_dir :
ensure => directory,
owner => $::horizon::params::wsgi_user,
group => $::horizon::params::wsgi_group,
mode => '0755'
}
}
if $cache_server_ip =~ /^127\.0\.0\.1/ {
Class['memcached'] -> Class['horizon']
}
}

View File

@ -2,50 +2,40 @@
# should be considered to be constant
class horizon::params {
$logdir = '/var/log/horizon'
$logdir = '/var/log/horizon'
$django_wsgi = '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi'
$manage_py = '/usr/share/openstack-dashboard/manage.py'
case $::osfamily {
'RedHat': {
$http_service = 'httpd'
$vhosts_file = '/etc/httpd/conf.d/ssl.conf'
$http_modwsgi = 'mod_wsgi'
$package_name = 'openstack-dashboard'
$horizon_additional_packages = ['nodejs', 'nodejs-less', 'python-lesscpy']
$httpd_listen_config_file = '/etc/httpd/conf.d/ports.conf'
$local_settings_path = '/etc/openstack-dashboard/local_settings'
$root_url = '/dashboard'
$apache_user = 'apache'
$apache_group = 'apache'
$apache_confdir = ['/etc/httpd', '/etc/httpd/conf.d']
$ssl_key_group = 'root'
$ssl_cert_file = '/etc/pki/tls/certs/localhost.crt'
$ssl_key_file = '/etc/pki/tls/private/localhost.key'
$ssl_cert_type = 'crt'
$dashboard_http_conf_file = '/etc/httpd/conf.d/openstack-dashboard.conf'
$apache_tuning_file = '/etc/httpd/conf.d/zzz_performance_tuning.conf'
$http_service = 'httpd'
$http_modwsgi = 'mod_wsgi'
$package_name = 'openstack-dashboard'
$config_file = '/etc/openstack-dashboard/local_settings'
$httpd_config_file = '/etc/httpd/conf.d/openstack-dashboard.conf'
$httpd_listen_config_file = '/etc/httpd/conf/httpd.conf'
$root_url = '/dashboard'
$apache_user = 'apache'
$apache_group = 'apache'
$wsgi_user = 'dashboard'
$wsgi_group = 'dashboard'
}
'Debian': {
$http_service = 'apache2'
$vhosts_file = '/etc/apache2/sites-available/openstack-dashboard.conf'
$local_settings_path = '/etc/openstack-dashboard/local_settings.py'
$httpd_listen_config_file = '/etc/apache2/ports.conf'
$http_modwsgi = 'libapache2-mod-wsgi'
$root_url = '/horizon'
$apache_user = 'horizon'
$apache_group = 'horizon'
$apache_confdir = '/etc/apache2'
$ssl_key_group = 'ssl-cert'
$ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
$ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
$ssl_cert_type = 'pem'
$dashboard_http_conf_file = '/etc/apache2/conf-available/openstack-dashboard.conf'
$apache_tuning_file = '/etc/apache2/conf.d/zzz_performance_tuning.conf'
$http_service = 'apache2'
$config_file = '/etc/openstack-dashboard/local_settings.py'
$httpd_config_file = '/etc/apache2/conf-available/openstack-dashboard.conf'
$httpd_listen_config_file = '/etc/apache2/ports.conf'
$root_url = '/horizon'
$apache_user = 'www-data'
$apache_group = 'www-data'
$wsgi_user = 'horizon'
$wsgi_group = 'horizon'
case $::operatingsystem {
'Debian': {
$package_name = 'openstack-dashboard-apache'
$package_name = 'openstack-dashboard-apache'
}
default: {
$package_name = 'openstack-dashboard'
$package_name = 'openstack-dashboard'
}
}
}
@ -53,5 +43,4 @@ class horizon::params {
fail("Unsupported osfamily: ${::osfamily} operatingsystem: ${::operatingsystem}, module ${module_name} only support osfamily RedHat and Debian")
}
}
}

View File

@ -0,0 +1,199 @@
# == Class: horizon::wsgi::apache
#
# Configures Apache WSGI for Horizon.
#
# === Parameters
#
# [*bind_address*]
# (optional) Bind address in Apache for Horizon. (Defaults to '0.0.0.0')
#
# [*server_aliases*]
# (optional) List of names which should be defined as ServerAlias directives
# in vhost.conf.
# Defaults to ::fqdn.
#
# [*listen_ssl*]
# (optional) Enable SSL support in Apache. (Defaults to false)
#
# [*horizon_cert*]
# (required with listen_ssl) Certificate to use for SSL support.
#
# [*horizon_key*]
# (required with listen_ssl) Private key to use for SSL support.
#
# [*horizon_ca*]
# (required with listen_ssl) CA certificate to use for SSL support.
#
# [*wsgi_processes*]
# (optional) Number of Horizon processes to spawn
# Defaults to '3'
#
# [*wsgi_threads*]
# (optional) Number of thread to run in a Horizon process
# Defaults to '10'
#
# [*priority*]
# (optional) The apache vhost priority.
# Defaults to '15'. To set Horizon as the primary vhost, change to '10'.
#
# [*extra_params*]
# (optional) A hash of extra paramaters for apache::wsgi class.
# Defaults to {}
class horizon::wsgi::apache (
$bind_address = undef,
$fqdn = undef,
$servername = $::fqdn,
$server_aliases = $::fqdn,
$listen_ssl = false,
$ssl_redirect = true,
$horizon_cert = undef,
$horizon_key = undef,
$horizon_ca = undef,
$wsgi_processes = '3',
$wsgi_threads = '10',
$priority = '15',
$vhost_conf_name = 'horizon_vhost',
$vhost_ssl_conf_name = 'horizon_ssl_vhost',
$extra_params = {},
) {
include ::horizon::params
include ::apache
if $fqdn {
warning('Parameter fqdn is deprecated. Please use parameter server_aliases for setting ServerAlias directives in vhost.conf.')
$final_server_aliases = $fqdn
} else {
$final_server_aliases = $server_aliases
}
include ::apache::mod::wsgi
# We already use apache::vhost to generate our own
# configuration file, let's clean the configuration
# embedded within the package
file { $::horizon::params::httpd_config_file:
ensure => present,
content => "#
# This file has been cleaned by Puppet.
#
# OpenStack Horizon configuration has been moved to:
# - ${priority}-${vhost_conf_name}.conf
# - ${priority}-${vhost_ssl_conf_name}.conf
#",
require => Package[$::horizon::params::package_name]
}
if $listen_ssl {
include ::apache::mod::ssl
$ensure_ssl_vhost = 'present'
if $horizon_ca == undef {
fail('The horizon_ca parameter is required when listen_ssl is true')
}
if $horizon_cert == undef {
fail('The horizon_cert parameter is required when listen_ssl is true')
}
if $horizon_key == undef {
fail('The horizon_key parameter is required when listen_ssl is true')
}
if $ssl_redirect {
$redirect_match = '(.*)'
$redirect_url = "https://${servername}"
}
} else {
$ensure_ssl_vhost = 'absent'
$redirect_match = '^/$'
$redirect_url = $::horizon::params::root_url
}
Package['horizon'] -> Package[$::horizon::params::http_service]
File[$::horizon::params::config_file] ~> Service[$::horizon::params::http_service]
$unix_user = $::osfamily ? {
'RedHat' => $::horizon::params::apache_user,
default => $::horizon::params::wsgi_user
}
$unix_group = $::osfamily ? {
'RedHat' => $::horizon::params::apache_group,
default => $::horizon::params::wsgi_group,
}
file { $::horizon::params::logdir:
ensure => directory,
owner => $unix_user,
group => $unix_group,
before => Service[$::horizon::params::http_service],
mode => '0751',
require => Package['horizon']
}
file { "${::horizon::params::logdir}/horizon.log":
ensure => file,
owner => $unix_user,
group => $unix_group,
before => Service[$::horizon::params::http_service],
mode => '0640',
require => [ File[$::horizon::params::logdir], Package['horizon'] ],
}
$default_vhost_conf_no_ip = {
servername => $servername,
serveraliases => os_any2array($final_server_aliases),
docroot => '/var/www/',
access_log_file => 'horizon_access.log',
error_log_file => 'horizon_error.log',
priority => $priority,
aliases => [
{ alias => '/static', path => '/usr/share/openstack-dashboard/static' }
],
port => 80,
ssl_cert => $horizon_cert,
ssl_key => $horizon_key,
ssl_ca => $horizon_ca,
wsgi_script_aliases => hash([$::horizon::params::root_url, $::horizon::params::django_wsgi]),
wsgi_daemon_process => $::horizon::params::wsgi_group,
wsgi_daemon_process_options => {
processes => $wsgi_processes,
threads => $wsgi_threads,
user => $unix_user,
group => $unix_group,
},
wsgi_import_script => $::horizon::params::django_wsgi,
wsgi_process_group => $::horizon::params::wsgi_group,
redirectmatch_status => 'permanent',
}
# Only add the 'ip' element to the $default_vhost_conf hash if it was explicitly
# specified in the instantiation of the class. This is because ip => undef gets
# changed to ip => '' via the Puppet function API when ensure_resource is called.
# See https://bugs.launchpad.net/puppet-horizon/+bug/1371345
if $bind_address {
$default_vhost_conf = merge($default_vhost_conf_no_ip, { ip => $bind_address })
} else {
$default_vhost_conf = $default_vhost_conf_no_ip
}
ensure_resource('apache::vhost', $vhost_conf_name, merge ($default_vhost_conf, $extra_params, {
redirectmatch_regexp => $redirect_match,
redirectmatch_dest => $redirect_url,
}))
ensure_resource('apache::vhost', $vhost_ssl_conf_name, merge ($default_vhost_conf, $extra_params, {
access_log_file => 'horizon_ssl_access.log',
error_log_file => 'horizon_ssl_error.log',
priority => $priority,
ssl => true,
port => 443,
ensure => $ensure_ssl_vhost,
wsgi_daemon_process => 'horizon-ssl',
wsgi_process_group => 'horizon-ssl',
redirectmatch_regexp => '^/$',
redirectmatch_dest => $::horizon::params::root_url,
}))
}

View File

@ -0,0 +1,38 @@
{
"name": "stackforge-horizon",
"version": "5.0.0",
"author": "Puppet Labs and StackForge Contributors",
"summary": "Puppet module for OpenStack Horizon",
"license": "Apache License 2.0",
"source": "git://github.com/stackforge/puppet-horizon.git",
"project_page": "https://launchpad.net/puppet-horizon",
"issues_url": "https://bugs.launchpad.net/puppet-horizon",
"requirements": [
{ "name": "pe","version_requirement": "3.x" },
{ "name": "puppet","version_requirement": "3.x" }
],
"operatingsystem_support": [
{
"operatingsystem": "Debian",
"operatingsystemrelease": ["7"]
},
{
"operatingsystem": "Fedora",
"operatingsystemrelease": ["20"]
},
{
"operatingsystem": "RedHat",
"operatingsystemrelease": ["6.5","7"]
},
{
"operatingsystem": "Ubuntu",
"operatingsystemrelease": ["12.04","14.04"]
}
],
"description": "Installs and configures OpenStack Horizon (Dashboard).",
"dependencies": [
{ "name": "puppetlabs/apache", "version_requirement": ">=1.2.0 <2.0.0" },
{ "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" },
{ "name": "saz/memcached", "version_requirement": ">=2.0.2 <3.0.0" }
]
}

View File

@ -1,65 +1,330 @@
require 'spec_helper'
describe 'horizon' do
let :params do
{
'cache_server_ip' => '10.0.0.1',
'secret_key' => 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'
{ 'secret_key' => 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0',
'fqdn' => '*' }
end
let :pre_condition do
'include apache'
end
let :fixtures_path do
File.expand_path(File.join(__FILE__, '..', '..', 'fixtures'))
end
let :facts do
{ :concat_basedir => '/var/lib/puppet/concat',
:fqdn => 'some.host.tld'
}
end
describe 'when running on redhat' do
let :facts do
{
'osfamily' => 'RedHat'
shared_examples 'horizon' do
context 'with default parameters' do
it {
should contain_package('python-lesscpy').with_ensure('present')
should contain_package('horizon').with_ensure('present')
}
end
it { should contain_exec('refresh_horizon_django_cache').with({
:command => '/usr/share/openstack-dashboard/manage.py compress',
:refreshonly => true,
})}
it { should contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') }
it {
should contain_service('httpd').with_name('httpd')
}
end
describe 'when running on debian' do
let :facts do
{
'osfamily' => 'Debian'
}
end
it {
should contain_service('httpd').with_name('apache2')
}
describe 'with default parameters' do
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_HOST = "127.0.0.1"$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_KEYSTONE_URL = "http:\/\/%s:5000\/v2.0" % OPENSTACK_HOST$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^DEBUG = False$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^API_RESULT_LIMIT = 1000$/) }
end
describe 'when overriding parameters' do
let :params do
{
:secret_key => 'dummy',
:cache_server_ip => '10.0.0.1',
:keystone_host => 'keystone.example.com',
:keystone_port => 4682,
:keystone_scheme => 'https',
:keystone_default_role => 'SwiftOperator',
:django_debug => true,
:api_result_limit => 4682,
}
it 'configures apache' do
should contain_class('horizon::wsgi::apache').with({
:servername => 'some.host.tld',
:listen_ssl => false,
:servername => 'some.host.tld',
:extra_params => {},
})
end
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^SECRET_KEY = 'dummy'$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_HOST = "keystone.example.com"$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_KEYSTONE_URL = "https:\/\/%s:4682\/v2.0" % OPENSTACK_HOST$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^OPENSTACK_KEYSTONE_DEFAULT_ROLE = "SwiftOperator"$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^DEBUG = True$/) }
it { should contain_file('/etc/openstack-dashboard/local_settings.py').with_content(/^API_RESULT_LIMIT = 4682$/) }
it 'generates local_settings.py' do
verify_contents(subject, platforms_params[:config_file], [
'DEBUG = False',
"ALLOWED_HOSTS = ['*', ]",
"SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'",
'OPENSTACK_KEYSTONE_URL = "http://127.0.0.1:5000/v2.0"',
'OPENSTACK_KEYSTONE_DEFAULT_ROLE = "_member_"',
" 'can_set_mount_point': True,",
" 'can_set_password': False,",
" 'enable_lb': False,",
" 'enable_firewall': False,",
" 'enable_quotas': True,",
" 'enable_security_group': True,",
" 'enable_vpn': False,",
'API_RESULT_LIMIT = 1000',
"LOGIN_URL = '#{platforms_params[:root_url]}/auth/login/'",
"LOGOUT_URL = '#{platforms_params[:root_url]}/auth/logout/'",
"LOGIN_REDIRECT_URL = '#{platforms_params[:root_url]}'",
'COMPRESS_OFFLINE = True',
"FILE_UPLOAD_TEMP_DIR = '/tmp'"
])
# From internals of verify_contents, get the contents to check for absence of a line
content = subject.resource('file', platforms_params[:config_file]).send(:parameters)[:content]
# With default options, should _not_ have a line to configure SESSION_ENGINE
content.should_not match(/^SESSION_ENGINE/)
end
it { should_not contain_file(params[:file_upload_temp_dir]) }
end
context 'with overridden parameters' do
before do
params.merge!({
:cache_server_ip => '10.0.0.1',
:django_session_engine => 'django.contrib.sessions.backends.cache',
:keystone_default_role => 'SwiftOperator',
:keystone_url => 'https://keystone.example.com:4682',
:openstack_endpoint_type => 'internalURL',
:secondary_endpoint_type => 'ANY-VALUE',
:django_debug => true,
:api_result_limit => 4682,
:compress_offline => false,
:hypervisor_options => {'can_set_mount_point' => false, 'can_set_password' => true },
:neutron_options => {'enable_lb' => true, 'enable_firewall' => true, 'enable_quotas' => false, 'enable_security_group' => false, 'enable_vpn' => true, 'profile_support' => 'cisco' },
:file_upload_temp_dir => '/var/spool/horizon',
:secure_cookies => true
})
end
it 'generates local_settings.py' do
verify_contents(subject, platforms_params[:config_file], [
'DEBUG = True',
"ALLOWED_HOSTS = ['*', ]",
'CSRF_COOKIE_SECURE = True',
'SESSION_COOKIE_SECURE = True',
"SECRET_KEY = 'elj1IWiLoWHgcyYxFVLj7cM5rGOOxWl0'",
" 'LOCATION': '10.0.0.1:11211',",
'SESSION_ENGINE = "django.contrib.sessions.backends.cache"',
'OPENSTACK_KEYSTONE_URL = "https://keystone.example.com:4682"',
'OPENSTACK_KEYSTONE_DEFAULT_ROLE = "SwiftOperator"',
" 'can_set_mount_point': False,",
" 'can_set_password': True,",
" 'enable_lb': True,",
" 'enable_firewall': True,",
" 'enable_quotas': False,",
" 'enable_security_group': False,",
" 'enable_vpn': True,",
" 'profile_support': 'cisco',",
'OPENSTACK_ENDPOINT_TYPE = "internalURL"',
'SECONDARY_ENDPOINT_TYPE = "ANY-VALUE"',
'API_RESULT_LIMIT = 4682',
'COMPRESS_OFFLINE = False',
"FILE_UPLOAD_TEMP_DIR = '/var/spool/horizon'"
])
end
it { should_not contain_file(platforms_params[:config_file]).that_notifies('Exec[refresh_horizon_django_cache]') }
it { should contain_file(params[:file_upload_temp_dir]) }
end
context 'with overridden parameters and cache_server_ip array' do
before do
params.merge!({
:cache_server_ip => ['10.0.0.1','10.0.0.2'],
})
end
it 'generates local_settings.py' do
verify_contents(subject, platforms_params[:config_file], [
" 'LOCATION': [ '10.0.0.1:11211','10.0.0.2:11211', ],",
])
end
it { should contain_exec('refresh_horizon_django_cache') }
end
context 'with deprecated parameters' do
before do
params.merge!({
:keystone_host => 'keystone.example.com',
:keystone_port => 4682,
:keystone_scheme => 'https',
:can_set_mount_point => true,
})
end
it 'generates local_settings.py' do
verify_contents(subject, platforms_params[:config_file], [
'OPENSTACK_KEYSTONE_URL = "https://keystone.example.com:4682/v2.0"',
" 'can_set_mount_point': True,"
])
end
end
context 'with vhost_extra_params' do
before do
params.merge!({
:vhost_extra_params => { 'add_listen' => false },
})
end
it 'configures apache' do
should contain_class('horizon::wsgi::apache').with({
:extra_params => { 'add_listen' => false },
})
end
end
context 'with ssl enabled' do
before do
params.merge!({
:listen_ssl => true,
:servername => 'some.host.tld',
:horizon_cert => '/etc/pki/tls/certs/httpd.crt',
:horizon_key => '/etc/pki/tls/private/httpd.key',
:horizon_ca => '/etc/pki/tls/certs/ca.crt',
})
end
it 'configures apache' do
should contain_class('horizon::wsgi::apache').with({
:bind_address => nil,
:listen_ssl => true,
:horizon_cert => '/etc/pki/tls/certs/httpd.crt',
:horizon_key => '/etc/pki/tls/private/httpd.key',
:horizon_ca => '/etc/pki/tls/certs/ca.crt',
})
end
end
context 'without apache' do
before do
params.merge!({ :configure_apache => false })
end
it 'does not configure apache' do
should_not contain_class('horizon::wsgi::apache')
end
end
context 'with available_regions parameter' do
before do
params.merge!({
:available_regions => [
['http://region-1.example.com:5000/v2.0', 'Region-1'],
['http://region-2.example.com:5000/v2.0', 'Region-2']
]
})
end
it 'AVAILABLE_REGIONS is configured' do
verify_contents(subject, platforms_params[:config_file], [
"AVAILABLE_REGIONS = [",
" ('http://region-1.example.com:5000/v2.0', 'Region-1'),",
" ('http://region-2.example.com:5000/v2.0', 'Region-2'),",
"]"
])
end
end
context 'with policy parameters' do
before do
params.merge!({
:policy_files_path => '/opt/openstack-dashboard',
:policy_files => {
'identity' => 'keystone_policy.json',
'compute' => 'nova_policy.json',
'network' => 'neutron_policy.json',
}
})
end
it 'POLICY_FILES_PATH and POLICY_FILES are configured' do
verify_contents(subject, platforms_params[:config_file], [
"POLICY_FILES_PATH = '/opt/openstack-dashboard'",
"POLICY_FILES = {",
" 'identity': 'keystone_policy.json',",
" 'compute': 'nova_policy.json',",
" 'network': 'neutron_policy.json',",
"} # POLICY_FILES"
])
end
end
context 'with overriding local_settings_template' do
before do
params.merge!({
:django_debug => 'True',
:help_url => 'https://docs.openstack.org',
:local_settings_template => fixtures_path + '/override_local_settings.py.erb'
})
end
it 'uses the custom local_settings.py template' do
verify_contents(subject, platforms_params[:config_file], [
'# Custom local_settings.py',
'DEBUG = True',
"HORIZON_CONFIG = {",
" 'dashboards': ('project', 'admin', 'settings',),",
" 'default_dashboard': 'project',",
" 'user_home': 'openstack_dashboard.views.get_user_home',",
" 'ajax_queue_limit': 10,",
" 'auto_fade_alerts': {",
" 'delay': 3000,",
" 'fade_duration': 1500,",
" 'types': ['alert-success', 'alert-info']",
" },",
" 'help_url': \"https://docs.openstack.org\",",
" 'exceptions': {'recoverable': exceptions.RECOVERABLE,",
" 'not_found': exceptions.NOT_FOUND,",
" 'unauthorized': exceptions.UNAUTHORIZED},",
"}",
])
end
end
context 'with /var/tmp as upload temp dir' do
before do
params.merge!({
:file_upload_temp_dir => '/var/tmp'
})
end
it { should_not contain_file(params[:file_upload_temp_dir]) }
end
end
context 'on RedHat platforms' do
before do
facts.merge!({
:osfamily => 'RedHat',
:operatingsystemrelease => '6.0'
})
end
let :platforms_params do
{ :config_file => '/etc/openstack-dashboard/local_settings',
:package_name => 'openstack-dashboard',
:root_url => '/dashboard' }
end
it_behaves_like 'horizon'
end
context 'on Debian platforms' do
before do
facts.merge!({
:osfamily => 'Debian',
:operatingsystemrelease => '6.0'
})
end
let :platforms_params do
{ :config_file => '/etc/openstack-dashboard/local_settings.py',
:package_name => 'openstack-dashboard-apache',
:root_url => '/horizon' }
end
it_behaves_like 'horizon'
end
end

View File

@ -0,0 +1,230 @@
require 'spec_helper'
describe 'horizon::wsgi::apache' do
let :params do
{ :fqdn => '*',
:servername => 'some.host.tld',
:wsgi_processes => '3',
:wsgi_threads => '10',
}
end
let :pre_condition do
"include apache\n" +
"class { 'horizon': secret_key => 's3cr3t', configure_apache => false }"
end
let :fixtures_path do
File.expand_path(File.join(__FILE__, '..', '..', 'fixtures'))
end
let :facts do
{ :concat_basedir => '/var/lib/puppet/concat',
:fqdn => 'some.host.tld'
}
end
shared_examples 'apache for horizon' do
context 'with default parameters' do
it 'configures apache' do
should contain_class('horizon::params')
should contain_class('apache')
should contain_class('apache::mod::wsgi')
should contain_service('httpd').with_name(platforms_params[:http_service])
should contain_file(platforms_params[:httpd_config_file])
should contain_package('horizon').with_ensure('present')
should contain_apache__vhost('horizon_vhost').with(
'servername' => 'some.host.tld',
'access_log_file' => 'horizon_access.log',
'error_log_file' => 'horizon_error.log',
'priority' => '15',
'serveraliases' => '*',
'docroot' => '/var/www/',
'ssl' => 'false',
'redirectmatch_status' => 'permanent',
'redirectmatch_regexp' => '^/$',
'redirectmatch_dest' => platforms_params[:root_url],
'wsgi_script_aliases' => { platforms_params[:root_url] => '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi' },
'wsgi_process_group' => platforms_params[:wsgi_group],
'wsgi_daemon_process' => platforms_params[:wsgi_group],
'wsgi_daemon_process_options' => { 'processes' => params[:wsgi_processes], 'threads' => params[:wsgi_threads], 'user' => platforms_params[:unix_user], 'group' => platforms_params[:unix_group] }
)
end
end
context 'with overriden parameters' do
before do
params.merge!({
:priority => '10',
})
end
it 'configures apache' do
should contain_class('horizon::params')
should contain_class('apache')
should contain_class('apache::mod::wsgi')
should contain_service('httpd').with_name(platforms_params[:http_service])
should contain_file(platforms_params[:httpd_config_file])
should contain_package('horizon').with_ensure('present')
should contain_apache__vhost('horizon_vhost').with(
'servername' => 'some.host.tld',
'access_log_file' => 'horizon_access.log',
'error_log_file' => 'horizon_error.log',
'priority' => params[:priority],
'serveraliases' => '*',
'docroot' => '/var/www/',
'ssl' => 'false',
'redirectmatch_status' => 'permanent',
'redirectmatch_regexp' => '^/$',
'redirectmatch_dest' => platforms_params[:root_url],
'wsgi_script_aliases' => { platforms_params[:root_url] => '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi' },
'wsgi_process_group' => platforms_params[:wsgi_group],
'wsgi_daemon_process' => platforms_params[:wsgi_group],
'wsgi_daemon_process_options' => { 'processes' => params[:wsgi_processes], 'threads' => params[:wsgi_threads], 'user' => platforms_params[:unix_user], 'group' => platforms_params[:unix_group] }
)
end
end
context 'with ssl enabled' do
before do
params.merge!({
:listen_ssl => true,
:ssl_redirect => true,
:horizon_cert => '/etc/pki/tls/certs/httpd.crt',
:horizon_key => '/etc/pki/tls/private/httpd.key',
:horizon_ca => '/etc/pki/tls/certs/ca.crt',
})
end
context 'with required parameters' do
it 'configures apache for SSL' do
should contain_class('apache::mod::ssl')
end
it { should contain_apache__vhost('horizon_ssl_vhost').with(
'servername' => 'some.host.tld',
'access_log_file' => 'horizon_ssl_access.log',
'error_log_file' => 'horizon_ssl_error.log',
'priority' => '15',
'serveraliases' => '*',
'docroot' => '/var/www/',
'ssl' => 'true',
'ssl_cert' => '/etc/pki/tls/certs/httpd.crt',
'ssl_key' => '/etc/pki/tls/private/httpd.key',
'ssl_ca' => '/etc/pki/tls/certs/ca.crt',
'redirectmatch_status' => 'permanent',
'redirectmatch_regexp' => '^/$',
'redirectmatch_dest' => platforms_params[:root_url],
'wsgi_process_group' => 'horizon-ssl',
'wsgi_daemon_process' => 'horizon-ssl',
'wsgi_script_aliases' => { platforms_params[:root_url] => '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi' }
)}
it { should contain_apache__vhost('horizon_vhost').with(
'servername' => 'some.host.tld',
'access_log_file' => 'horizon_access.log',
'error_log_file' => 'horizon_error.log',
'priority' => '15',
'serveraliases' => '*',
'docroot' => '/var/www/',
'ssl' => 'false',
'redirectmatch_status' => 'permanent',
'redirectmatch_regexp' => '(.*)',
'redirectmatch_dest' => 'https://some.host.tld',
'wsgi_process_group' => platforms_params[:wsgi_group],
'wsgi_daemon_process' => platforms_params[:wsgi_group],
'wsgi_script_aliases' => { platforms_params[:root_url] => '/usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi' }
)}
end
context 'without required parameters' do
context 'without horizon_ca parameter' do
before { params.delete(:horizon_ca) }
it_raises 'a Puppet::Error', /The horizon_ca parameter is required when listen_ssl is true/
end
context 'without horizon_cert parameter' do
before { params.delete(:horizon_cert) }
it_raises 'a Puppet::Error', /The horizon_cert parameter is required when listen_ssl is true/
end
context 'without horizon_key parameter' do
before { params.delete(:horizon_key) }
it_raises 'a Puppet::Error', /The horizon_key parameter is required when listen_ssl is true/
end
end
context 'with extra parameters' do
before do
params.merge!({
:extra_params => {
'add_listen' => false,
'docroot' => '/tmp'
},
})
end
it 'configures apache' do
should contain_apache__vhost('horizon_vhost').with(
'add_listen' => false,
'docroot' => '/tmp'
)
end
end
end
end
context 'on RedHat platforms' do
before do
facts.merge!({
:osfamily => 'RedHat',
:operatingsystemrelease => '6.0'
})
end
let :platforms_params do
{ :http_service => 'httpd',
:httpd_config_file => '/etc/httpd/conf.d/openstack-dashboard.conf',
:root_url => '/dashboard',
:apache_user => 'apache',
:apache_group => 'apache',
:wsgi_user => 'dashboard',
:wsgi_group => 'dashboard',
:unix_user => 'apache',
:unix_group => 'apache' }
end
it_behaves_like 'apache for horizon'
it {
should contain_class('apache::mod::wsgi').with(:wsgi_socket_prefix => '/var/run/wsgi')
}
end
context 'on Debian platforms' do
before do
facts.merge!({
:osfamily => 'Debian',
:operatingsystemrelease => '6.0'
})
end
let :platforms_params do
{ :http_service => 'apache2',
:httpd_config_file => '/etc/apache2/conf-available/openstack-dashboard.conf',
:root_url => '/horizon',
:apache_user => 'www-data',
:apache_group => 'www-data',
:wsgi_user => 'horizon',
:wsgi_group => 'horizon',
:unix_user => 'horizon',
:unix_group => 'horizon' }
end
it_behaves_like 'apache for horizon'
end
end

View File

@ -0,0 +1,18 @@
# Custom local_settings.py
DEBUG = <%= @django_debug %>
HORIZON_CONFIG = {
'dashboards': ('project', 'admin', 'settings',),
'default_dashboard': 'project',
'user_home': 'openstack_dashboard.views.get_user_home',
'ajax_queue_limit': 10,
'auto_fade_alerts': {
'delay': 3000,
'fade_duration': 1500,
'types': ['alert-success', 'alert-info']
},
'help_url': "<%= @help_url %>",
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
}

View File

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

View File

@ -1 +1,7 @@
require 'puppetlabs_spec_helper/module_spec_helper'
require 'shared_examples'
RSpec.configure do |c|
c.alias_it_should_behave_like_to :it_configures, 'configures'
c.alias_it_should_behave_like_to :it_raises, 'raises'
end

View File

@ -0,0 +1,55 @@
#! /usr/bin/env ruby -S rspec
require 'spec_helper'
describe "the os_any2array function" do
let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
it "should exist" do
Puppet::Parser::Functions.function("os_any2array").should == "function_os_any2array"
end
it "should return an empty array if there is less than 1 argument" do
result = scope.function_os_any2array([])
result.should(eq([]))
end
it "should convert boolean true to [ true ] " do
result = scope.function_os_any2array([true])
result.should(eq([true]))
end
it "should convert one object to [object]" do
result = scope.function_os_any2array(['one'])
result.should(eq(['one']))
end
it "should convert multiple objects to [objects]" do
result = scope.function_os_any2array(['one', 'two'])
result.should(eq(['one', 'two']))
end
it "should return empty array it was called with" do
result = scope.function_os_any2array([[]])
result.should(eq([]))
end
it "should return one-member array it was called with" do
result = scope.function_os_any2array([['string']])
result.should(eq(['string']))
end
it "should return multi-member array it was called with" do
result = scope.function_os_any2array([['one', 'two']])
result.should(eq(['one', 'two']))
end
it "should return members of a hash it was called with" do
result = scope.function_os_any2array([{ 'key' => 'value' }])
result.should(eq(['key', 'value']))
end
it "should return an empty array if it was called with an empty hash" do
result = scope.function_os_any2array([{ }])
result.should(eq([]))
end
end

View File

@ -1,22 +1,23 @@
import os
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard import exceptions
DEBUG =<% if @django_debug %>True<% else %>False<% end %>
DEBUG = <%= @django_debug.to_s.capitalize %>
TEMPLATE_DEBUG = DEBUG
PROD = True
#USE_SSL = False
SITE_BRANDING = 'Mirantis OpenStack Dashboard'
# Required for Django 1.5.
# If horizon is running in production (DEBUG is False), set this
# with the list of host/domain names that the application can serve.
# For more information see:
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
# ALLOWED_HOSTS = ['horizon.example.com', 'localhost']
ALLOWED_HOSTS = ['*']
#ALLOWED_HOSTS = ['horizon.example.com', ]
<% if @final_allowed_hosts.kind_of?(Array) %>
ALLOWED_HOSTS = ['<%= @final_allowed_hosts.join("', '") %>', ]
<% else %>
ALLOWED_HOSTS = ['<%= @final_allowed_hosts %>', ]
<% end %>
# Set SSL proxy settings:
# For Django 1.4+ pass this header from the proxy after terminating the SSL,
@ -27,17 +28,22 @@ ALLOWED_HOSTS = ['*']
# If Horizon is being served through SSL, then uncomment the following two
# settings to better secure the cookies from security exploits
<% if @secure_cookies %>
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
<% else %>
#CSRF_COOKIE_SECURE = True
#SESSION_COOKIE_SECURE = True
<% end %>
# Overrides for OpenStack API versions. Use this setting to force the
# OpenStack dashboard to use a specfic API version for a given service API.
# NOTE: The version should be formatted as it appears in the URL for the
# service API. For example, The identity service APIs have inconsistent
# use of the decimal point, so valid options would be "2.0" or "3".
OPENSTACK_API_VERSIONS = {
"identity": 2.0
}
# OPENSTACK_API_VERSIONS = {
# "identity": 3
# }
# Set this to True if running on multi-domain model. When this is enabled, it
# will require user to enter the Domain name in addition to username for login.
@ -49,11 +55,11 @@ OPENSTACK_API_VERSIONS = {
# Set Console type:
# valid options would be "AUTO", "VNC" or "SPICE"
CONSOLE_TYPE = "AUTO"
# CONSOLE_TYPE = "AUTO"
# Default OpenStack Dashboard configuration.
HORIZON_CONFIG = {
'dashboards': ('project', 'admin', 'settings'),
'dashboards': ('project', 'admin', 'settings',),
'default_dashboard': 'project',
'user_home': 'openstack_dashboard.views.get_user_home',
'ajax_queue_limit': 10,
@ -62,21 +68,12 @@ HORIZON_CONFIG = {
'fade_duration': 1500,
'types': ['alert-success', 'alert-info']
},
'help_url': "http://docs.openstack.org",
'exceptions': {
'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED
},
'help_url': "<%= @help_url %>",
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
}
# Ubuntu-specific: Enables an extra panel in the 'Settings' section
# that easily generates a Juju environments.yaml for download,
# preconfigured with endpoints and credentials required for bootstrap
# and service deployment.
ENABLE_JUJU_PANEL = True
# Specify a regular expression to validate user passwords.
# HORIZON_CONFIG["password_validator"] = {
# "regex": '.*',
@ -85,13 +82,12 @@ ENABLE_JUJU_PANEL = True
# Disable simplified floating IP address management for deployments with
# multiple floating IP pools or complex network requirements.
HORIZON_CONFIG["simple_ip_management"] = False
# HORIZON_CONFIG["simple_ip_management"] = False
# Turn off browser autocompletion for the login form if so desired.
# HORIZON_CONFIG["password_autocomplete"] = "off"
#LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
LOCAL_PATH = '/tmp'
LOCAL_PATH = os.path.dirname(os.path.abspath(__file__))
# Set custom secret key:
# You can either set it to a specific value or you can let horizion generate a
@ -102,22 +98,41 @@ LOCAL_PATH = '/tmp'
# behind a load-balancer). Either you have to make sure that a session gets all
# requests routed to the same dashboard instance or you set the same SECRET_KEY
# for all of them.
#from horizon.utils import secret_key
#SECRET_KEY = secret_key.generate_or_read_from_file(os.path.join(LOCAL_PATH, '.secret_key_store'))
# from horizon.utils import secret_key
# SECRET_KEY = secret_key.generate_or_read_from_file(os.path.join(LOCAL_PATH, '.secret_key_store'))
SECRET_KEY = '<%= @secret_key %>'
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# We recommend you use memcached for development; otherwise after every reload
# of the django development server, you will have to login again. To use
# memcached set CACHES to something like
# CACHES = {
# 'default': {
# 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
# 'LOCATION' : '127.0.0.1:11211',
# }
#}
CACHES = {
'default': {
'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION' : "<%= @cache_server_ip.collect {|ip| ip + ':' + @cache_server_port }.join ';' %>"
},
#'local': {
# 'BACKEND' : 'django.core.cache.backends.locmem.LocMemCache'
#}
<% if @cache_server_ip %>
# 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
<% if @cache_server_ip.kind_of?(Array) %>
<% split = ":" + @cache_server_port + "','" %>
'LOCATION': [ <% @cache_server_ip.each do |ip| -%>'<%= ip -%>:<%= @cache_server_port -%>',<% end -%> ],
<% else %>
'LOCATION': '<%= @cache_server_ip %>:<%= @cache_server_port %>',
<% end %>
<% else %>
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
<% end %>
}
}
<% if @django_session_engine %>
SESSION_ENGINE = "<%= @django_session_engine %>"
<% end %>
# Send email to the console by default
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# Or send them to /dev/null
@ -130,17 +145,23 @@ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# EMAIL_HOST_PASSWORD = 'top-secret!'
# For multiple regions uncomment this configuration, and add (endpoint, title).
# AVAILABLE_REGIONS = [
# ('http://cluster1.example.com:5000/v2.0', 'cluster1'),
# ('http://cluster2.example.com:5000/v2.0', 'cluster2'),
# ]
<% if @available_regions.kind_of?(Array) %>
AVAILABLE_REGIONS = [
<% @available_regions.each do |r| -%>
('<%= r[0] -%>', '<%= r[1] -%>'),
<% end -%>
]
<% end -%>
#OPENSTACK_HOST = "127.0.0.1"
#OPENSTACK_KEYSTONE_URL = "http://%s:5000/v2.0" % OPENSTACK_HOST
#OPENSTACK_KEYSTONE_DEFAULT_ROLE = "Member"
OPENSTACK_HOST = "<%= @keystone_host %>"
OPENSTACK_KEYSTONE_URL = "<%= @keystone_scheme %>://%s:<%= @keystone_port %>/v2.0" % OPENSTACK_HOST
<%
if (!@keystone_scheme.nil?) || (!@keystone_host.nil?) || (!@keystone_port.nil?)
@keystone_scheme ||= "http"
@keystone_host ||= "127.0.0.1"
@keystone_port ||= "5000"
@keystone_url = "#{@keystone_scheme}://#{@keystone_host}:#{@keystone_port}/v2.0"
end
-%>
OPENSTACK_KEYSTONE_URL = "<%= @keystone_url %>"
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "<%= @keystone_default_role %>"
# Disable SSL certificate checks (useful for self-signed certificates):
@ -164,22 +185,30 @@ OPENSTACK_KEYSTONE_BACKEND = {
'can_edit_role': True
}
# The OPENSTACK_HYPERVISOR_FEATURES settings can be used to enable optional
# services provided by hypervisors.
OPENSTACK_HYPERVISOR_FEATURES = {
'can_set_mount_point': False
<%- @hypervisor_options = @hypervisor_defaults.merge(@hypervisor_options) -%>
'can_set_mount_point': <%= @hypervisor_options['can_set_mount_point'].to_s.capitalize %>,
'can_set_password': <%= @hypervisor_options['can_set_password'].to_s.capitalize %>,
}
# The OPENSTACK_NEUTRON_NETWORK settings can be used to enable optional
# services provided by neutron. Options currenly available are load
# balancer service, security groups, quotas, VPN service.
OPENSTACK_NEUTRON_NETWORK = {
'enable_lb': False,
'enable_firewall': False,
'enable_quotas': True,
'enable_vpn': False,
# The profile_support option is used to detect if an external router can be
<%- @neutron_options = @neutron_defaults.merge(@neutron_options) -%>
'enable_lb': <%= @neutron_options['enable_lb'].to_s.capitalize %>,
'enable_firewall': <%= @neutron_options['enable_firewall'].to_s.capitalize %>,
'enable_quotas': <%= @neutron_options['enable_quotas'].to_s.capitalize %>,
'enable_security_group': <%= @neutron_options['enable_security_group'].to_s.capitalize %>,
'enable_vpn': <%= @neutron_options['enable_vpn'].to_s.capitalize %>,
# The profile_support option is used to detect if an externa lrouter can be
# configured via the dashboard. When using specific plugins the
# profile_support can be turned on if needed.
'profile_support': None,
<%- if @neutron_options['profile_support'] != 'None' -%>
'profile_support': '<%= @neutron_options['profile_support'] %>',
<%- end -%>
#'profile_support': 'cisco',
}
@ -205,6 +234,9 @@ OPENSTACK_NEUTRON_NETWORK = {
# in the Keystone service catalog. Use this setting when Horizon is running
# external to the OpenStack environment. The default is 'publicURL'.
#OPENSTACK_ENDPOINT_TYPE = "publicURL"
<% if @openstack_endpoint_type %>
OPENSTACK_ENDPOINT_TYPE = "<%= @openstack_endpoint_type %>"
<% end %>
# SECONDARY_ENDPOINT_TYPE specifies the fallback endpoint type to use in the
# case that OPENSTACK_ENDPOINT_TYPE is not present in the endpoints
@ -212,15 +244,13 @@ OPENSTACK_NEUTRON_NETWORK = {
# external to the OpenStack environment. The default is None. This
# value should differ from OPENSTACK_ENDPOINT_TYPE if used.
#SECONDARY_ENDPOINT_TYPE = "publicURL"
<% if @secondary_endpoint_type %>
SECONDARY_ENDPOINT_TYPE = "<%= @secondary_endpoint_type %>"
<% end %>
<% if @swift -%>
# Include the SWIFT interface extension in Horizon
SWIFT_ENABLED = True
SWIFT_PAGINATE_LIMIT = 100
<% end -%>
# The number of Swift containers and objects to display on a single page before
# providing a paging element (a "more" link) to paginate results.
# The number of objects (Swift containers/objects or images) to display
# on a single page before providing a paging element (a "more" link)
# to paginate results.
API_RESULT_LIMIT = <%= @api_result_limit %>
API_RESULT_PAGE_SIZE = 20
@ -228,6 +258,11 @@ API_RESULT_PAGE_SIZE = 20
# of your entire OpenStack installation, and hopefully be in UTC.
TIME_ZONE = "UTC"
# If you have external monitoring links, eg:
<% if @horizon_app_links %>
EXTERNAL_MONITORING = <%= @horizon_app_links %>
<% end %>
# When launching an instance, the menu of available flavors is
# sorted by RAM usage, ascending. Provide a callback method here
# (and/or a flag for reverse sort) for the sorted() method if you'd
@ -244,12 +279,27 @@ TIME_ZONE = "UTC"
# target installation.
# Path to directory containing policy.json files
<% if !(@policy_files_path.nil?) %>
POLICY_FILES_PATH = '<%= @policy_files_path %>'
<% elsif @osfamily == 'RedHat' %>
POLICY_FILES_PATH = '/etc/openstack-dashboard'
<% else %>
#POLICY_FILES_PATH = os.path.join(ROOT_PATH, "conf")
<% end -%>
# Map of local copy of service policy files
<% if @policy_files.kind_of?(Hash) %>
POLICY_FILES = {
<% @policy_files.each do |service_name,filename| -%>
'<%= service_name -%>': '<%= filename -%>',
<% end -%>
} # POLICY_FILES
<% else -%>
#POLICY_FILES = {
# 'identity': 'keystone_policy.json',
# 'compute': 'nova_policy.json'
#}
<% end -%>
# Trove user and database extension support. By default support for
# creating users and databases on database instances is turned on.
@ -258,146 +308,147 @@ TIME_ZONE = "UTC"
# TROVE_ADD_USER_PERMS = []
# TROVE_ADD_DATABASE_PERMS = []
# If you have external monitoring links, eg:
EXTERNAL_MONITORING = <% if @horizon_app_links %><%= @horizon_app_links %><% else %>[ ]<% end %>
LOGGING = {
'version': 1,
# When set to True this will disable all logging except
# for loggers specified in this configuration dictionary. Note that
# if nothing is specified here and disable_existing_loggers is True,
# django.db.backends will still log unless it is disabled explicitly.
'disable_existing_loggers': False,
'formatters': {
'debug': {
'format': 'dashboard-%(name)s: %(levelname)s [pid=%(process)d] %(module)s %(funcName)s %(message)s'
},
'normal': {
'format': 'dashboard-%(name)s: %(levelname)s %(message)s'
},
'version': 1,
# When set to True this will disable all logging except
# for loggers specified in this configuration dictionary. Note that
# if nothing is specified here and disable_existing_loggers is True,
# django.db.backends will still log unless it is disabled explicitly.
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(asctime)s %(process)d %(levelname)s %(name)s '
'%(message)s'
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'django.utils.log.NullHandler',
},
'console': {
# Set the level to "DEBUG" for verbose output logging.
'level': 'INFO',
'class': 'logging.StreamHandler',
},
'file': {
'level': '<%= @log_level %>',
'class': 'logging.FileHandler',
'filename': '<%= scope.lookupvar("horizon::params::logdir") %>/horizon.log',
'formatter': 'normal'
},
'syslog': {
'level': '<%= @log_level %>',
'facility': 'local1',
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log',
'formatter': 'normal'
},
},
'loggers': {
# Logging from django.db.backends is VERY verbose, send to null
# by default.
'django.db.backends': {
'handlers': ['null'],
'propagate': False,
},
'requests': {
'handlers': ['null'],
'propagate': False,
},
'horizon': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'openstack_dashboard': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'novaclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'cinderclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'glanceclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'keystoneclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'neutronclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'heatclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'ceilometerclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'troveclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'swiftclient': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'openstack_auth': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False,
},
'nose.plugins.manager': {
'handlers':<% if @use_syslog -%> ['syslog']<% else -%> ['file']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'django': {
'handlers':<% if @django_debug and @use_syslog -%> ['syslog']<% elif @django_debug -%> ['file']<% else -%> ['null']<% end -%>,
'level': 'DEBUG',
'propagate': False
},
'iso8601': {
'handlers': ['null'],
'propagate': False,
},
}
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'django.utils.log.NullHandler',
},
'console': {
# Set the level to "DEBUG" for verbose output logging.
'level': 'INFO',
'class': 'logging.StreamHandler',
},
'file': {
'level': '<%= @log_level %>',
'class': 'logging.FileHandler',
'filename': '<%= scope.lookupvar("horizon::params::logdir") %>/horizon.log',
'formatter': 'verbose',
},
},
'loggers': {
# Logging from django.db.backends is VERY verbose, send to null
# by default.
'django.db.backends': {
'handlers': ['null'],
'propagate': False,
},
'requests': {
'handlers': ['null'],
'propagate': False,
},
'horizon': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'openstack_dashboard': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'novaclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'cinderclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'keystoneclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'glanceclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'neutronclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'heatclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'ceilometerclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'troveclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'swiftclient': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'openstack_auth': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'nose.plugins.manager': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
'django': {
# 'handlers': ['console'],
'handlers': ['file'],
# 'level': 'DEBUG',
'level': '<%= @log_level %>',
'propagate': False,
},
}
}
LOGIN_URL='<%= scope.lookupvar("horizon::params::root_url") %>/auth/login/'
LOGIN_REDIRECT_URL='<%= scope.lookupvar("horizon::params::root_url") %>'
LOGOUT_URL='<%= scope.lookupvar("horizon::params::root_url") %>/auth/logout/'
# The Ubuntu package includes pre-compressed JS and compiled CSS to allow
# offline compression by default.
# Cantos will compress it durind deploy
# To enable online compression, install
# the node-less package and enable the following option.
COMPRESS_OFFLINE = True
SECURITY_GROUP_RULES = {
'all_tcp': {
@ -487,8 +538,8 @@ SECURITY_GROUP_RULES = {
'ms_sql': {
'name': 'MS SQL',
'ip_protocol': 'tcp',
'from_port': '1443',
'to_port': '1443',
'from_port': '1433',
'to_port': '1433',
},
'mysql': {
'name': 'MYSQL',
@ -504,10 +555,16 @@ SECURITY_GROUP_RULES = {
},
}
ENABLED_QUOTA_GROUPS = {
<% if scope.lookupvar('::openstack::horizon::nova_quota') %>
'nova': True
<% else %>
'nova': False
<% end %>
}
LOGIN_URL = '<%= scope.lookupvar("horizon::params::root_url") %>/auth/login/'
LOGOUT_URL = '<%= scope.lookupvar("horizon::params::root_url") %>/auth/logout/'
LOGIN_REDIRECT_URL = '<%= scope.lookupvar("horizon::params::root_url") %>'
# The Ubuntu package includes pre-compressed JS and compiled CSS to allow
# offline compression by default. To enable online compression, install
# the python-lesscpy package and disable the following option.
COMPRESS_OFFLINE = <%= @compress_offline.to_s.capitalize %>
# For Glance image upload, Horizon uses the file upload support from Django
# so we add this option to change the directory where uploaded files are temporarily
# stored until they are loaded into Glance.
FILE_UPLOAD_TEMP_DIR = '<%= @file_upload_temp_dir %>'

View File

@ -1,58 +0,0 @@
#
# This file autogenerated by Puppet
# Do not edit, changes will be overwritten
#
<%
if @memorysize_mb.to_i < 1200 or @processorcount.to_i <= 3
wsgi_daemon_processes = 3
wsgi_daemon_threads = 10
else
wsgi_daemon_processes = @processorcount
wsgi_daemon_threads = 15
end
if @osfamily == 'RedHat' %>
WSGIDaemonProcess dashboard processes=<%= wsgi_daemon_processes %> threads=<%= wsgi_daemon_threads %>
WSGIProcessGroup dashboard
WSGISocketPrefix run/wsgi
WSGIScriptAlias /dashboard /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
Alias /static /usr/share/openstack-dashboard/static
<Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
<IfModule mod_headers.c>
# Make sure proxies dont deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
Order allow,deny
Allow from all
</Directory>
<Directory /usr/share/openstack-dashboard/static>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access 6 month"
</IfModule>
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
Order allow,deny
Allow from all
</Directory>
<%
end
if @osfamily == 'Debian' %>
WSGIScriptAlias /horizon /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
WSGIDaemonProcess horizon user=horizon group=horizon processes=<%= wsgi_daemon_processes %> threads=<%= wsgi_daemon_threads %>
WSGIProcessGroup horizon
Alias /static /usr/share/openstack-dashboard/openstack_dashboard/static/
<Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
Order allow,deny
Allow from all
</Directory>
<% end %>

View File

@ -1,23 +0,0 @@
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement
NameVirtualHost *:<%= @http_port %>
Listen <%= @bind_address %>:<%= @http_port %>
<% if @osfamily == 'RedHat' -%>
<% if @use_ssl =~ /^(default|exist|custom)$/ -%>
NameVirtualHost *:<%= @https_port %>
Listen <%= @bind_address %>:<%= @https_port %>
<% end %>
<% else %>
<IfModule mod_ssl.c>
# Server Name Indication for SSL named virtual hosts is currently not
# supported by MSIE on Windows XP.
NameVirtualHost *:<%= @https_port %>
Listen <%= @bind_address %>:<%= @https_port %>
</IfModule>
<IfModule mod_gnutls.c>
Listen <%= @bind_address %>:<%= @https_port %>
</IfModule>
<% end %>

View File

@ -1,37 +0,0 @@
#
# This file autogenerated by Puppet
# Do not edit, changes will be overwritten
#
# Configuration file for the httpd service.
#
# The default processing model (MPM) is the process-based
# 'prefork' model. A thread-based model, 'worker', is also
# available, but does not work with some modules (such as PHP).
# The service must be stopped before changing this variable.
#
HTTPD=/usr/sbin/httpd.event
#
# To pass additional options (for instance, -D definitions) to the
# httpd binary at startup, set OPTIONS here.
#
#OPTIONS=
#
# By default, the httpd process is started in the C locale; to
# change the locale in which the server runs, the HTTPD_LANG
# variable can be set.
#
#HTTPD_LANG=C
#
# By default, the httpd process will create the file
# /var/run/httpd/httpd.pid in which it records its process
# identification number when it starts. If an alternate location is
# specified in httpd.conf (via the PidFile directive), the new
# location needs to be reported in the PIDFILE.
#
#PIDFILE=/var/run/httpd/httpd.pid

View File

@ -1,40 +0,0 @@
#
# This file autogenerated by Puppet
# Do not edit, changes will be overwritten
#
<% if @use_ssl =~ /^(default|exist|custom)$/ -%>
# SSL support
<% if @osfamily == 'RedHat' -%>
LoadModule ssl_module modules/mod_ssl.so
<% end -%>
SSLPassPhraseDialog builtin
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout 300
SSLMutex default
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<% end -%>
<% if @use_syslog -%>
ErrorLog syslog:local1
<% end -%>
<VirtualHost *:<%= @http_port %>>
RedirectMatch permanent ^/$ <%= @root_url %>/
<% if @use_ssl =~ /^(default|exist|custom)$/ -%>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
</VirtualHost>
<VirtualHost *:<%= @https_port %>>
RedirectMatch permanent ^/$ <%= @root_url %>/
SSLEngine on
SSLCertificateFile <%= @ssl_cert_file %>
SSLCertificateKeyFile <%= @ssl_key_file %>
<% end -%>
</VirtualHost>

View File

@ -1,78 +0,0 @@
#
# This file autogenerated by Puppet
# Do not edit, changes will be overwritten
#
<%
if @memorysize_mb.to_i < 4100
max_clients = 100
else
max_clients = Integer(@memorysize_mb.to_i / 40)
end
if @processorcount.to_i <= 2
start_servers = 2
else
start_servers = @processorcount.to_i
end
if @osfamily == 'RedHat' %>
<IfModule prefork.c>
StartServers <%= start_servers %>
MinSpareServers <%= start_servers %>
MaxSpareServers <%= Integer(max_clients / 2) %>
ServerLimit <%= max_clients %>
MaxClients <%= max_clients %>
MaxRequestsPerChild 4000
</IfModule>
<IfModule worker.c>
StartServers <%= start_servers %>
ServerLimit <%= Integer(max_clients * 4 / 25) %>
MaxClients <%= Integer(max_clients * 4) %>
MinSpareThreads 25
MaxSpareThreads <%= Integer(max_clients * 2) %>
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
<IfModule event.c>
StartServers <%= start_servers %>
ServerLimit <%= Integer(max_clients * 4 / 25) %>
MaxClients <%= Integer(max_clients * 4) %>
MinSpareThreads 25
MaxSpareThreads <%= Integer(max_clients * 2) %>
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
<%
end
if @osfamily == 'Debian' %>
<IfModule mpm_prefork_module>
StartServers <%= start_servers %>
MinSpareServers <%= start_servers %>
MaxSpareServers <%= Integer(max_clients / 2) %>
ServerLimit <%= max_clients %>
MaxClients <%= max_clients %>
MaxRequestsPerChild 4000
</IfModule>
<IfModule mpm_worker_module>
StartServers <%= start_servers %>
ServerLimit <%= Integer(max_clients * 4 / 25) %>
MaxClients <%= Integer(max_clients * 4) %>
MinSpareThreads 25
MaxSpareThreads <%= Integer(max_clients * 2) %>
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
<IfModule mpm_event_module>
StartServers <%= start_servers %>
ServerLimit <%= Integer(max_clients * 4 / 25) %>
MaxClients <%= Integer(max_clients * 4) %>
MinSpareThreads 25
MaxSpareThreads <%= Integer(max_clients * 2) %>
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
<% end %>

View File

@ -12,7 +12,6 @@ glance
haproxy
heat
heat_ha
horizon
inifile
l23network
mcollective