From 5740ed3118dedd2fe49f7cfe21a076d0ccac8998 Mon Sep 17 00:00:00 2001
From: Spencer Krum <krum.spencer@gmail.com>
Date: Tue, 4 Mar 2014 08:14:35 -0800
Subject: [PATCH] Add PuppetBoard to openstack infra

This places the puppet web dashboard puppetboard from
https://github.com/nedap/puppetboard onto the puppetdb server.

This enables anyone to see the output of puppet runs, which nodes
are failing and which nodes have not checked in over time. We can
also quickly and interactively query the facts database.

This also modifies install_modules.sh to support a list of modules
that will be installed without dependency resolution.

Change-Id: I09d09410dd8fa71759ce6b2f9c7f34f78eefe204
---
 install_modules.sh                            | 26 +++++++++++
 .../manifests/puppetboard.pp                  | 44 +++++++++++++++++++
 .../openstack_project/manifests/puppetdb.pp   |  5 +++
 .../puppetboard/puppetboard.vhost.erb         | 13 ++++++
 4 files changed, 88 insertions(+)
 create mode 100644 modules/openstack_project/manifests/puppetboard.pp
 create mode 100644 modules/openstack_project/templates/puppetboard/puppetboard.vhost.erb

diff --git a/install_modules.sh b/install_modules.sh
index 5920d3401e..da2468c886 100755
--- a/install_modules.sh
+++ b/install_modules.sh
@@ -13,6 +13,10 @@ function remove_module {
 
 # Array of modules to be installed key:value is module:version.
 declare -A MODULES
+
+# These modules will be installed without dependency resolution
+declare -A  NONDEP_MODULES
+
 #NOTE: if we previously installed kickstandproject-ntp we nuke it here
 # since puppetlabs-ntp and kickstandproject-ntp install to the same dir
 if grep kickstandproject-ntp /etc/puppet/modules/ntp/Modulefile &> /dev/null; then
@@ -50,6 +54,9 @@ MODULES["rafaelfc-pear"]="1.0.3"
 MODULES["puppetlabs-inifile"]="1.0.0"
 MODULES["puppetlabs-firewall"]="0.0.4"
 MODULES["puppetlabs-puppetdb"]="3.0.1"
+MODULES["stankevich-python"]="1.6.6"
+
+NONDEP_MODULES["nibalizer-puppetboard"]="2.3.0"
 
 MODULE_LIST=`puppet module list`
 
@@ -59,6 +66,7 @@ then
     rm -rf /etc/puppet/modules/vcsrepo
 fi
 
+# Install all the modules
 for MOD in ${!MODULES[*]} ; do
   # If the module at the current version does not exist upgrade or install it.
   if ! echo $MODULE_LIST | grep "$MOD ([^v]*v${MODULES[$MOD]}" >/dev/null 2>&1
@@ -71,3 +79,21 @@ for MOD in ${!MODULES[*]} ; do
     fi
   fi
 done
+
+MODULE_LIST=`puppet module list`
+
+# Make a second pass, installing all modules without their dependencies
+for MOD in ${!NONDEP_MODULES[*]} ; do
+  # If the module at the current version does not exist upgrade or install it.
+  if ! echo $MODULE_LIST | grep "$MOD ([^v]*v${NONDEP_MODULES[$MOD]}" >/dev/null 2>&1
+  then
+    # Attempt module upgrade. If that fails try installing the module.
+    if ! puppet module upgrade $MOD --ignore-dependencies --version \
+         ${NONDEP_MODULES[$MOD]} >/dev/null 2>&1
+    then
+      # This will get run in cron, so silence non-error output
+      puppet module install $MOD --ignore-dependencies --version \
+      ${NONDEP_MODULES[$MOD]} >/dev/null
+    fi
+  fi
+done
diff --git a/modules/openstack_project/manifests/puppetboard.pp b/modules/openstack_project/manifests/puppetboard.pp
new file mode 100644
index 0000000000..77efe01989
--- /dev/null
+++ b/modules/openstack_project/manifests/puppetboard.pp
@@ -0,0 +1,44 @@
+# Class to configure puppetboard on a node.
+# This will only work on the puppetdb server for now
+class openstack_project::puppetboard(
+  $basedir = $::puppetboard::params::basedir,
+  $user    = $::puppetboard::params::user,
+  $group   = $::puppetboard::params::group,
+  $port    = '80',
+) {
+
+  include apache
+
+  class { 'apache::mod::wsgi': }
+
+  class { '::puppetboard':
+    enable_query => 'False', # This being a python false
+  }
+
+  $docroot = "${basedir}/puppetboard"
+
+  # Template Uses:
+  # - $basedir
+  #
+  file { "${docroot}/wsgi.py":
+    ensure  => present,
+    content => template('puppetboard/wsgi.py.erb'),
+    owner   => $user,
+    group   => $group,
+    require => User[$user],
+  }
+
+  # Template Uses:
+  # - $docroot
+  # - $user
+  # - $group
+  # - $port
+  #
+  apache::vhost { $::fqdn:
+    port     => 80,
+    docroot  => 'MEANINGLESS ARGUMENT',
+    priority => '50',
+    template => 'openstack_projects/puppetboard/puppetboard.vhost.erb',
+  }
+
+}
diff --git a/modules/openstack_project/manifests/puppetdb.pp b/modules/openstack_project/manifests/puppetdb.pp
index 07cd1c06f8..39237551d2 100644
--- a/modules/openstack_project/manifests/puppetdb.pp
+++ b/modules/openstack_project/manifests/puppetdb.pp
@@ -2,6 +2,7 @@
 #
 class openstack_project::puppetdb (
   $sysadmins = [],
+  $puppetboard = true,
 ) {
 
   # The puppetlabs postgres module does not manage the postgres user
@@ -36,4 +37,8 @@ class openstack_project::puppetdb (
       Class['puppetdb::database::postgresql'],],
   }
 
+  if $puppetboard {
+    class { 'openstack_project::puppetboard': }
+  }
+
 }
diff --git a/modules/openstack_project/templates/puppetboard/puppetboard.vhost.erb b/modules/openstack_project/templates/puppetboard/puppetboard.vhost.erb
new file mode 100644
index 0000000000..54e052e2aa
--- /dev/null
+++ b/modules/openstack_project/templates/puppetboard/puppetboard.vhost.erb
@@ -0,0 +1,13 @@
+<VirtualHost *:<%= @port %>>
+    ServerName <%= @fqdn %>
+
+    WSGIDaemonProcess puppetboard user=<%= @user %> group=<%= @group %> threads=5
+    WSGIScriptAlias / <%= @docroot %>/wsgi.py
+
+    <Directory <%= @docroot %>>
+        WSGIProcessGroup <%= @group %>
+        WSGIApplicationGroup %{GLOBAL}
+        Order deny,allow
+        Allow from all
+    </Directory>
+</VirtualHost>