diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..70813df
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+Gemfile.lock
+.bundled_gems
+log/
+junit/
+.vagrant/
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..439ed4f
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,28 @@
+source 'https://rubygems.org'
+
+group :development, :test do
+ gem 'puppetlabs_spec_helper', :require => false
+
+ gem 'metadata-json-lint'
+ gem 'puppet-lint-absolute_classname-check'
+ gem 'puppet-lint-absolute_template_path'
+ gem 'puppet-lint-trailing_newline-check'
+
+ gem 'puppet-lint-unquoted_string-check'
+ gem 'puppet-lint-leading_zero-check'
+ gem 'puppet-lint-variable_contains_upcase'
+ gem 'puppet-lint-spaceship_operator_without_tag-check'
+ gem 'puppet-lint-undef_in_function-check'
+
+ if puppetversion = ENV['PUPPET_GEM_VERSION']
+ gem 'puppet', puppetversion, :require => false
+ else
+ gem 'puppet', '~> 3.0', :require => false
+ end
+end
+
+group :system_tests do
+ gem 'beaker-rspec', :require => false
+end
+
+# vim:ft=ruby
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a1a8ab7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+# OpenStack Health Puppet Module
+
+## Overview
+
+This module provisions (OpenStack Health)[http://git.openstack.org/cgit/openstack/openstack-health].
+
+## Running lint
+
+```
+$ bundle install
+$ bundle exec rake lint
+```
+
+## Running acceptance tests
+
+```
+$ bundle install
+$ bundle exec rspec spec/acceptance
+```
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..ff1f0d7
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,8 @@
+require 'rubygems'
+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_autoloader_layout')
+PuppetLint.configuration.send('disable_class_inherits_from_params_class')
+PuppetLint.configuration.send('disable_class_parameter_defaults')
diff --git a/manifests/api.pp b/manifests/api.pp
new file mode 100644
index 0000000..c75644a
--- /dev/null
+++ b/manifests/api.pp
@@ -0,0 +1,67 @@
+# Install and maintain OpenStack Health.
+# params:
+# source_dir:
+# The directory where the application will be running
+# serveradmin:
+# Used in the Apache virtual host, eg., openstack-health@openstack.org
+# vhost_name:
+# Used in the Apache virtual host, eg., health.openstack.org
+# vhost_port:
+# Used in the Apache virtual host, eg., 5000
+class openstack_health::api(
+ $db_uri = undef,
+ $source_dir = '/opt/openstack-health',
+ $server_admin = "webmaster@${::fqdn}",
+ $vhost_name = 'localhost',
+ $vhost_port = 5000,
+) {
+
+ include ::httpd::mod::wsgi
+
+ $api_dir = "${source_dir}/openstack_health"
+ $virtualenv_dir = "${source_dir}/.venv"
+
+ class { '::python':
+ dev => true,
+ pip => true,
+ virtualenv => true,
+ version => 'system',
+ }
+
+ ::python::virtualenv { $virtualenv_dir:
+ ensure => present,
+ require => Class['::python'],
+ }
+
+ ::python::requirements { "${source_dir}/requirements.txt":
+ virtualenv => $virtualenv_dir,
+ require => Python::Virtualenv[$virtualenv_dir],
+ subscribe => Vcsrepo[$source_dir],
+ }
+
+ exec { 'package-application':
+ command => "${virtualenv_dir}/bin/pip install ${source_dir}",
+ require => Python::Requirements["${source_dir}/requirements.txt"],
+ }
+
+ file { '/etc/openstack-health.conf':
+ ensure => present,
+ content => template('openstack_health/openstack-health.conf.erb'),
+ owner => 'openstack_health',
+ group => 'openstack_health',
+ mode => '0644',
+ subscribe => Vcsrepo[$source_dir],
+ }
+
+ ::httpd::vhost { "${vhost_name}-api":
+ docroot => 'MEANINGLESS ARGUMENT',
+ port => $vhost_port,
+ priority => '50',
+ ssl => false,
+ template => 'openstack_health/openstack-health-api.vhost.erb',
+ require => [
+ File['/etc/openstack-health.conf'],
+ Exec['package-application'],
+ ],
+ }
+}
diff --git a/manifests/frontend.pp b/manifests/frontend.pp
new file mode 100644
index 0000000..0af6c05
--- /dev/null
+++ b/manifests/frontend.pp
@@ -0,0 +1,68 @@
+# Install and maintain OpenStack Health.
+# params:
+# source_dir:
+# The directory where the application will be running
+# serveradmin:
+# Used in the Apache virtual host, eg., openstack-health@openstack.org
+# vhost_name:
+# Used in the Apache virtual host, eg., health.openstack.org
+# vhost_port:
+# Used in the Apache virtual host, eg., 5000
+# api_endpoint:
+# The URL where openstack-health API is running
+class openstack_health::frontend(
+ $source_dir = '/opt/openstack-health',
+ $serveradmin = "webmaster@${::fqdn}",
+ $vhost_name = 'localhost',
+ $vhost_port = 80,
+ $api_endpoint = 'http://localhost:5000',
+) {
+
+ $frontend_dir = "${source_dir}/build"
+
+ class { '::nodejs':
+ legacy_debian_symlinks => true,
+ repo_url_suffix => 'node_0.12',
+ }
+
+ package { 'node-gyp':
+ ensure => present,
+ provider => npm,
+ require => Class['::nodejs'],
+ }
+
+ package { 'gulp':
+ ensure => present,
+ provider => npm,
+ require => Class['::nodejs'],
+ }
+
+ exec { 'install-frontend-requirements':
+ command => 'npm install',
+ cwd => $source_dir,
+ path => ['/usr/local/bin/', '/usr/bin/', '/bin/'],
+ timeout => 900,
+ require => [
+ Package['gulp'],
+ Package['node-gyp'],
+ ],
+ subscribe => Vcsrepo[$source_dir],
+ }
+
+ exec { 'build-static-files':
+ command => 'gulp prod',
+ cwd => $source_dir,
+ path => ['/usr/local/bin/', '/usr/bin/', '/bin/'],
+ require => Exec['install-frontend-requirements'],
+ subscribe => Vcsrepo[$source_dir],
+ }
+
+ ::httpd::vhost { "${vhost_name}-frontend":
+ docroot => 'MEANINGLESS ARGUMENT',
+ port => $vhost_port,
+ priority => '100',
+ ssl => false,
+ template => 'openstack_health/openstack-health-frontend.vhost.erb',
+ require => Exec['build-static-files'],
+ }
+}
diff --git a/manifests/init.pp b/manifests/init.pp
new file mode 100644
index 0000000..cd7ea4a
--- /dev/null
+++ b/manifests/init.pp
@@ -0,0 +1,27 @@
+# Install and maintain OpenStack Health.
+# params:
+# source_dir:
+# The directory where the application will be running
+# git_source_repo:
+# Source code repository
+# git_revision:
+# Branch or tag that will be deployed
+class openstack_health(
+ $source_dir = '/opt/openstack-health',
+ $git_source_repo = 'https://git.openstack.org/openstack/openstack-health',
+ $git_revision = 'master',
+) {
+
+ include ::httpd
+ include ::openstack_health::user
+
+ vcsrepo { $source_dir :
+ ensure => latest,
+ owner => 'openstack_health',
+ group => 'openstack_health',
+ provider => git,
+ revision => $git_revision,
+ source => $git_source_repo,
+ require => Class['::openstack_health::user'],
+ }
+}
diff --git a/manifests/user.pp b/manifests/user.pp
new file mode 100644
index 0000000..7837962
--- /dev/null
+++ b/manifests/user.pp
@@ -0,0 +1,25 @@
+# == Class: gerrit::user
+#
+class openstack_health::user {
+ group { 'openstack_health':
+ ensure => present,
+ }
+
+ user { 'openstack_health':
+ ensure => present,
+ comment => 'Openstack-Health User',
+ home => '/home/openstack_health',
+ gid => 'openstack_health',
+ shell => '/bin/bash',
+ membership => 'minimum',
+ require => Group['openstack_health'],
+ }
+
+ file { '/home/openstack_health':
+ ensure => directory,
+ owner => 'openstack_health',
+ group => 'openstack_health',
+ mode => '0644',
+ require => User['openstack_health'],
+ }
+}
diff --git a/metadata.json b/metadata.json
new file mode 100644
index 0000000..99bb290
--- /dev/null
+++ b/metadata.json
@@ -0,0 +1,24 @@
+{
+ "name": "openstackinfra-openstack_health",
+ "version": "0.0.1",
+ "author": "OpenStack Contributors",
+ "summary": "Puppet module for OpenStack Health",
+ "license": "Apache 2.0",
+ "source": "git://git.openstack.org/openstack-infra/puppet-openstack-health.git",
+ "project_page": "http://docs.openstack.org/infra/system-config/",
+ "issues_url": "",
+ "description": "Installs and configures OpenStack Health",
+ "operatingsystem_support": [
+ {
+ "operatingsystem": "Debian",
+ "operatingsystemrelease": ["8"]
+ },
+ {
+ "operatingsystem": "Ubuntu",
+ "operatingsystemrelease": ["14.04"]
+ }
+ ],
+ "dependencies": [
+ {"name":"openstackinfra/vcsrepo","version_requirement":">= 0.0.8"}
+ ]
+}
diff --git a/spec/acceptance/api_spec.rb b/spec/acceptance/api_spec.rb
new file mode 100644
index 0000000..f111799
--- /dev/null
+++ b/spec/acceptance/api_spec.rb
@@ -0,0 +1,62 @@
+require 'spec_helper_acceptance'
+
+describe 'puppet-openstack_health::api manifest', :if => ['debian', 'ubuntu'].include?(os[:family]) do
+ def pp_path
+ base_path = File.dirname(__FILE__)
+ File.join(base_path, 'fixtures')
+ end
+
+ def api_puppet_module
+ module_path = File.join(pp_path, 'api.pp')
+ File.read(module_path)
+ end
+
+ it 'should work with no errors' do
+ apply_manifest(api_puppet_module, catch_failures: true)
+ end
+
+ describe 'required packages' do
+ describe 'os packages' do
+ required_packages = [
+ package('apache2'),
+ package('python-dev'),
+ package('python-pip'),
+ package('python-virtualenv'),
+ ]
+
+ required_packages.each do |package|
+ describe package do
+ it { should be_installed }
+ end
+ end
+ end
+ end
+
+ describe 'required files' do
+ describe file('/opt/openstack-health') do
+ it { should be_directory }
+ it { should be_owned_by 'openstack_health' }
+ it { should be_grouped_into 'openstack_health' }
+ end
+
+ describe file('/etc/openstack-health.conf') do
+ it { should be_file }
+ it { should be_owned_by 'openstack_health' }
+ it { should be_grouped_into 'openstack_health' }
+ end
+ end
+
+ describe 'required services' do
+ describe 'ports are open and services are reachable' do
+ describe port(5000) do
+ it { should be_listening }
+ end
+
+ describe command('curl http://localhost:5000/status --verbose') do
+ its(:stdout) { should contain('status') }
+ its(:stdout) { should contain('true') }
+ its(:stdout) { should_not contain('false') }
+ end
+ end
+ end
+end
diff --git a/spec/acceptance/fixtures/api.pp b/spec/acceptance/fixtures/api.pp
new file mode 100644
index 0000000..6624004
--- /dev/null
+++ b/spec/acceptance/fixtures/api.pp
@@ -0,0 +1,13 @@
+$source_dir = '/opt/openstack-health'
+
+class { '::openstack_health':
+ source_dir => $source_dir,
+}
+
+class { '::openstack_health::api':
+ db_uri => 'mysql+pymysql://query:query@logstash.openstack.org/subunit2sql',
+ source_dir => '/opt/openstack-health',
+ server_admin => 'webmaster@localhost',
+ vhost_name => 'localhost',
+ vhost_port => 5000,
+}
diff --git a/spec/acceptance/fixtures/frontend.pp b/spec/acceptance/fixtures/frontend.pp
new file mode 100644
index 0000000..687b4c2
--- /dev/null
+++ b/spec/acceptance/fixtures/frontend.pp
@@ -0,0 +1,13 @@
+$source_dir = '/opt/openstack-health'
+
+class { '::openstack_health':
+ source_dir => $source_dir,
+}
+
+class { '::openstack_health::frontend':
+ source_dir => '/opt/openstack-health',
+ serveradmin => 'webmaster@localhost',
+ vhost_name => 'localhost',
+ vhost_port => 80,
+ api_endpoint => 'http://localhost:5000',
+}
diff --git a/spec/acceptance/frontend_spec.rb b/spec/acceptance/frontend_spec.rb
new file mode 100644
index 0000000..5f294a0
--- /dev/null
+++ b/spec/acceptance/frontend_spec.rb
@@ -0,0 +1,66 @@
+require 'spec_helper_acceptance'
+
+describe 'puppet-openstack_health::api manifest', :if => ['debian', 'ubuntu'].include?(os[:family]) do
+ def pp_path
+ base_path = File.dirname(__FILE__)
+ File.join(base_path, 'fixtures')
+ end
+
+ def frontend_puppet_module
+ module_path = File.join(pp_path, 'frontend.pp')
+ File.read(module_path)
+ end
+
+ it 'should work with no errors' do
+ apply_manifest(frontend_puppet_module, catch_failures: true)
+ end
+
+ describe 'required packages' do
+ describe 'os packages' do
+ required_packages = [
+ package('apache2'),
+ package('nodejs'),
+ ]
+
+ required_packages.each do |package|
+ describe package do
+ it { should be_installed }
+ end
+ end
+ end
+
+ describe 'npm packages' do
+ required_packages = [
+ package('npm'),
+ package('node-gyp'),
+ package('gulp'),
+ ]
+
+ required_packages.each do |package|
+ describe package do
+ it { should be_installed.by('npm') }
+ end
+ end
+ end
+ end
+
+ describe 'required files' do
+ describe file('/opt/openstack-health') do
+ it { should be_directory }
+ it { should be_owned_by 'openstack_health' }
+ it { should be_grouped_into 'openstack_health' }
+ end
+ end
+
+ describe 'required services' do
+ describe 'ports are open and services are reachable' do
+ describe port(80) do
+ it { should be_listening }
+ end
+
+ describe command('curl http://localhost --verbose') do
+ its(:stdout) { should contain('OpenStack Health') }
+ end
+ end
+ end
+end
diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml
new file mode 100644
index 0000000..3bb3e62
--- /dev/null
+++ b/spec/acceptance/nodesets/default.yml
@@ -0,0 +1,11 @@
+HOSTS:
+ ubuntu-server-1404-x64:
+ roles:
+ - master
+ platform: ubuntu-14.04-amd64
+ box: puppetlabs/ubuntu-14.04-64-nocm
+ box_url: https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm
+ hypervisor: vagrant
+CONFIG:
+ log_level: debug
+ type: git
diff --git a/spec/acceptance/nodesets/nodepool-centos7.yml b/spec/acceptance/nodesets/nodepool-centos7.yml
new file mode 100644
index 0000000..c552874
--- /dev/null
+++ b/spec/acceptance/nodesets/nodepool-centos7.yml
@@ -0,0 +1,10 @@
+HOSTS:
+ centos-70-x64:
+ roles:
+ - master
+ platform: el-7-x86_64
+ hypervisor: none
+ ip: 127.0.0.1
+CONFIG:
+ type: foss
+ set_env: false
diff --git a/spec/acceptance/nodesets/nodepool-trusty.yml b/spec/acceptance/nodesets/nodepool-trusty.yml
new file mode 100644
index 0000000..9fc624e
--- /dev/null
+++ b/spec/acceptance/nodesets/nodepool-trusty.yml
@@ -0,0 +1,10 @@
+HOSTS:
+ ubuntu-14.04-amd64:
+ roles:
+ - master
+ platform: ubuntu-14.04-amd64
+ hypervisor: none
+ ip: 127.0.0.1
+CONFIG:
+ type: foss
+ set_env: false
diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb
new file mode 100644
index 0000000..fe24457
--- /dev/null
+++ b/spec/spec_helper_acceptance.rb
@@ -0,0 +1,56 @@
+require 'beaker-rspec'
+
+hosts.each do |host|
+ install_puppet
+ on host, "mkdir -p #{host['distmoduledir']}"
+end
+
+RSpec.configure do |c|
+ # Project root
+ proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+ modname = JSON.parse(open('metadata.json').read)['name'].split('-')[1]
+
+ # Readable test descriptions
+ c.formatter = :documentation
+
+ # Configure all nodes in nodeset
+ c.before :suite do
+ # Install module and dependencies
+ hosts.each do |host|
+
+ # Clean out any module cruft
+ shell('rm -fr /etc/puppet/modules/*')
+
+ # install git
+ install_package host, 'git'
+
+ zuul_ref = ENV['ZUUL_REF']
+ zuul_branch = ENV['ZUUL_BRANCH']
+ zuul_url = ENV['ZUUL_URL']
+
+ # Install dependent modules via git or zuul
+ r = on host, "test -e /usr/zuul-env/bin/zuul-cloner", { :acceptable_exit_codes => [0,1] }
+ repo = 'openstack-infra/system-config'
+ if r.exit_code == 0
+ zuul_clone_cmd = '/usr/zuul-env/bin/zuul-cloner '
+ zuul_clone_cmd += '--cache-dir /opt/git '
+ zuul_clone_cmd += "--zuul-ref #{zuul_ref} "
+ zuul_clone_cmd += "--zuul-branch #{zuul_branch} "
+ zuul_clone_cmd += "--zuul-url #{zuul_url} "
+ zuul_clone_cmd += "git://git.openstack.org #{repo}"
+ on host, zuul_clone_cmd
+ else
+ on host, "git clone https://git.openstack.org/#{repo} #{repo}"
+ end
+
+ on host, "ZUUL_REF=#{zuul_ref} ZUUL_BRANCH=#{zuul_branch} ZUUL_URL=#{zuul_url} bash #{repo}/tools/install_modules_acceptance.sh"
+ on host, "rm -fr /etc/puppet/modules/#{modname}"
+
+ # Install the module being tested
+ puppet_module_install(:source => proj_root, :module_name => modname)
+ on host, "rm -fr #{repo}"
+ # List modules installed to help with debugging
+ on hosts[0], puppet('module','list'), { :acceptable_exit_codes => 0 }
+ end
+ end
+end
diff --git a/templates/openstack-health-api.vhost.erb b/templates/openstack-health-api.vhost.erb
new file mode 100644
index 0000000..1b82e42
--- /dev/null
+++ b/templates/openstack-health-api.vhost.erb
@@ -0,0 +1,27 @@
+<% unless [443, 80].include?(scope.lookupvar("openstack_health::api::vhost_port").to_i) %>
+Listen <%= scope.lookupvar("openstack_health::api::vhost_port") %>
+<% end %>
+WSGIPythonHome <%= scope.lookupvar("openstack_health::api::virtualenv_dir") %>
+>
+ ServerName <%= scope.lookupvar("openstack_health::api::vhost_name") %>
+ ServerAdmin <%= scope.lookupvar("openstack_health::api::server_admin") %>
+
+ LogLevel info
+ CustomLog ${APACHE_LOG_DIR}/openstack-health-api-access.log combined
+ ErrorLog ${APACHE_LOG_DIR}/openstack-health-api-error.log
+
+ WSGIDaemonProcess flask user=openstack_health group=openstack_health threads=5 home=<%= scope.lookupvar("openstack_health::api::source_dir") %>
+ WSGIScriptAlias / <%= scope.lookupvar("openstack_health::api::virtualenv_dir") %>/bin/openstack-health
+
+ /bin>
+ WSGIProcessGroup flask
+ WSGIApplicationGroup %{GLOBAL}
+ WSGIScriptReloading On
+
+ Order allow,deny
+ Allow from all
+ Require all granted
+
+
+ DocumentRoot <%= scope.lookupvar("openstack_health::api::api_dir") %>
+
diff --git a/templates/openstack-health-frontend.vhost.erb b/templates/openstack-health-frontend.vhost.erb
new file mode 100644
index 0000000..6fdd9a0
--- /dev/null
+++ b/templates/openstack-health-frontend.vhost.erb
@@ -0,0 +1,20 @@
+<% unless [443, 80].include?(scope.lookupvar("openstack_health::frontend::vhost_port").to_i) %>
+Listen <%= scope.lookupvar("openstack_health::frontend::vhost_port") %>
+<% end %>
+>
+ ServerName <%= scope.lookupvar("openstack_health::frontend::vhost_name") %>
+ ServerAdmin <%= scope.lookupvar("openstack_health::frontend::serveradmin") %>
+
+ LogLevel info
+ CustomLog ${APACHE_LOG_DIR}/openstack-health-frontend-access.log combined
+ ErrorLog ${APACHE_LOG_DIR}/openstack-health-frontend-error.log
+
+ >
+ Order allow,deny
+ Allow from all
+ Require all granted
+
+
+ DocumentRoot <%= scope.lookupvar("openstack_health::frontend::frontend_dir") %>
+ DirectoryIndex index.html
+
diff --git a/templates/openstack-health.conf.erb b/templates/openstack-health.conf.erb
new file mode 100644
index 0000000..c84d971
--- /dev/null
+++ b/templates/openstack-health.conf.erb
@@ -0,0 +1,2 @@
+[default]
+db_uri = <%= scope.lookupvar("openstack_health::api::db_uri") %>