From 6ffa2cdddc647865759e0683f9713c2c087384a9 Mon Sep 17 00:00:00 2001 From: Rhommel Lamas Date: Thu, 7 Apr 2016 14:28:24 +1000 Subject: [PATCH] Initial commit --- .fixtures.yml | 5 + .github/CONTRIBUTING | 7 ++ .github/ISSUE_TEMPLATE | 5 + .github/PULL_REQUEST_TEMPLATE | 11 ++ .gitignore | 12 ++ .pre-commit-config.yaml | 11 ++ .rspec | 4 + .travis.yml | 42 +++++++ Gemfile | 36 ++++++ README.md | 53 ++++++++ Rakefile | 44 +++++++ data/common.yaml | 18 +++ data/hiera.yaml | 8 ++ lib/puppet/parser/functions/sorted_json.rb | 44 +++++++ manifests/config.pp | 51 ++++++++ manifests/init.pp | 71 +++++++++++ manifests/install.pp | 46 +++++++ manifests/service.pp | 16 +++ metadata.json | 22 ++++ spec/classes/init_spec.rb | 20 +++ spec/classes/vault_config_spec.rb | 60 +++++++++ spec/classes/vault_service_spec.rb | 58 +++++++++ spec/spec_helper.rb | 1 + templates/init-script.erb | 137 +++++++++++++++++++++ tests/init.pp | 12 ++ 25 files changed, 794 insertions(+) create mode 100644 .fixtures.yml create mode 100644 .github/CONTRIBUTING create mode 100644 .github/ISSUE_TEMPLATE create mode 100644 .github/PULL_REQUEST_TEMPLATE create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .rspec create mode 100644 .travis.yml create mode 100644 Gemfile create mode 100644 README.md create mode 100644 Rakefile create mode 100644 data/common.yaml create mode 100644 data/hiera.yaml create mode 100644 lib/puppet/parser/functions/sorted_json.rb create mode 100644 manifests/config.pp create mode 100644 manifests/init.pp create mode 100644 manifests/install.pp create mode 100644 manifests/service.pp create mode 100644 metadata.json create mode 100644 spec/classes/init_spec.rb create mode 100644 spec/classes/vault_config_spec.rb create mode 100644 spec/classes/vault_service_spec.rb create mode 100644 spec/spec_helper.rb create mode 100644 templates/init-script.erb create mode 100644 tests/init.pp diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 0000000..8d09f58 --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,5 @@ +fixtures: + repositories: + stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git" + symlinks: + vault: "#{source_dir}" diff --git a/.github/CONTRIBUTING b/.github/CONTRIBUTING new file mode 100644 index 0000000..e95dfef --- /dev/null +++ b/.github/CONTRIBUTING @@ -0,0 +1,7 @@ +## Development + +1. Clone the repo +2. Change directory to the actual module dir +3. We use pre-commit.com hooks to ensure guidelines `pre-commit install` +4. Create a feature branch +5. Submit a PR diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 0000000..3ec7ec9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,5 @@ +### Expected behavior + +### Actual behavior + +### Steps to reproduce the behavior diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE new file mode 100644 index 0000000..5759013 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE @@ -0,0 +1,11 @@ +Fixes # + +Changes proposed in this pull request: +- +- +- + +@permeate/admins + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b192b47 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/pkg/ +/bin/ +/Gemfile.lock +/vendor/ +spec/fixtures +/.vagrant/ +/.bundle/ +/coverage/ +/.idea/ +*.iml +*.swp +.tmp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..4fc60f3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +- repo: https://github.com/chriskuehl/puppet-pre-commit-hooks.git + sha: 4bc20784cca4713e2ba5f884ff4c37a1e4e87de1 + hooks: + - id: puppet-validate + - id: erb-validate + - id: puppet-lint +- repo: git://github.com/pre-commit/pre-commit-hooks + sha: ff65d01841ad012d0a9aa1dc451fc4539d8b7baf + hooks: + - id: trailing-whitespace + - id: check-json diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..f8cd59d --- /dev/null +++ b/.rspec @@ -0,0 +1,4 @@ +--color +--format +progress +--backtrace \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d4d60b3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +--- +language: ruby + +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 + - 2.1.0 + +env: + matrix: + - PUPPET_GEM_VERSION="~> 3.1.0" + - PUPPET_GEM_VERSION="~> 3.2.0" + - PUPPET_GEM_VERSION="~> 3.3.0" + - PUPPET_GEM_VERSION="~> 3.4.0" + - PUPPET_GEM_VERSION="~> 3.5.1" + - PUPPET_GEM_VERSION="~> 3.6.0" + - PUPPET_GEM_VERSION="~> 3.7.0" + - PUPPET_GEM_VERSION="~> 3.8.0" + +sudo: false + +bundler_args: --without system_tests + +script: 'bundle exec metadata-json-lint metadata.json && bundle exec rake validate && bundle exec rake lint && SPEC_OPTS="--color --format documentation" bundle exec rake spec' + +matrix: + fast_finish: true + exclude: + - rvm: 2.0.0 + env: PUPPET_GEM_VERSION="~> 3.1.0" + - rvm: 2.1.0 + env: PUPPET_GEM_VERSION="~> 3.1.0" + - rvm: 2.1.0 + env: PUPPET_GEM_VERSION="~> 3.2.0" + - rvm: 2.1.0 + env: PUPPET_GEM_VERSION="~> 3.3.0" + - rvm: 2.1.0 + env: PUPPET_GEM_VERSION="~> 3.4.0" + +notifications: + email: false diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..2131c2b --- /dev/null +++ b/Gemfile @@ -0,0 +1,36 @@ +source ENV['GEM_SOURCE'] || 'https://rubygems.org' + +if puppetversion = ENV['PUPPET_GEM_VERSION'] + gem 'puppet', puppetversion, :require => false +else + gem 'puppet', :require => false +end + +gem 'mocha' +gem 'diff-lcs' +gem 'json_pure' +gem 'json' +gem 'metadata-json-lint' +gem 'puppetlabs_spec_helper', '>= 0.1.0' +gem 'facter', '>= 1.7.0' +gem 'rspec-puppet' +gem 'rake', '~> 10.5.0' + +gem 'puppet-lint', :git => 'https://github.com/rodjek/puppet-lint.git' +gem 'puppet-lint-absolute_classname-check' +gem 'puppet-lint-alias-check' +gem 'puppet-lint-empty_string-check' +gem 'puppet-lint-file_ensure-check' +gem 'puppet-lint-file_source_rights-check' +gem 'puppet-lint-fileserver-check' +gem 'puppet-lint-leading_zero-check' +gem 'puppet-lint-spaceship_operator_without_tag-check' +gem 'puppet-lint-trailing_comma-check' +gem 'puppet-lint-undef_in_function-check' +gem 'puppet-lint-unquoted_string-check' +gem 'puppet-lint-variable_contains_upcase' + +# rspec must be v2 for ruby 1.8.7 +if RUBY_VERSION >= '1.8.7' and RUBY_VERSION < '1.9' + gem 'rspec', '~> 2.0' +end diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c885de --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# puppet-vault [![Build Status](https://travis-ci.com/rhoml/puppet-vault.svg?token=vfFGLwkzPiw5jXGyyDBy&branch=master)](https://travis-ci.com/rhoml/puppet-vault) + +# Overview + +This is a puppet module to install Hashicorp's [vault project](https://www.vaultproject.io) to keep your secrets safe. This module doesn't build the Vault packages which should be pretty easy to do using fpm. + +Documentation for Vault can be found on their [site](https://www.vaultproject.io/docs/config/index.html). Take into consideration: +* You can only define one storage backend, listener and telemetry on the config file. +* Other configurations should be set up using Vault API or CLI. + +# Install Vault + +```` +include ::vault +```` + +# Configure Vault using Hiera + +This module enables you to use hiera to configure your Vault server. It also allows you to use module [data](https://github.com/rhoml/puppet-vault/blob/master/data/common.yaml). + +```` +vault::config_hash: + backend: + consul: + address: 127.0.0.1:8500 + advertise_addr: "http://%{::ipaddress_eth0}" + path: 'vault/' + listener: + tcp: + address: "%{::fqdn}:8200" + tls_disable: 1 + telemetry: + statsite_address: '127.0.0.1:8125' + disable_hostname: true + disable_mlock: true +vault::manage_user: true +vault::package_ensure: 'latest' +vault::vault_user: 'vault' +vault::restart_cmd: '/etc/init.d/vault restart' +```` + +# Uninstalling Vault + +Ensure the following hiera key is present so Vault can be correctly uninstalled + +``` +vault::package_ensure: absent +``` + +# See also + +* [hiera-vault](https://github.com/jsok/hiera-vault) +* [consul](https://github.com/solarkennedy/puppet-consul) diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..f7ca75f --- /dev/null +++ b/Rakefile @@ -0,0 +1,44 @@ +require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet-lint/tasks/puppet-lint' + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.send('relative') +PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.relative = true + +desc 'Validate manifests, templates, and ruby files' +task :validate do + Dir['manifests/**/*.pp'].each do |manifest| + sh "puppet parser validate --noop #{manifest}" + end + Dir['spec/**/*.rb','lib/**/*.rb'].each do |ruby_file| + sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/ + end + Dir['templates/**/*.erb'].each do |template| + sh "erb -P -x -T '-' #{template} | ruby -c" + end +end + +PuppetLint::RakeTask.new :lint do |config| + # Pattern of files to check, defaults to `**/*.pp` + config.pattern = 'manifests/**/*.pp' + + # Should the task fail if there were any warnings, defaults to false + config.fail_on_warnings = true + + # Format string for puppet-lint's output (see the puppet-lint help output + # for details + config.log_format = '%{filename} - %{message}' + + # Print out the context for the problem, defaults to false + config.with_context = true + + # Enable automatic fixing of problems, defaults to false + config.fix = true + + # Show ignored problems in the output, defaults to false + config.show_ignored = false + + # Compare module layout relative to the module root + config.relative = true +end diff --git a/data/common.yaml b/data/common.yaml new file mode 100644 index 0000000..5f4aa39 --- /dev/null +++ b/data/common.yaml @@ -0,0 +1,18 @@ +vault::config_hash: + backend: + consul: + advertise_addr: "http://%{::ipaddress}" + path: 'vault/' + listener: + tcp: + address: "%{::fqdn}:8200" + tls_disable: 1 + telemetry: + statsite_address: '%{::ipaddress}:8125' + disable_hostname: true + disable_mlock: true +vault::manage_user: true +vault::package_ensure: present +vault::version: 0.5.2 +vault::vault_user: vault +vault::restart_cmd: '/etc/init.d/vault restart' diff --git a/data/hiera.yaml b/data/hiera.yaml new file mode 100644 index 0000000..cf80a77 --- /dev/null +++ b/data/hiera.yaml @@ -0,0 +1,8 @@ +--- +version: 4 + +datadir: hieradata + +:hierarchy: +- osfamily/%{::osfamily} +- common diff --git a/lib/puppet/parser/functions/sorted_json.rb b/lib/puppet/parser/functions/sorted_json.rb new file mode 100644 index 0000000..49b8cbd --- /dev/null +++ b/lib/puppet/parser/functions/sorted_json.rb @@ -0,0 +1,44 @@ +# Puppet parser function for outputting JSON-formatted objects, in a sorted consistent way. +# Credit: @falzm +# https://gist.github.com/falzm/8575549 +require 'json' + +def sorted_json(obj) + case obj + when String, Fixnum, Float, TrueClass, FalseClass, NilClass + return obj.to_json + when Array + arrayRet = [] + obj.each do |a| + arrayRet.push(sorted_json(a)) + end + return "[" << arrayRet.join(',') << "]"; + when Hash + ret = [] + obj.keys.sort.each do |k| + ret.push(k.to_json << ":" << sorted_json(obj[k])) + end + return "{" << ret.join(",") << "}"; + else + raise Exception("Unable to handle object of type <%s>" % obj.class.to_s) + end +end + +module Puppet::Parser::Functions + newfunction(:sorted_json, :type => :rvalue, :doc => <<-EOS +This function takes data, outputs making sure the hash keys are sorted + +*Examples:* + + sorted_json({'key'=>'value'}) + +Would return: {'key':'value'} + EOS + ) do |arguments| + raise(Puppet::ParseError, "sorted_json(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + json = arguments[0] + return sorted_json(json) + end +end diff --git a/manifests/config.pp b/manifests/config.pp new file mode 100644 index 0000000..1c529e2 --- /dev/null +++ b/manifests/config.pp @@ -0,0 +1,51 @@ +# Class to configure vault +class vault::config ( + $config_hash = $::vault::config_hash, + $manage_user = $::vault::manage_user, + $vault_user = $::vault::vault_user, + ){ + + if $manage_user { + + group { $vault_user: + ensure => 'present', + } + + user { $vault_user: + ensure => 'present', + gid => $vault_user, + require => Group['vault'], + } + } + + file { '/etc/init.d/vault': + ensure => 'file', + mode => '0755', + owner => 'root', + group => 'root', + content => template('vault/init-script.erb'), + notify => Class['::vault::service'], + require => Package['vault'], + } + + file { '/etc/vault': + ensure => 'directory', + mode => '0755', + owner => 'root', + group => 'root', + purge => true, + recurse => true, + require => Package['vault'], + } + + file { '/etc/vault/vault.json': + ensure => 'file', + mode => '0644', + group => $vault_user, + owner => $vault_user, + content => sorted_json($config_hash), + notify => Class['::vault::service'], + require => [ File['/etc/vault'], + File['/etc/init.d/vault'] ], + } +} diff --git a/manifests/init.pp b/manifests/init.pp new file mode 100644 index 0000000..39de49f --- /dev/null +++ b/manifests/init.pp @@ -0,0 +1,71 @@ +# Class: vault +# =========================== +# +# Full description of class vault here. +# +# Usage +# ----- +# +# class { 'vault': +# config_hash => { +# 'backend' => { +# 'github' => { +# 'token' => '' +# } +# }, +# 'listener' => { +# 'tcp' => { +# 'address' => '127.0.0.1:8200', +# 'tls_disable' => 1 +# } +# }, +# 'telemetry' => { +# 'statsite_address' => '127.0.0.1:8125' +# }, +# 'disable_hostname' => true, +# 'disable_mlock' => false +# } +# } +# +# +# Authors +# ------- +# +# Rhommel Lamas +# Twitter: @rhoml +# IRC #freenode: @rhoml +# +# +# Copyright +# --------- +# +# Copyright 2015 Rhommel Lamas, unless otherwise noted. +# +class vault ( + $config_hash = {}, + $manage_user = undef, + $package_ensure = 'present', + $restart_cmd = '/etc/init.d/vault restart', + $service_ensure = 'running', + $service_enable = true, + $vault_user = 'vault', + $version = '0.5.2' + ){ + + validate_re($package_ensure, [ '^present$', '^absent$' ], + '\$package_ensure should be \'present\' or \'purged\'.') + + validate_hash($config_hash) + + if $package_ensure == 'present' { + class {'::vault::install': } + -> + class {'::vault::config': } + ~> + class{'::vault::service': } + } else { + + class {'::vault::install': } + + } +} diff --git a/manifests/install.pp b/manifests/install.pp new file mode 100644 index 0000000..4ba96dd --- /dev/null +++ b/manifests/install.pp @@ -0,0 +1,46 @@ +# Class to install Hashicorp Vault +class vault::install( + $package_ensure = $::vault::package_ensure, + $vault_user = $::vault::vault_user, + $version = $::vault::version, +) { + + case $::osfamily { + /(Debian|Ubuntu)/: { + $real_provider = 'aptitude' + } + default: { + fail("\"${module_name}\" We don't support \"${::osfamily}\"") + } + } + + $vault_ensure = $package_ensure ? { + 'absent' => 'purged', + default => $version, + } + + package { 'vault': + ensure => $vault_ensure, + provider => $real_provider, + } + + # If we are uninstalling Vault we should remove + # all its dependencies + if $package_ensure == 'absent' { + group { $vault_user: + ensure => $package_ensure, + } + + user { $vault_user: + ensure => $package_ensure, + } + + file { '/etc/init.d/vault': + ensure => $package_ensure, + } + + file { '/etc/vault': + ensure => $package_ensure, + } + } +} diff --git a/manifests/service.pp b/manifests/service.pp new file mode 100644 index 0000000..9b9207e --- /dev/null +++ b/manifests/service.pp @@ -0,0 +1,16 @@ +# Class to manage vault service +class vault::service( + $restart_cmd = $::vault::restart_cmd, + $service_ensure = $::vault::service_ensure, + $service_enable = $::vault::service_enable + ){ + service { + 'vault': + ensure => $service_ensure, + enable => $service_enable, + hasstatus => true, + hasrestart => true, + restart => $restart_cmd, + require => File['/etc/vault/vault.json'], + } +} diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..9389ff1 --- /dev/null +++ b/metadata.json @@ -0,0 +1,22 @@ +{ + "name": "rhoml/vault", + "version": "0.0.1", + "author": "Rhommel Lamas", + "email": "roml@rhommell.com", + "summary": "Installs and configure Hashicorp Vault project.", + "license": "MIT", + "source": "https://github.com/rhoml/puppet-vault", + "project_page": "https://github.com/rhoml/puppet-vault/README.md", + "issues_url": "https://github.com/rhoml/puppet-vault/issues", + "tags": ["hashicorp", "vault"], + "dependencies": [ + {"name":"puppetlabs-stdlib","version_requirement":">= 2.2.1"} + ], + "operatingsystem_support": [ + { + "operatingsystem": "Debian", + "operatingsystemrelease": [ "6", "7" ] + } + ] +} + diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb new file mode 100644 index 0000000..ae0e217 --- /dev/null +++ b/spec/classes/init_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + + describe 'vault' do + context 'with defaults for all parameters' do + it { should compile.with_all_deps } + + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistcodename: 'wheezy', + manage_user: true, + } + end + + it { should contain_class('vault') } + + end + +end diff --git a/spec/classes/vault_config_spec.rb b/spec/classes/vault_config_spec.rb new file mode 100644 index 0000000..7cd7050 --- /dev/null +++ b/spec/classes/vault_config_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe 'vault::config', :type => :class do + context "On a Debian OS" do + let :facts do + { + :osfamily => 'Debian', + :operatingsystemrelease => '7', + :concat_basedir => '/tmp', + :lsbdistid => 'Debian', + } + + end + + context "user and group exist for vault if manage users is set to true" do + let (:params) {{:vault_user => 'vault', :manage_user => true}} + it { should contain_group('vault').with_ensure('present') } + + it { should contain_user('vault').with( + 'ensure' => 'present', + 'gid' => 'vault' + ) } + end + + context "vault init should be created" do + it { should contain_file('/etc/init.d/vault').with( + 'ensure' => 'file', + 'mode' => '0755', + 'owner' => 'root', + 'group' => 'root', + ) } + end + + context "vault config dir" do + it { should contain_file('/etc/vault').with( + 'ensure' => 'directory', + 'mode' => '0755', + 'owner' => 'root', + 'group' => 'root', + 'purge' => true, + 'recurse' => true + ) } + end + + context "vault config file" do + let (:params) {{:vault_user => 'vault'}} + it { should contain_file('/etc/vault/vault.json').with( + 'ensure' => 'file', + 'mode' => '0644', + 'owner' => 'vault', + 'group' => 'vault', + ).that_requires( + 'File[/etc/vault]' + ).that_requires( + 'File[/etc/init.d/vault]' + ) } + end + + end +end diff --git a/spec/classes/vault_service_spec.rb b/spec/classes/vault_service_spec.rb new file mode 100644 index 0000000..14e6505 --- /dev/null +++ b/spec/classes/vault_service_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe 'vault::service', :type => :class do + context "On a Debian OS" do + let :facts do + { + :osfamily => 'Debian', + :operatingsystemrelease => '7', + :concat_basedir => '/tmp', + :lsbdistid => 'Debian', + } + end + context "vault running and enabled" do + let (:params) {{:restart_cmd => '/etc/init.d/vault restart', :service_ensure => 'running', :service_enable => true}} + it { should contain_service("vault").with( + 'ensure' => 'running', + 'enable' => 'true', + 'hasstatus' => 'true', + 'hasrestart' => 'true', + 'restart' => '/etc/init.d/vault restart' + ) + } + end + context "vault running and disabled" do + let (:params) {{:restart_cmd => '/etc/init.d/vault restart', :service_ensure => 'running', :service_enable => false}} + it { should contain_service("vault").with( + 'ensure' => 'running', + 'enable' => 'false', + 'hasstatus' => 'true', + 'hasrestart' => 'true', + 'restart' => '/etc/init.d/vault restart' + ) + } + end + context "vault stopped but enabled" do + let (:params) {{:restart_cmd => '/etc/init.d/vault restart', :service_ensure => 'stopped', :service_enable => true}} + it { should contain_service("vault").with( + 'ensure' => 'stopped', + 'enable' => 'true', + 'hasstatus' => 'true', + 'hasrestart' => 'true', + 'restart' => '/etc/init.d/vault restart' + ) + } + end + context "vault stopped and disabled" do + let (:params) {{:restart_cmd => '/etc/init.d/vault restart', :service_ensure => 'stopped', :service_enable => false}} + it { should contain_service("vault").with( + 'ensure' => 'stopped', + 'enable' => 'false', + 'hasstatus' => 'true', + 'hasrestart' => 'true', + 'restart' => '/etc/init.d/vault restart' + ) + } + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..2c6f566 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1 @@ +require 'puppetlabs_spec_helper/module_spec_helper' diff --git a/templates/init-script.erb b/templates/init-script.erb new file mode 100644 index 0000000..428d7c6 --- /dev/null +++ b/templates/init-script.erb @@ -0,0 +1,137 @@ +#!/bin/bash +### BEGIN INIT INFO +# Provides: vault +# Required-Start: $local_fs $remote_fs +# Required-Stop: $local_fs $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: S 0 1 6 +# Short-Description: Vault secrets management framework +# Description: Stores, generates, and manages secrets. +### END INIT INFO + +PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH +DESC="Vault secrets management framework" +NAME=vault +DAEMON=/usr/bin/$NAME +PIDFILE=/var/run/$NAME.pid +DAEMON_ARGS=( server -config=/etc/vault/vault.json ) +USER=<%= @vault_user %> +SCRIPTNAME=/etc/init.d/$NAME + +# Exit if the package is not installed +[ -x "$DAEMON" ] || exit 0 + +# Read configuration variable file if it is present +[ -r "/etc/default/$NAME" ] && . "/etc/default/$NAME" + +# Load the VERBOSE setting and other rcS variables +[ -f /etc/default/rcS ] && . /etc/default/rcS + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + echo -e "Starting vault and backgrounding\n" + start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" --chuid "$USER" --background --make-pidfile --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" --chuid "$USER" --background --make-pidfile -- \ + "${DAEMON_ARGS[@]}" \ + || return 2 +} +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$PIDFILE" --name "$NAME" + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$DAEMON" + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f "$PIDFILE" + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile "$PIDFILE" --name "$NAME" + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + status) + status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/tests/init.pp b/tests/init.pp new file mode 100644 index 0000000..0c986d7 --- /dev/null +++ b/tests/init.pp @@ -0,0 +1,12 @@ +# The baseline for module testing used by Puppet Labs is that each manifest +# should have a corresponding test manifest that declares that class or defined +# type. +# +# Tests are then run by using puppet apply --noop (to check for compilation +# errors and view a log of events) or by fully applying the test in a virtual +# environment (to compare the resulting system state to the desired state). +# +# Learn more about module testing here: +# http://docs.puppetlabs.com/guides/tests_smoke.html +# +include ::vault