├── .fixtures.yml ├── .github ├── CONTRIBUTING ├── ISSUE_TEMPLATE └── PULL_REQUEST_TEMPLATE ├── .gitignore ├── .pre-commit-config.yaml ├── .rspec ├── .travis.yml ├── Gemfile ├── README.md ├── Rakefile ├── data ├── common.yaml └── hiera.yaml ├── lib └── puppet │ └── parser │ └── functions │ └── sorted_json.rb ├── manifests ├── config.pp ├── init.pp ├── install.pp └── service.pp ├── metadata.json ├── spec ├── classes │ ├── init_spec.rb │ ├── vault_config_spec.rb │ ├── vault_install_spec.rb │ └── vault_service_spec.rb └── spec_helper.rb ├── templates └── init-script.erb └── tests └── init.pp /.fixtures.yml: -------------------------------------------------------------------------------- 1 | fixtures: 2 | repositories: 3 | stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git" 4 | symlinks: 5 | vault: "#{source_dir}" 6 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING: -------------------------------------------------------------------------------- 1 | ## Development 2 | 3 | 1. Clone the repo 4 | 2. Change directory to the actual module dir 5 | 3. We use pre-commit.com hooks to ensure guidelines `pre-commit install` 6 | 4. Create a feature branch 7 | 5. Submit a PR 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | ### Expected behavior 2 | 3 | ### Actual behavior 4 | 5 | ### Steps to reproduce the behavior 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | Changes proposed in this pull request: 4 | - 5 | - 6 | - 7 | 8 | @permeate/admins 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /pkg/ 2 | /bin/ 3 | /Gemfile.lock 4 | /vendor/ 5 | spec/fixtures 6 | /.vagrant/ 7 | /.bundle/ 8 | /coverage/ 9 | /.idea/ 10 | *.iml 11 | *.swp 12 | .tmp 13 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | - repo: https://github.com/chriskuehl/puppet-pre-commit-hooks.git 2 | sha: 4bc20784cca4713e2ba5f884ff4c37a1e4e87de1 3 | hooks: 4 | - id: puppet-validate 5 | - id: erb-validate 6 | - id: puppet-lint 7 | - repo: git://github.com/pre-commit/pre-commit-hooks 8 | sha: ff65d01841ad012d0a9aa1dc451fc4539d8b7baf 9 | hooks: 10 | - id: trailing-whitespace 11 | - id: check-json 12 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format 3 | progress 4 | --backtrace -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | 4 | rvm: 5 | - 1.9.3 6 | - 2.0.0 7 | - 2.1.0 8 | 9 | env: 10 | matrix: 11 | - PUPPET_GEM_VERSION="~> 3.1.0" 12 | - PUPPET_GEM_VERSION="~> 3.2.0" 13 | - PUPPET_GEM_VERSION="~> 3.3.0" 14 | - PUPPET_GEM_VERSION="~> 3.4.0" 15 | - PUPPET_GEM_VERSION="~> 3.5.1" 16 | - PUPPET_GEM_VERSION="~> 3.6.0" 17 | - PUPPET_GEM_VERSION="~> 3.7.0" 18 | - PUPPET_GEM_VERSION="~> 3.8.0" 19 | 20 | sudo: false 21 | 22 | bundler_args: --without system_tests 23 | 24 | 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' 25 | 26 | matrix: 27 | fast_finish: true 28 | exclude: 29 | - rvm: 2.0.0 30 | env: PUPPET_GEM_VERSION="~> 3.1.0" 31 | - rvm: 2.1.0 32 | env: PUPPET_GEM_VERSION="~> 3.1.0" 33 | - rvm: 2.1.0 34 | env: PUPPET_GEM_VERSION="~> 3.2.0" 35 | - rvm: 2.1.0 36 | env: PUPPET_GEM_VERSION="~> 3.3.0" 37 | - rvm: 2.1.0 38 | env: PUPPET_GEM_VERSION="~> 3.4.0" 39 | 40 | notifications: 41 | email: false 42 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 2 | 3 | if puppetversion = ENV['PUPPET_GEM_VERSION'] 4 | gem 'puppet', puppetversion, :require => false 5 | else 6 | gem 'puppet', :require => false 7 | end 8 | 9 | gem 'mocha' 10 | gem 'diff-lcs' 11 | gem 'json_pure' 12 | gem 'json' 13 | gem 'metadata-json-lint' 14 | gem 'puppetlabs_spec_helper', '>= 0.1.0' 15 | gem 'facter', '>= 1.7.0' 16 | gem 'rspec-puppet' 17 | gem 'rspec', '~> 3.4.0' 18 | gem 'rake', '~> 11.1.2' 19 | 20 | gem 'puppet-lint', :git => 'https://github.com/rodjek/puppet-lint.git' 21 | gem 'puppet-lint-absolute_classname-check' 22 | gem 'puppet-lint-alias-check' 23 | gem 'puppet-lint-empty_string-check' 24 | gem 'puppet-lint-file_ensure-check' 25 | gem 'puppet-lint-file_source_rights-check' 26 | gem 'puppet-lint-fileserver-check' 27 | gem 'puppet-lint-leading_zero-check' 28 | gem 'puppet-lint-spaceship_operator_without_tag-check' 29 | gem 'puppet-lint-trailing_comma-check' 30 | gem 'puppet-lint-undef_in_function-check' 31 | gem 'puppet-lint-unquoted_string-check' 32 | gem 'puppet-lint-variable_contains_upcase' 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # puppet-vault 2 | 3 | [![Build Status](https://travis-ci.org/rhoml/puppet-vault.svg?branch=master)](https://travis-ci.org/rhoml/puppet-vault) 4 | [![Puppet 5 | Forge](http://img.shields.io/puppetforge/v/rhoml/vault.svg)](https://forge.puppetlabs.com/rhoml/vault) 6 | [![Dependency Status](https://gemnasium.com/badges/github.com/rhoml/puppet-vault.svg)](https://gemnasium.com/github.com/rhoml/puppet-vault) 7 | 8 | # Overview 9 | 10 | 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. 11 | 12 | Documentation for Vault can be found on their [site](https://www.vaultproject.io/docs/config/index.html). Take into consideration: 13 | * You can only define one storage backend, listener and telemetry on the config file. 14 | * Other configurations should be set up using Vault API or CLI. 15 | 16 | # Install Vault 17 | 18 | ```` 19 | include ::vault 20 | ```` 21 | 22 | # Configure Vault using Hiera 23 | 24 | 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). 25 | 26 | ```` 27 | vault::config_hash: 28 | backend: 29 | consul: 30 | address: '127.0.0.1:8500' 31 | advertise_addr: "http://%{::ipaddress_eth0}" 32 | path: 'vault/' 33 | listener: 34 | tcp: 35 | address: "%{::fqdn}:8200" 36 | tls_disable: 1 37 | telemetry: 38 | statsite_address: '127.0.0.1:8125' 39 | disable_hostname: true 40 | disable_mlock: true 41 | vault::manage_user: true 42 | vault::package_ensure: 'latest' 43 | vault::vault_user: 'vault' 44 | vault::restart_cmd: '/etc/init.d/vault restart' 45 | ```` 46 | 47 | # Uninstalling Vault 48 | 49 | Ensure the following hiera key is present so Vault can be correctly uninstalled 50 | 51 | ``` 52 | vault::package_ensure: absent 53 | ``` 54 | 55 | # See also 56 | 57 | * [hiera-vault](https://github.com/jsok/hiera-vault) 58 | * [consul](https://github.com/solarkennedy/puppet-consul) 59 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'puppetlabs_spec_helper/rake_tasks' 2 | require 'puppet-lint/tasks/puppet-lint' 3 | 4 | PuppetLint.configuration.fail_on_warnings = true 5 | PuppetLint.configuration.send('relative') 6 | PuppetLint.configuration.send('disable_80chars') 7 | PuppetLint.configuration.relative = true 8 | 9 | desc 'Validate manifests, templates, and ruby files' 10 | task :validate do 11 | Dir['manifests/**/*.pp'].each do |manifest| 12 | sh "puppet parser validate --noop #{manifest}" 13 | end 14 | Dir['spec/**/*.rb','lib/**/*.rb'].each do |ruby_file| 15 | sh "ruby -c #{ruby_file}" unless ruby_file =~ /spec\/fixtures/ 16 | end 17 | Dir['templates/**/*.erb'].each do |template| 18 | sh "erb -P -x -T '-' #{template} | ruby -c" 19 | end 20 | end 21 | 22 | PuppetLint::RakeTask.new :lint do |config| 23 | # Pattern of files to check, defaults to `**/*.pp` 24 | config.pattern = 'manifests/**/*.pp' 25 | 26 | # Should the task fail if there were any warnings, defaults to false 27 | config.fail_on_warnings = true 28 | 29 | # Format string for puppet-lint's output (see the puppet-lint help output 30 | # for details 31 | config.log_format = '%{filename} - %{message}' 32 | 33 | # Print out the context for the problem, defaults to false 34 | config.with_context = true 35 | 36 | # Enable automatic fixing of problems, defaults to false 37 | config.fix = true 38 | 39 | # Show ignored problems in the output, defaults to false 40 | config.show_ignored = false 41 | 42 | # Compare module layout relative to the module root 43 | config.relative = true 44 | end 45 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | vault::config_hash: 3 | backend: 4 | consul: 5 | advertise_addr: "http://%{::ipaddress}" 6 | path: 'vault/' 7 | listener: 8 | tcp: 9 | address: "%{::fqdn}:8200" 10 | tls_disable: 1 11 | telemetry: 12 | statsite_address: '%{::ipaddress}:8125' 13 | disable_hostname: true 14 | disable_mlock: true 15 | vault::manage_user: true 16 | vault::package_ensure: present 17 | vault::version: 0.5.2 18 | vault::vault_user: vault 19 | vault::restart_cmd: '/etc/init.d/vault restart' 20 | -------------------------------------------------------------------------------- /data/hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 4 3 | 4 | datadir: hieradata 5 | 6 | :hierarchy: 7 | - osfamily/%{::osfamily} 8 | - common 9 | -------------------------------------------------------------------------------- /lib/puppet/parser/functions/sorted_json.rb: -------------------------------------------------------------------------------- 1 | # Puppet parser function for outputting JSON-formatted objects, in a sorted consistent way. 2 | # Credit: @falzm 3 | # https://gist.github.com/falzm/8575549 4 | require 'json' 5 | 6 | def sorted_json(obj) 7 | case obj 8 | when String, Fixnum, Float, TrueClass, FalseClass, NilClass 9 | return obj.to_json 10 | when Array 11 | arrayRet = [] 12 | obj.each do |a| 13 | arrayRet.push(sorted_json(a)) 14 | end 15 | return "[" << arrayRet.join(',') << "]"; 16 | when Hash 17 | ret = [] 18 | obj.keys.sort.each do |k| 19 | ret.push(k.to_json << ":" << sorted_json(obj[k])) 20 | end 21 | return "{" << ret.join(",") << "}"; 22 | else 23 | raise Exception("Unable to handle object of type <%s>" % obj.class.to_s) 24 | end 25 | end 26 | 27 | module Puppet::Parser::Functions 28 | newfunction(:sorted_json, :type => :rvalue, :doc => <<-EOS 29 | This function takes data, outputs making sure the hash keys are sorted 30 | 31 | *Examples:* 32 | 33 | sorted_json({'key'=>'value'}) 34 | 35 | Would return: {'key':'value'} 36 | EOS 37 | ) do |arguments| 38 | raise(Puppet::ParseError, "sorted_json(): Wrong number of arguments " + 39 | "given (#{arguments.size} for 1)") if arguments.size != 1 40 | 41 | json = arguments[0] 42 | return sorted_json(json) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /manifests/config.pp: -------------------------------------------------------------------------------- 1 | # Class to configure vault 2 | class vault::config ( 3 | $config_hash = $::vault::config_hash, 4 | $manage_user = $::vault::manage_user, 5 | $vault_user = $::vault::vault_user, 6 | ){ 7 | 8 | if $manage_user { 9 | 10 | group { $vault_user: 11 | ensure => 'present', 12 | } 13 | 14 | user { $vault_user: 15 | ensure => 'present', 16 | gid => $vault_user, 17 | require => Group['vault'], 18 | } 19 | } 20 | 21 | file { '/etc/init.d/vault': 22 | ensure => 'file', 23 | mode => '0755', 24 | owner => 'root', 25 | group => 'root', 26 | content => template('vault/init-script.erb'), 27 | notify => Class['::vault::service'], 28 | require => Package['vault'], 29 | } 30 | 31 | file { '/etc/vault': 32 | ensure => 'directory', 33 | mode => '0755', 34 | owner => 'root', 35 | group => 'root', 36 | purge => true, 37 | recurse => true, 38 | require => Package['vault'], 39 | } 40 | 41 | file { '/etc/vault/vault.json': 42 | ensure => 'file', 43 | mode => '0644', 44 | group => $vault_user, 45 | owner => $vault_user, 46 | content => sorted_json($config_hash), 47 | notify => Class['::vault::service'], 48 | require => [ File['/etc/vault'], 49 | File['/etc/init.d/vault'] ], 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Class: vault 2 | # =========================== 3 | # 4 | # Full description of class vault here. 5 | # 6 | # Usage 7 | # ----- 8 | # 9 | # class { 'vault': 10 | # config_hash => { 11 | # 'backend' => { 12 | # 'github' => { 13 | # 'token' => '' 14 | # } 15 | # }, 16 | # 'listener' => { 17 | # 'tcp' => { 18 | # 'address' => '127.0.0.1:8200', 19 | # 'tls_disable' => 1 20 | # } 21 | # }, 22 | # 'telemetry' => { 23 | # 'statsite_address' => '127.0.0.1:8125' 24 | # }, 25 | # 'disable_hostname' => true, 26 | # 'disable_mlock' => false 27 | # } 28 | # } 29 | # 30 | # 31 | # Authors 32 | # ------- 33 | # 34 | # Rhommel Lamas 35 | # Twitter: @rhoml 36 | # IRC #freenode: @rhoml 37 | # 38 | # 39 | # Copyright 40 | # --------- 41 | # 42 | # Copyright 2015 Rhommel Lamas, unless otherwise noted. 43 | # 44 | class vault ( 45 | $config_hash = {}, 46 | $manage_user = undef, 47 | $package_ensure = 'present', 48 | $restart_cmd = '/etc/init.d/vault restart', 49 | $service_ensure = 'running', 50 | $service_enable = true, 51 | $vault_user = 'vault', 52 | $version = '0.5.2' 53 | ){ 54 | 55 | validate_re($package_ensure, [ '^present$', '^absent$' ], 56 | '\$package_ensure should be \'present\' or \'purged\'.') 57 | 58 | validate_hash($config_hash) 59 | 60 | if $package_ensure == 'present' { 61 | class {'::vault::install': } 62 | -> 63 | class {'::vault::config': } 64 | ~> 65 | class{'::vault::service': } 66 | } else { 67 | class {'::vault::install': } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /manifests/install.pp: -------------------------------------------------------------------------------- 1 | # Class to install Hashicorp Vault 2 | class vault::install( 3 | $package_ensure = $::vault::package_ensure, 4 | $vault_user = $::vault::vault_user, 5 | $version = $::vault::version, 6 | ) { 7 | 8 | case $::osfamily { 9 | /(Debian|Ubuntu)/: { 10 | $real_provider = 'aptitude' 11 | } 12 | default: { 13 | fail("\"${module_name}\" We don't support \"${::osfamily}\"") 14 | } 15 | } 16 | 17 | $vault_ensure = $package_ensure ? { 18 | 'absent' => 'purged', 19 | default => $version, 20 | } 21 | 22 | package { 'vault': 23 | ensure => $vault_ensure, 24 | provider => $real_provider, 25 | } 26 | 27 | # If we are uninstalling Vault we should remove 28 | # all its dependencies 29 | if $package_ensure == 'absent' { 30 | group { $vault_user: 31 | ensure => $package_ensure, 32 | } 33 | 34 | user { $vault_user: 35 | ensure => $package_ensure, 36 | } 37 | 38 | file { '/etc/init.d/vault': 39 | ensure => $package_ensure, 40 | } 41 | 42 | file { '/etc/vault': 43 | ensure => $package_ensure, 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /manifests/service.pp: -------------------------------------------------------------------------------- 1 | # Class to manage vault service 2 | class vault::service( 3 | $restart_cmd = $::vault::restart_cmd, 4 | $service_ensure = $::vault::service_ensure, 5 | $service_enable = $::vault::service_enable 6 | ){ 7 | service { 8 | 'vault': 9 | ensure => $service_ensure, 10 | enable => $service_enable, 11 | hasstatus => true, 12 | hasrestart => true, 13 | restart => $restart_cmd, 14 | require => File['/etc/vault/vault.json'], 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rhoml/vault", 3 | "version": "0.0.4", 4 | "author": "Rhommel Lamas", 5 | "email": "roml@rhommell.com", 6 | "license": "MIT", 7 | "summary": "Installs and configure Hashicorp Vault project", 8 | "source": "https://github.com/rhoml/puppet-vault", 9 | "project_page": "https://github.com/rhoml/puppet-vault", 10 | "issues_url": "https://github.com/rhoml/puppet-vault/issues", 11 | "tags": ["hashicorp", "vault"], 12 | "operatingsystem_support": [{ 13 | "operatingsystem": "Ubuntu", 14 | "operatingsystemrelease": ["12.04", "10.04"] 15 | }, 16 | { 17 | "operatingsystem": "Debian", 18 | "operatingsystemrelease": ["6", "7"] 19 | }], 20 | "dependencies": [{ 21 | "name": "puppetlabs/stdlib", 22 | "version_requirement": ">= 2.2.1" 23 | }], 24 | "data_provider": "hiera" 25 | } 26 | -------------------------------------------------------------------------------- /spec/classes/init_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'vault' do 4 | context 'with defaults for all parameters' do 5 | it { should compile.with_all_deps } 6 | 7 | let(:facts) { 8 | { 9 | osfamily: 'Debian', 10 | operatingsystem: 'Debian', 11 | lsbdistcodename: 'wheezy', 12 | manage_user: true, 13 | } 14 | } 15 | 16 | it { should contain_class('vault') } 17 | 18 | end 19 | 20 | context 'installs and configure vault' do 21 | let(:facts) { 22 | { 23 | osfamily: 'Debian', 24 | operatingsystem: 'Debian', 25 | lsbdistcodename: 'wheezy', 26 | manage_user: true, 27 | } 28 | } 29 | 30 | let (:params) { 31 | { 32 | :package_ensure => 'present', 33 | :vault_user => 'vault', 34 | :version => '0.5.2' 35 | } 36 | } 37 | 38 | it { is_expected.to contain_class('vault::install') } 39 | it { is_expected.to contain_class('vault::config') } 40 | it { is_expected.to contain_class('vault::service') } 41 | 42 | end 43 | 44 | context 'uninstall vault from the system' do 45 | let(:facts) { 46 | { 47 | osfamily: 'Debian', 48 | operatingsystem: 'Debian', 49 | lsbdistcodename: 'wheezy', 50 | manage_user: true, 51 | } 52 | } 53 | 54 | let (:params) { 55 | { 56 | :package_ensure => 'absent', 57 | :vault_user => 'vault', 58 | :version => '0.5.2' 59 | } 60 | } 61 | 62 | it { is_expected.to contain_class('vault::install') } 63 | 64 | end 65 | 66 | end 67 | -------------------------------------------------------------------------------- /spec/classes/vault_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'vault::config', :type => :class do 4 | context "On a Debian OS" do 5 | let :facts do 6 | { 7 | :osfamily => 'Debian', 8 | :operatingsystemrelease => '7', 9 | :concat_basedir => '/tmp', 10 | :lsbdistid => 'Debian', 11 | } 12 | 13 | end 14 | 15 | context "user and group exist for vault if manage users is set to true" do 16 | let (:params) { 17 | { 18 | :vault_user => 'vault', 19 | :manage_user => true 20 | } 21 | } 22 | 23 | it { should contain_group('vault').with_ensure('present') } 24 | 25 | it { should contain_user('vault').with( 26 | 'ensure' => 'present', 27 | 'gid' => 'vault' 28 | ) } 29 | end 30 | 31 | context "vault init should be created" do 32 | it { should contain_file('/etc/init.d/vault').with( 33 | 'ensure' => 'file', 34 | 'mode' => '0755', 35 | 'owner' => 'root', 36 | 'group' => 'root', 37 | ) } 38 | end 39 | 40 | context "vault config dir" do 41 | it { should contain_file('/etc/vault').with( 42 | 'ensure' => 'directory', 43 | 'mode' => '0755', 44 | 'owner' => 'root', 45 | 'group' => 'root', 46 | 'purge' => true, 47 | 'recurse' => true 48 | ) } 49 | end 50 | 51 | context "vault config file" do 52 | let (:params) {{:vault_user => 'vault'}} 53 | it { should contain_file('/etc/vault/vault.json').with( 54 | 'ensure' => 'file', 55 | 'mode' => '0644', 56 | 'owner' => 'vault', 57 | 'group' => 'vault', 58 | ).that_requires( 59 | 'File[/etc/vault]' 60 | ).that_requires( 61 | 'File[/etc/init.d/vault]' 62 | ) } 63 | end 64 | 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /spec/classes/vault_install_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'vault::install', :type => :class do 4 | context "On a Debian OS" do 5 | let :facts do 6 | { 7 | :osfamily => 'Debian', 8 | :operatingsystemrelease => '7', 9 | :concat_basedir => '/tmp', 10 | :lsbdistid => 'Debian', 11 | } 12 | 13 | end 14 | 15 | context "install vault when version is set" do 16 | let (:params) { 17 | { 18 | :package_ensure => 'present', 19 | :version => '0.5.2', 20 | } 21 | } 22 | it { should contain_package('vault').with( 23 | 'ensure' => '0.5.2', 24 | 'provider' => 'aptitude' 25 | ) } 26 | end 27 | 28 | context "uninstall vault when package_ensure is set to absent" do 29 | let (:params) { 30 | { 31 | :package_ensure => 'absent', 32 | :vault_user => 'vault' 33 | } 34 | } 35 | 36 | it { should contain_package('vault').with( 37 | 'ensure' => 'purged' 38 | ) } 39 | end 40 | 41 | context "remove vault group" do 42 | let (:params) { 43 | { 44 | :package_ensure => 'absent', 45 | :vault_user => 'vault' 46 | } 47 | } 48 | 49 | it { should contain_group('vault').with( 50 | 'ensure' => 'absent' 51 | ) } 52 | end 53 | 54 | context "remove vault user" do 55 | let (:params) { 56 | { 57 | :package_ensure => 'absent', 58 | :vault_user => 'vault' 59 | } 60 | } 61 | 62 | it { should contain_user('vault').with( 63 | 'ensure' => 'absent' 64 | ) } 65 | end 66 | 67 | context "remove vault init script" do 68 | let (:params) { 69 | { 70 | :package_ensure => 'absent', 71 | :vault_user => 'vault' 72 | } 73 | } 74 | 75 | it { should contain_file('/etc/init.d/vault').with( 76 | 'ensure' => 'absent' 77 | ) } 78 | end 79 | 80 | context "remove vault config directory" do 81 | let (:params) { 82 | { 83 | :package_ensure => 'absent', 84 | :vault_user => 'vault' 85 | } 86 | } 87 | 88 | it { should contain_file('/etc/vault').with( 89 | 'ensure' => 'absent' 90 | ) } 91 | end 92 | 93 | 94 | end 95 | end 96 | -------------------------------------------------------------------------------- /spec/classes/vault_service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'vault::service', :type => :class do 4 | context "On a Debian OS" do 5 | let :facts do 6 | { 7 | :osfamily => 'Debian', 8 | :operatingsystemrelease => '7', 9 | :concat_basedir => '/tmp', 10 | :lsbdistid => 'Debian', 11 | } 12 | end 13 | 14 | context "vault running and enabled" do 15 | let (:params) { 16 | { 17 | :restart_cmd => '/etc/init.d/vault restart', 18 | :service_ensure => 'running', 19 | :service_enable => true 20 | } 21 | } 22 | it { should contain_service("vault").with( 23 | 'ensure' => 'running', 24 | 'enable' => 'true', 25 | 'hasstatus' => 'true', 26 | 'hasrestart' => 'true', 27 | 'restart' => '/etc/init.d/vault restart' 28 | ) 29 | } 30 | end 31 | 32 | context "vault running and disabled" do 33 | let (:params) { 34 | { 35 | :restart_cmd => '/etc/init.d/vault restart', 36 | :service_ensure => 'running', 37 | :service_enable => false 38 | } 39 | } 40 | it { should contain_service("vault").with( 41 | 'ensure' => 'running', 42 | 'enable' => 'false', 43 | 'hasstatus' => 'true', 44 | 'hasrestart' => 'true', 45 | 'restart' => '/etc/init.d/vault restart' 46 | ) 47 | } 48 | end 49 | 50 | context "vault stopped but enabled" do 51 | let (:params) { 52 | { 53 | :restart_cmd => '/etc/init.d/vault restart', 54 | :service_ensure => 'stopped', 55 | :service_enable => true 56 | } 57 | } 58 | it { should contain_service("vault").with( 59 | 'ensure' => 'stopped', 60 | 'enable' => 'true', 61 | 'hasstatus' => 'true', 62 | 'hasrestart' => 'true', 63 | 'restart' => '/etc/init.d/vault restart' 64 | ) 65 | } 66 | end 67 | 68 | context "vault stopped and disabled" do 69 | let (:params) { 70 | { 71 | :restart_cmd => '/etc/init.d/vault restart', 72 | :service_ensure => 'stopped', 73 | :service_enable => false 74 | } 75 | } 76 | it { should contain_service("vault").with( 77 | 'ensure' => 'stopped', 78 | 'enable' => 'false', 79 | 'hasstatus' => 'true', 80 | 'hasrestart' => 'true', 81 | 'restart' => '/etc/init.d/vault restart' 82 | ) 83 | } 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'puppetlabs_spec_helper/module_spec_helper' 2 | -------------------------------------------------------------------------------- /templates/init-script.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ### BEGIN INIT INFO 3 | # Provides: vault 4 | # Required-Start: $local_fs $remote_fs 5 | # Required-Stop: $local_fs $remote_fs 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: S 0 1 6 8 | # Short-Description: Vault secrets management framework 9 | # Description: Stores, generates, and manages secrets. 10 | ### END INIT INFO 11 | 12 | PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH 13 | DESC="Vault secrets management framework" 14 | NAME=vault 15 | DAEMON=/usr/bin/$NAME 16 | PIDFILE=/var/run/$NAME.pid 17 | DAEMON_ARGS=( server -config=/etc/vault/vault.json ) 18 | USER=<%= @vault_user %> 19 | SCRIPTNAME=/etc/init.d/$NAME 20 | 21 | # Exit if the package is not installed 22 | [ -x "$DAEMON" ] || exit 0 23 | 24 | # Read configuration variable file if it is present 25 | [ -r "/etc/default/$NAME" ] && . "/etc/default/$NAME" 26 | 27 | # Load the VERBOSE setting and other rcS variables 28 | [ -f /etc/default/rcS ] && . /etc/default/rcS 29 | 30 | # Define LSB log_* functions. 31 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. 32 | . /lib/lsb/init-functions 33 | 34 | # 35 | # Function that starts the daemon/service 36 | # 37 | do_start() 38 | { 39 | # Return 40 | # 0 if daemon has been started 41 | # 1 if daemon was already running 42 | # 2 if daemon could not be started 43 | echo -e "Starting vault and backgrounding\n" 44 | start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" --chuid "$USER" --background --make-pidfile --test > /dev/null \ 45 | || return 1 46 | start-stop-daemon --start --quiet --pidfile "$PIDFILE" --exec "$DAEMON" --chuid "$USER" --background --make-pidfile -- \ 47 | "${DAEMON_ARGS[@]}" \ 48 | || return 2 49 | } 50 | # 51 | # Function that stops the daemon/service 52 | # 53 | do_stop() 54 | { 55 | # Return 56 | # 0 if daemon has been stopped 57 | # 1 if daemon was already stopped 58 | # 2 if daemon could not be stopped 59 | # other if a failure occurred 60 | start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile "$PIDFILE" --name "$NAME" 61 | RETVAL="$?" 62 | [ "$RETVAL" = 2 ] && return 2 63 | # Wait for children to finish too if this is a daemon that forks 64 | # and if the daemon is only ever run from this initscript. 65 | # If the above conditions are not satisfied then add some other code 66 | # that waits for the process to drop all resources that could be 67 | # needed by services started subsequently. A last resort is to 68 | # sleep for some time. 69 | start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec "$DAEMON" 70 | [ "$?" = 2 ] && return 2 71 | # Many daemons don't delete their pidfiles when they exit. 72 | rm -f "$PIDFILE" 73 | return "$RETVAL" 74 | } 75 | 76 | # 77 | # Function that sends a SIGHUP to the daemon/service 78 | # 79 | do_reload() { 80 | # 81 | # If the daemon can reload its configuration without 82 | # restarting (for example, when it is sent a SIGHUP), 83 | # then implement that here. 84 | # 85 | start-stop-daemon --stop --signal 1 --quiet --pidfile "$PIDFILE" --name "$NAME" 86 | return 0 87 | } 88 | 89 | case "$1" in 90 | start) 91 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" 92 | do_start 93 | case "$?" in 94 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 95 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 96 | esac 97 | ;; 98 | stop) 99 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" 100 | do_stop 101 | case "$?" in 102 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 103 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; 104 | esac 105 | ;; 106 | restart|force-reload) 107 | # 108 | # If the "reload" option is implemented then remove the 109 | # 'force-reload' alias 110 | # 111 | log_daemon_msg "Restarting $DESC" "$NAME" 112 | do_stop 113 | case "$?" in 114 | 0|1) 115 | do_start 116 | case "$?" in 117 | 0) log_end_msg 0 ;; 118 | 1) log_end_msg 1 ;; # Old process is still running 119 | *) log_end_msg 1 ;; # Failed to start 120 | esac 121 | ;; 122 | *) 123 | # Failed to stop 124 | log_end_msg 1 125 | ;; 126 | esac 127 | ;; 128 | status) 129 | status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $? 130 | ;; 131 | *) 132 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 133 | exit 3 134 | ;; 135 | esac 136 | 137 | : 138 | -------------------------------------------------------------------------------- /tests/init.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here: 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | include ::vault 13 | --------------------------------------------------------------------------------