diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..83e16f8 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/.travis.yml b/.travis.yml index 952e71e..d56e144 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,11 @@ rvm: - 2.2.0 cache: bundler +before_install: |- + wget -O vault.zip -q https://releases.hashicorp.com/vault/0.6.0/vault_0.6.0_linux_amd64.zip + unzip vault.zip -d $HOME/bin + export PATH="$HOME/bin:$PATH" + deploy: provider: rubygems on: diff --git a/Gemfile b/Gemfile index 2b245b5..6d07894 100644 --- a/Gemfile +++ b/Gemfile @@ -2,4 +2,10 @@ source "http://rubygems.org" gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.8' gem "vault", '~> 0.4' -gem "rake" +gem "rake", '~> 11.1' + +group :development, :test do + gem 'rspec', "~> 3.3", :require => false + gem "rspec-legacy_formatters", "~> 1.0", :require => false + gem 'mocha', "~> 0.10.5", :require => false +end diff --git a/Gemfile.lock b/Gemfile.lock index aa651a5..b48646d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,22 +2,44 @@ GEM remote: http://rubygems.org/ specs: CFPropertyList (2.2.8) + diff-lcs (1.2.5) facter (2.4.6) CFPropertyList (~> 2.2.6) hiera (1.3.4) json_pure json_pure (1.8.3) + metaclass (0.0.4) + mocha (0.10.5) + metaclass (~> 0.0.1) puppet (3.8.6) facter (> 1.6, < 3) hiera (~> 1.0) json_pure rake (11.1.2) + rspec (3.4.0) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-core (3.4.4) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-legacy_formatters (1.0.1) + rspec (~> 3.0) + rspec-mocks (3.4.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) vault (0.4.0) PLATFORMS ruby DEPENDENCIES + mocha (~> 0.10.5) puppet (~> 3.8) - rake + rake (~> 11.1) + rspec (~> 3.3) + rspec-legacy_formatters (~> 1.0) vault (~> 0.4) diff --git a/Rakefile b/Rakefile index 18d83fe..24faa41 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,9 @@ -task :default do - puts "TBD: https://github.com/jsok/hiera-vault/issues/17" +require 'rake' +require 'rspec/core/rake_task' + +RSpec::Core::RakeTask.new(:spec) do |t| + t.pattern = Dir.glob('spec/**/*_spec.rb') + t.rspec_opts = '--format documentation' end + +task :default => :spec diff --git a/spec/integration/vault_backend_spec.rb b/spec/integration/vault_backend_spec.rb new file mode 100644 index 0000000..0bb0c7b --- /dev/null +++ b/spec/integration/vault_backend_spec.rb @@ -0,0 +1,44 @@ +require 'spec_helper' +require 'hiera/backend/vault_backend' + +class Hiera + module Backend + describe Vault_backend do + + before do + Hiera.stubs(:debug) + Hiera.stubs(:warn) + Hiera::Backend.stubs(:empty_answer).returns(nil) + RSpec::VaultServer.token + end + + describe '#initialize' do + it "should work with valid config" do + Config.load({:vault => { + :addr => RSpec::VaultServer.address + }}) + Vault_backend.new + end + + it "should validate :default_field_parse" do + Config.load({:vault => {:default_field_parse => 'invalid'}}) + expect { Vault_backend.new }.to raise_error /invalid value for :default_field_parse/ + end + + it "should validate :default_field_behavior" do + Config.load({:vault => {:default_field_behavior => 'invalid'}}) + expect { Vault_backend.new }.to raise_error /invalid value for :default_field_behavior/ + end + + it "should skip backend on configuration error" do + Vault::Client.stubs(:new).raises(Exception) + Hiera.expects(:warn).with(regexp_matches /Skipping backend/).once + + Config.load({:vault => {}}) + Vault_backend.new + end + end + + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..7adc051 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,13 @@ +$:.insert(0, File.join([File.dirname(__FILE__), "..", "lib"])) + +require 'rubygems' +require 'rspec' +require 'mocha' +require 'hiera' +require 'vault' + +require_relative "support/vault_server" + +RSpec.configure do |config| + config.mock_with :mocha +end diff --git a/spec/support/vault_server.rb b/spec/support/vault_server.rb new file mode 100644 index 0000000..9338d88 --- /dev/null +++ b/spec/support/vault_server.rb @@ -0,0 +1,79 @@ +### +# Graciously copied from https://github.com/hashicorp/vault-ruby/blob/master/spec/support/vault_server.rb +#### + +require "open-uri" +require "singleton" +require "timeout" +require "tempfile" + +module RSpec + class VaultServer + include Singleton + + TOKEN_PATH = File.expand_path("~/.vault-token").freeze + TOKEN_PATH_BKUP = "#{TOKEN_PATH}.bak".freeze + + def self.method_missing(m, *args, &block) + self.instance.public_send(m, *args, &block) + end + + attr_reader :token + attr_reader :unseal_token + + def initialize + # If there is already a vault-token, we need to move it so we do not + # clobber! + if File.exist?(TOKEN_PATH) + FileUtils.mv(TOKEN_PATH, TOKEN_PATH_BKUP) + at_exit do + FileUtils.mv(TOKEN_PATH_BKUP, TOKEN_PATH) + end + end + + io = Tempfile.new("vault-server") + pid = Process.spawn({}, "vault server -dev", out: io.to_i, err: io.to_i) + + at_exit do + Process.kill("INT", pid) + Process.waitpid2(pid) + + io.close + io.unlink + end + + wait_for_ready do + @token = File.read(TOKEN_PATH) + + output = "" + while + io.rewind + output = io.read + break if !output.empty? + end + + if output.match(/Unseal Key: (.+)/) + @unseal_token = $1.strip + else + raise "Vault did not return an unseal token!" + end + end + end + + def address + "http://127.0.0.1:8200" + end + + def wait_for_ready(&block) + Timeout.timeout(5) do + while !File.exist?(TOKEN_PATH) + sleep(0.25) + end + end + + yield + rescue Timeout::Error + raise "Vault did not start in 5 seconds!" + end + end +end