chef-vault-testfixtures 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40a722deedcbf099b45c88908a5a220547084dc6
4
+ data.tar.gz: aa04d1e8e99a94b72ee12fba6e3541b81f3cc21b
5
+ SHA512:
6
+ metadata.gz: 33644416bda7fda97172ba9e79216d0ba7c2f930cbcf3ed1ee3b75dcf2938bb753ad49ef75089ae3dd7a18bda7064f9e14051c695f66135b24edc89e0e7e4552
7
+ data.tar.gz: a81fc11dac06193f59aee78a88f9ea2ae1ae9eb7ecdf0f4d03c0da0d76a03bf94f19bf2910e79421f1f4e82bfb4c1d140668d2f71bad0072dbdaaae75b21c941
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,14 @@
1
+ AllCops:
2
+ Exclude:
3
+ - '**/Gemfile'
4
+ - '**/*.gemspec'
5
+
6
+ Style/RegexpLiteral:
7
+ Exclude:
8
+ - '**/Guardfile'
9
+
10
+ Style/Documentation:
11
+ Exclude:
12
+ - 'spec/**/*.rb'
13
+ - lib/chef-vault/test_fixtures/version.rb
14
+ - lib/hoe/markdown.rb
@@ -0,0 +1,4 @@
1
+ -
2
+ README.rdoc
3
+ History.rdoc
4
+ lib/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gemspec
@@ -0,0 +1,16 @@
1
+ # prevent dropping into pry when nothing is happening
2
+ interactor :off
3
+
4
+ guard :rubocop, all_on_start: true, cli: ['-D'] do
5
+ watch(%r{bin/.+$})
6
+ watch(%r{.+\.rb$})
7
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
8
+ watch('Gemfile')
9
+ watch('Rakefile')
10
+ end
11
+
12
+ guard :rspec, all_on_start: true, cmd: 'bundle exec rescue rspec' do
13
+ watch(%r{^spec/(.+)_spec\.rb$})
14
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
15
+ watch(%r{^spec/spec_helper.*\.rb$}) { 'spec' }
16
+ end
@@ -0,0 +1,10 @@
1
+ # Changelog for chef-vault-testfixtures
2
+
3
+ ## 0.1.1
4
+
5
+ * fix disconnect between docs and code for shared context method
6
+ * remove Hoe test plugin so we don't double up on test runs
7
+
8
+ ## 0.1.0
9
+
10
+ * initial version
@@ -0,0 +1,16 @@
1
+ .rspec
2
+ .rubocop.yml
3
+ .yardopts
4
+ Gemfile
5
+ Guardfile
6
+ History.md
7
+ Manifest.txt
8
+ README.md
9
+ Rakefile
10
+ chef-vault-testfixtures.gemspec
11
+ lib/chef-vault/test_fixtures.rb
12
+ lib/hoe/markdown.rb
13
+ spec/lib/chef-vault/test_fixtures_spec.rb
14
+ spec/spec_helper.rb
15
+ spec/support/chef-vault/test_fixtures/bar.rb
16
+ spec/support/chef-vault/test_fixtures/foo.rb
@@ -0,0 +1,207 @@
1
+ # chef-vault-testfixtures
2
+
3
+ * home :: https://github.com/Nordstrom/chef-vault-testfixtures
4
+ * license :: [Apache2](http://www.apache.org/licenses/LICENSE-2.0)
5
+
6
+ ## DESCRIPTION
7
+
8
+ chef-vault-testfixtures provides an RSpec shared context that
9
+ dynamically stubs access to chef-vault encrypted data bags.
10
+
11
+ chef-vault is a gem to manage distribution and control of keys to
12
+ decrypt Chef encrypted data bags.
13
+
14
+ When testing a cookbook that uses chef-vault, encryption is generally
15
+ out of scope, which results in a large amount of stubs or mocks so that you get back fixture data without performing decryption.
16
+
17
+ This gem makes testing Chef cookbooks easier using ChefSpec by
18
+ dynamically stubbing attempts to access vault data to return invalid
19
+ (i.e. not real passwords for any of your environments) that are properly
20
+ formatted (e.g. a vault item containing an RSA key really contains one)
21
+
22
+ The intended use case is that for each group of distinct secrets
23
+ (e.g. an application stack, or a development team) you create one or
24
+ more plugins. The plugins contain data that is specific to your
25
+ application.
26
+
27
+ Since plugins can be whitelisted or blacklisted when the shared
28
+ context is created, this makes it easy to only include the appropriate
29
+ secrets in a given cookbook's tests.
30
+
31
+ Attempts to access secrets that would not be available to a node
32
+ during a real chef-client run will not be mocked, which will cause
33
+ the double to raise an 'unexpected message received' error.
34
+
35
+ ## SYNOPSIS
36
+
37
+ In the file `spec/support/chef-vault/test_fixtures/foo.rb`:
38
+
39
+ class ChefVault
40
+ class TestFixtures
41
+ class Foo
42
+ def bar
43
+ { 'baz' => 2 }
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ In your cookbook Gemfile:
50
+
51
+ gem 'chef-vault-testfixtures', '~> 0.1'
52
+
53
+ In your cookbook `spec/spec_helper.rb`:
54
+
55
+ require 'chef-vault/test_fixtures'
56
+
57
+ In a cookbook example:
58
+
59
+ RSpec.describe 'my_cookbook::default' do
60
+ include ChefVault::TestFixtures.rspec_shared_context
61
+
62
+ let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) }
63
+
64
+ it 'should converge' do
65
+ expect(chef_run).to include_recipe(described_recipe)
66
+ end
67
+ end
68
+
69
+ The recipe that the example tests:
70
+
71
+ chef_gem 'chef-vault' do
72
+ compile_time true if respond_to?(:compile_time)
73
+ end
74
+ require 'chef-vault'
75
+ item = ChefVault::Item.load('foo', 'bar')
76
+ file '/tmp/foo' do
77
+ contents item['password']
78
+ end
79
+
80
+ The call to `ChefVault::Item.load` will be stubbed so that you don't
81
+ need pre-encrypted data or private keys to run your specs.
82
+
83
+ ## PLUGINS
84
+
85
+ This gem uses [little-plugger](https://rubygems.org/gems/little-plugger)
86
+ to make adding vault fixtures easy. Each data bag needs a plugin
87
+ named using [little-pluggers's rules](https://github.com/TwP/little-plugger/blob/master/lib/little-plugger.rb#L13-24).
88
+
89
+ The plugin must define a class inside the naming hierarchy
90
+ `ChefVault::TestFixtures::`. The class name should be the filename
91
+ converted to CamelCase (e.g. `foo_bar.rb` = `FooBar`)
92
+
93
+ Inside of the plugin, define a class method for each vault item you
94
+ want to stub. The method must return a Hash, which contains the
95
+ vault data.
96
+
97
+ For example, if you wanted to stub the data bag item foo/bar, you would
98
+ create the class `ChefVault::TestFixtures::Foo` and inside define a class method `bar`.
99
+
100
+ ### ALIASING VAULT ITEMS
101
+
102
+ If you want your vault to return the same data for two different
103
+ vault items, just alias the method:
104
+
105
+ class ChefVault
106
+ class TestFixtures
107
+ class MyApp
108
+ def test
109
+ { 'baz' => 1 }
110
+ end
111
+
112
+ alias_method :prod, :test
113
+ end
114
+ end
115
+ end
116
+
117
+ Now you will get the same value for:
118
+
119
+ ChefVault::Item.load('my_app', 'test')['baz']
120
+
121
+ as you do from
122
+
123
+ ChefVault::Item.load('my_app', 'prod')['baz']
124
+
125
+ This can be useful when your vaults use `node.chef_environment`
126
+ (or a derivative thereof) for the item name.
127
+
128
+ ## FINDING VAULTS
129
+
130
+ LittlePlugger loads any files in any installed gem that match
131
+ the pathspec `lib/chef-vault/test_fixtures/*.rb`. Plugin classes
132
+ that are loaded using 'require' are also available as vaults.
133
+
134
+ You can bundle one or more plugins as a gem that you can distribute
135
+ publicly or privately, or you can distribute them baked into your cookbook.
136
+
137
+ For example, in a cookbook create the file `spec/support/chef-vault/test_fixtures/foo.rb`
138
+ with the same contents as above. LittlePlugger will not find
139
+ this automatically because it's not part of an installed gem, but
140
+ by requiring it from your `spec/spec_helper.rb`:
141
+
142
+ require 'support/chef-vault/test_fixtures/foo'
143
+
144
+ It will be available when `ChefVault::TestFixtures.rspec_shared_context` is called.
145
+
146
+ Note that LittlePlugger excludes any plugins that have a class name
147
+ all in capitals (because it assumes those are constants). A plugin
148
+ for database secrets should be named `Db` instead of `DB`. However,
149
+ this is only of interest to plugin authors. When selecting the plugins
150
+ to load, the names are always lowercase symbols.
151
+
152
+ ## LISTING VAULTS
153
+
154
+ To get a list of the stubbed vaults, call
155
+
156
+ ChefVault::TestFixtures.load_plugins
157
+ list = ChefVault::TestFixtures.plugins.keys
158
+
159
+ The return from `::plugins` is a hash of plugin names (as symbols)
160
+ to the class or module that provide them.
161
+
162
+ The plugin name is always a lowercase symbol.
163
+
164
+ ## RESTRICTING WHICH VAULTS ARE USED
165
+
166
+ Thanks to Little Plugger, you can change what plugins (vaults) will
167
+ be loaded the first time that `#rspec_shared_context` is called.
168
+
169
+ To only load certain plugins, call
170
+
171
+ ChefVault::TestFixtures.plugin :pluginone, :plugintwo
172
+
173
+ before calling `ChefVault::TestFixtures.rspec_shared_context`.
174
+
175
+ To prevent certain plugins from being loaded, call
176
+
177
+ ChefVault::TestFixtures.disregard_plugin :pluginthree
178
+
179
+ before calling `ChefVault::TestFixtures.rspec_shared_context`.
180
+
181
+ Note that the context is memoized on first call, so calling `::plugin` or `::disregard_plugin` after calling `::rspec_shared_context` will not change what vaults are available.
182
+
183
+ ## COMPANION COOKBOOK FOR TEST KITCHEN
184
+
185
+ A [companion cookbook](https://supermarket.chef.io/cookbooks/chef_vault_testfixtures)
186
+ is also available that uses the same data to populate vaults during
187
+ Test Kitchen integration runs.
188
+
189
+ ## AUTHOR
190
+
191
+ James FitzGibbon - james.i.fitzgibbon@nordstrom.com - @jf647
192
+
193
+ ## LICENSE
194
+
195
+ Copyright 2015 Nordstrom, Inc.
196
+
197
+ Licensed under the Apache License, Version 2.0 (the "License");
198
+ you may not use this file except in compliance with the License.
199
+ You may obtain a copy of the License at
200
+
201
+ http://www.apache.org/licenses/LICENSE-2.0
202
+
203
+ Unless required by applicable law or agreed to in writing, software
204
+ distributed under the License is distributed on an "AS IS" BASIS,
205
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
206
+ See the License for the specific language governing permissions and
207
+ limitations under the License.
@@ -0,0 +1,90 @@
1
+ require 'chef-vault/test_fixtures'
2
+
3
+ begin
4
+ require 'hoe'
5
+ require 'hoe/markdown'
6
+ Hoe.plugin :gemspec
7
+ Hoe.plugin :markdown
8
+ Hoe.plugins.delete :test
9
+ Hoe.spec 'chef-vault-testfixtures' do |s|
10
+ s.version = ChefVault::TestFixtures::VERSION
11
+ developer 'James FitzGibbon', 'james.i.fitzgibbon@nordstrom.com'
12
+ license 'apache2'
13
+ extra_deps << ['rspec', '~> 3.1']
14
+ extra_deps << ['chef-vault', '~> 2.5']
15
+ extra_deps << ['little-plugger', '~> 1.1']
16
+ extra_deps << ['chef', '>= 11.14']
17
+ extra_dev_deps << ['hoe', '~> 3.13']
18
+ extra_dev_deps << ['hoe-gemspec', '~> 1.0']
19
+ extra_dev_deps << ['rake', '~> 10.3']
20
+ extra_dev_deps << ['rspec', '~> 3.1']
21
+ extra_dev_deps << ['guard', '~> 2.12']
22
+ extra_dev_deps << ['guard-rspec', '~> 4.2']
23
+ extra_dev_deps << ['guard-rake', '~> 0.0']
24
+ extra_dev_deps << ['guard-rubocop', '~> 1.2']
25
+ extra_dev_deps << ['rubocop', '~> 0.29']
26
+ extra_dev_deps << ['simplecov', '~> 0.9']
27
+ extra_dev_deps << ['simplecov-console', '~> 0.2']
28
+ extra_dev_deps << ['pry-byebug', '~> 3.0']
29
+ extra_dev_deps << ['pry-rescue', '~> 1.3']
30
+ extra_dev_deps << ['pry-stack_explorer', '~> 0.4']
31
+ extra_dev_deps << ['yard', '~> 0.8']
32
+ end
33
+ # re-generate our gemspec before packaging
34
+ task package: 'gem:spec'
35
+ rescue LoadError
36
+ puts 'hoe not available; disabling tasks'
37
+ end
38
+
39
+ # Style Tests
40
+ begin
41
+ require 'rubocop/rake_task'
42
+ RuboCop::RakeTask.new do |t|
43
+ t.formatters = ['progress']
44
+ t.options = ['-D']
45
+ t.patterns = %w(
46
+ bin/*
47
+ lib/**/*.rb
48
+ spec/**/*.rb
49
+ ./Rakefile
50
+ )
51
+ end
52
+ desc 'Run Style Tests'
53
+ task style: [:rubocop]
54
+ rescue LoadError
55
+ puts 'rubocop not available; disabling tasks'
56
+ end
57
+
58
+ # Unit Tests
59
+ begin
60
+ require 'rspec/core/rake_task'
61
+ RSpec::Core::RakeTask.new
62
+
63
+ # Coverage
64
+ desc 'Generate unit test coverage report'
65
+ task :coverage do
66
+ ENV['COVERAGE'] = 'true'
67
+ Rake::Task[:test].invoke
68
+ end
69
+
70
+ # test is an alias for spec
71
+ desc 'runs unit tests'
72
+ task test: :spec
73
+
74
+ # default is to test everything
75
+ desc 'runs all tests'
76
+ task default: :test
77
+ rescue LoadError
78
+ puts 'rspec not available; disabling tasks'
79
+ end
80
+
81
+ # Documentation
82
+ begin
83
+ require 'yard'
84
+ require 'yard/rake/yardoc_task'
85
+ YARD::Rake::YardocTask.new(:doc) do |t|
86
+ t.stats_options = ['--list-undoc']
87
+ end
88
+ rescue LoadError
89
+ puts 'yard not available; disabling tasks'
90
+ end
@@ -0,0 +1,87 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: chef-vault-testfixtures 0.1.1.20150223230658 ruby lib
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "chef-vault-testfixtures"
6
+ s.version = "0.1.1.20150223230658"
7
+
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib"]
10
+ s.authors = ["James FitzGibbon"]
11
+ s.date = "2015-02-24"
12
+ s.description = "chef-vault-testfixtures provides an RSpec shared context that\ndynamically stubs access to chef-vault encrypted data bags.\n\nchef-vault is a gem to manage distribution and control of keys to\ndecrypt Chef encrypted data bags.\n\nWhen testing a cookbook that uses chef-vault, encryption is generally\nout of scope, which results in a large amount of stubs or mocks so that you get back fixture data without performing decryption.\n\nThis gem makes testing Chef cookbooks easier using ChefSpec by\ndynamically stubbing attempts to access vault data to return invalid\n(i.e. not real passwords for any of your environments) that are properly\nformatted (e.g. a vault item containing an RSA key really contains one)\n\nThe intended use case is that for each group of distinct secrets\n(e.g. an application stack, or a development team) you create one or\nmore plugins. The plugins contain data that is specific to your\napplication.\n\nSince plugins can be whitelisted or blacklisted when the shared\ncontext is created, this makes it easy to only include the appropriate\nsecrets in a given cookbook's tests.\n\nAttempts to access secrets that would not be available to a node\nduring a real chef-client run will not be mocked, which will cause\nthe double to raise an 'unexpected message received' error."
13
+ s.email = ["james.i.fitzgibbon@nordstrom.com"]
14
+ s.extra_rdoc_files = ["History.md", "Manifest.txt", "README.md"]
15
+ s.files = [".rspec", ".rubocop.yml", ".yardopts", "Gemfile", "Guardfile", "History.md", "Manifest.txt", "README.md", "Rakefile", "chef-vault-testfixtures.gemspec", "lib/chef-vault/test_fixtures.rb", "lib/hoe/markdown.rb", "spec/lib/chef-vault/test_fixtures_spec.rb", "spec/spec_helper.rb", "spec/support/chef-vault/test_fixtures/bar.rb", "spec/support/chef-vault/test_fixtures/foo.rb"]
16
+ s.homepage = "https://github.com/Nordstrom/chef-vault-testfixtures"
17
+ s.licenses = ["apache2"]
18
+ s.rdoc_options = ["--main", "README.md"]
19
+ s.rubygems_version = "2.4.4"
20
+ s.summary = "chef-vault-testfixtures provides an RSpec shared context that dynamically stubs access to chef-vault encrypted data bags"
21
+
22
+ if s.respond_to? :specification_version then
23
+ s.specification_version = 4
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ s.add_runtime_dependency(%q<rspec>, ["~> 3.1"])
27
+ s.add_runtime_dependency(%q<chef-vault>, ["~> 2.5"])
28
+ s.add_runtime_dependency(%q<little-plugger>, ["~> 1.1"])
29
+ s.add_runtime_dependency(%q<chef>, [">= 11.14"])
30
+ s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
31
+ s.add_development_dependency(%q<hoe>, ["~> 3.13"])
32
+ s.add_development_dependency(%q<hoe-gemspec>, ["~> 1.0"])
33
+ s.add_development_dependency(%q<rake>, ["~> 10.3"])
34
+ s.add_development_dependency(%q<guard>, ["~> 2.12"])
35
+ s.add_development_dependency(%q<guard-rspec>, ["~> 4.2"])
36
+ s.add_development_dependency(%q<guard-rake>, ["~> 0.0"])
37
+ s.add_development_dependency(%q<guard-rubocop>, ["~> 1.2"])
38
+ s.add_development_dependency(%q<rubocop>, ["~> 0.29"])
39
+ s.add_development_dependency(%q<simplecov>, ["~> 0.9"])
40
+ s.add_development_dependency(%q<simplecov-console>, ["~> 0.2"])
41
+ s.add_development_dependency(%q<pry-byebug>, ["~> 3.0"])
42
+ s.add_development_dependency(%q<pry-rescue>, ["~> 1.3"])
43
+ s.add_development_dependency(%q<pry-stack_explorer>, ["~> 0.4"])
44
+ s.add_development_dependency(%q<yard>, ["~> 0.8"])
45
+ else
46
+ s.add_dependency(%q<rspec>, ["~> 3.1"])
47
+ s.add_dependency(%q<chef-vault>, ["~> 2.5"])
48
+ s.add_dependency(%q<little-plugger>, ["~> 1.1"])
49
+ s.add_dependency(%q<chef>, [">= 11.14"])
50
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
51
+ s.add_dependency(%q<hoe>, ["~> 3.13"])
52
+ s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
53
+ s.add_dependency(%q<rake>, ["~> 10.3"])
54
+ s.add_dependency(%q<guard>, ["~> 2.12"])
55
+ s.add_dependency(%q<guard-rspec>, ["~> 4.2"])
56
+ s.add_dependency(%q<guard-rake>, ["~> 0.0"])
57
+ s.add_dependency(%q<guard-rubocop>, ["~> 1.2"])
58
+ s.add_dependency(%q<rubocop>, ["~> 0.29"])
59
+ s.add_dependency(%q<simplecov>, ["~> 0.9"])
60
+ s.add_dependency(%q<simplecov-console>, ["~> 0.2"])
61
+ s.add_dependency(%q<pry-byebug>, ["~> 3.0"])
62
+ s.add_dependency(%q<pry-rescue>, ["~> 1.3"])
63
+ s.add_dependency(%q<pry-stack_explorer>, ["~> 0.4"])
64
+ s.add_dependency(%q<yard>, ["~> 0.8"])
65
+ end
66
+ else
67
+ s.add_dependency(%q<rspec>, ["~> 3.1"])
68
+ s.add_dependency(%q<chef-vault>, ["~> 2.5"])
69
+ s.add_dependency(%q<little-plugger>, ["~> 1.1"])
70
+ s.add_dependency(%q<chef>, [">= 11.14"])
71
+ s.add_dependency(%q<rdoc>, ["~> 4.0"])
72
+ s.add_dependency(%q<hoe>, ["~> 3.13"])
73
+ s.add_dependency(%q<hoe-gemspec>, ["~> 1.0"])
74
+ s.add_dependency(%q<rake>, ["~> 10.3"])
75
+ s.add_dependency(%q<guard>, ["~> 2.12"])
76
+ s.add_dependency(%q<guard-rspec>, ["~> 4.2"])
77
+ s.add_dependency(%q<guard-rake>, ["~> 0.0"])
78
+ s.add_dependency(%q<guard-rubocop>, ["~> 1.2"])
79
+ s.add_dependency(%q<rubocop>, ["~> 0.29"])
80
+ s.add_dependency(%q<simplecov>, ["~> 0.9"])
81
+ s.add_dependency(%q<simplecov-console>, ["~> 0.2"])
82
+ s.add_dependency(%q<pry-byebug>, ["~> 3.0"])
83
+ s.add_dependency(%q<pry-rescue>, ["~> 1.3"])
84
+ s.add_dependency(%q<pry-stack_explorer>, ["~> 0.4"])
85
+ s.add_dependency(%q<yard>, ["~> 0.8"])
86
+ end
87
+ end
@@ -0,0 +1,66 @@
1
+ require 'rspec'
2
+ require 'rspec/core/shared_context'
3
+ require 'chef-vault'
4
+ require 'little-plugger'
5
+
6
+ class ChefVault
7
+ # dynamic RSpec contexts for cookbooks that use chef-vault
8
+ class TestFixtures
9
+ VERSION = '0.1.1'
10
+
11
+ extend LittlePlugger path: 'chef-vault/test_fixtures',
12
+ module: ChefVault::TestFixtures
13
+
14
+ # dynamically creates a memoized RSpec shared context
15
+ # that when included into an example group will stub
16
+ # ChefVault::Item for each of the defined vaults. The
17
+ # context is memoized and only created once
18
+ # @return [Module] the RSpec shared context
19
+ class << self
20
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
21
+ def rspec_shared_context
22
+ @context ||= begin
23
+ load_plugins
24
+ Module.new do
25
+ extend RSpec::Core::SharedContext
26
+
27
+ before do
28
+ ChefVault::TestFixtures.plugins.each do |vault, klass|
29
+ stub_vault(vault, klass)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def stub_vault(vaultname, pluginclass)
36
+ plugin = pluginclass.new
37
+ # stub a vault item for each method defined by the plugin
38
+ pluginclass.instance_methods(false).each do |item|
39
+ fakevault = make_fakevault(vaultname, item)
40
+ # stub lookup of each of the vault item keys
41
+ plugin.send(item).each do |k, v|
42
+ allow(fakevault).to receive(:[]).with(k).and_return(v)
43
+ end
44
+ # stub chef-vault to return the fake vault
45
+ allow(ChefVault::Item).to(
46
+ receive(:load)
47
+ .with(vaultname.to_s, item.to_s)
48
+ .and_return(fakevault)
49
+ )
50
+ end
51
+ end
52
+
53
+ def make_fakevault(vault, item)
54
+ fakevault = double "vault item #{vault}/#{item}"
55
+ allow(fakevault).to receive(:[]=).with(String, Object)
56
+ allow(fakevault).to receive(:clients).with(String)
57
+ allow(fakevault).to receive(:save)
58
+ fakevault
59
+ end
60
+ end
61
+ end
62
+ end
63
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,12 @@
1
+ class Hoe
2
+ module Markdown
3
+ def initialize_markdown
4
+ self.readme_file = readme_file.sub(/\.txt$/, '.md')
5
+ self.history_file = history_file.sub(/\.txt$/, '.md')
6
+ end
7
+
8
+ def define_markdown_tasks
9
+ # do nothing
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,113 @@
1
+ require 'chef-vault/test_fixtures'
2
+
3
+ # sample plugins
4
+ require 'support/chef-vault/test_fixtures/foo.rb'
5
+ require 'support/chef-vault/test_fixtures/bar.rb'
6
+
7
+ # LittlePlugger doesn't expect to have its inclusion/exclusion
8
+ # lists reset in a single process, so we have to monkeypatch
9
+ # in some testing functionality
10
+ module LittlePlugger
11
+ module ClassMethods
12
+ def clear_plugins
13
+ @plugin_names = []
14
+ @disregard_plugin = []
15
+ @loaded = {}
16
+ end
17
+ end
18
+ end
19
+
20
+ # same with ChefVault::TestFixtures
21
+ class ChefVault
22
+ class TestFixtures
23
+ class << self
24
+ def clear_context
25
+ @context = nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ RSpec.describe ChefVault::TestFixtures do
32
+ include ChefVault::TestFixtures.rspec_shared_context
33
+
34
+ before do
35
+ ChefVault::TestFixtures.clear_plugins
36
+ ChefVault::TestFixtures.clear_context
37
+ end
38
+
39
+ describe 'Generic functionality' do
40
+ it 'should be able to load plugins' do
41
+ expect(ChefVault::TestFixtures.plugins).to be_a(Hash)
42
+ end
43
+
44
+ it 'should load the expected vaults' do
45
+ expect(ChefVault::TestFixtures.plugins.keys).to(
46
+ contain_exactly(:foo, :bar)
47
+ )
48
+ end
49
+
50
+ it 'can create an RSpec shared context' do
51
+ sc = ChefVault::TestFixtures.rspec_shared_context
52
+ expect(sc).to be_a(Module)
53
+ expect(sc).to be_a(RSpec::Core::SharedContext)
54
+ end
55
+
56
+ it 'should only create one shared context' do
57
+ mod1 = ChefVault::TestFixtures.rspec_shared_context
58
+ mod2 = ChefVault::TestFixtures.rspec_shared_context
59
+ expect(mod2).to be(mod1)
60
+ end
61
+
62
+ it 'allows for the plugin list to be make explicit' do
63
+ ChefVault::TestFixtures.plugin :foo
64
+ expect(ChefVault::TestFixtures.plugins).to include(:foo)
65
+ expect(ChefVault::TestFixtures.plugins).not_to include(:bar)
66
+ end
67
+
68
+ it 'allows for plugins to be blacklisted' do
69
+ ChefVault::TestFixtures.disregard_plugin :foo
70
+ expect(ChefVault::TestFixtures.plugins).not_to include(:foo)
71
+ expect(ChefVault::TestFixtures.plugins).to include(:bar)
72
+ end
73
+ end
74
+
75
+ describe 'Stub a Vault' do
76
+ it 'it should stub the foo/bar vault item' do
77
+ ChefVault::TestFixtures.plugins
78
+ baz = ChefVault::Item.load('foo', 'bar')['baz']
79
+ expect(baz).to eq(2)
80
+ end
81
+
82
+ it 'it should stub the bar/foo vault item' do
83
+ ChefVault::TestFixtures.plugins
84
+ baz = ChefVault::Item.load('bar', 'foo')['baz']
85
+ expect(baz).to eq(1)
86
+ end
87
+
88
+ it 'should allow access to the aliased bar/gzonk vault item' do
89
+ ChefVault::TestFixtures.plugins
90
+ item1 = ChefVault::Item.load('bar', 'foo')
91
+ item2 = ChefVault::Item.load('bar', 'gzonk')
92
+ expect(item1['baz']).to eq(item2['baz'])
93
+ end
94
+
95
+ it 'should allow and ignore an attempt to change a vault' do
96
+ ChefVault::TestFixtures.plugins
97
+ item = ChefVault::Item.load('bar', 'foo')
98
+ item['foo'] = 'foo'
99
+ end
100
+
101
+ it 'should allow and ignore an attempt to set the clients' do
102
+ ChefVault::TestFixtures.plugins
103
+ item = ChefVault::Item.load('bar', 'foo')
104
+ item.clients('*:*')
105
+ end
106
+
107
+ it 'should allow and ignore an attempt to save' do
108
+ ChefVault::TestFixtures.plugins
109
+ item = ChefVault::Item.load('bar', 'foo')
110
+ item.save
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,23 @@
1
+ if ENV['COVERAGE']
2
+ require 'simplecov'
3
+ require 'simplecov-console'
4
+ SimpleCov.formatters = [
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ SimpleCov::Formatter::Console
7
+ ]
8
+ SimpleCov.start
9
+ end
10
+
11
+ RSpec.configure do |config|
12
+ config.expect_with :rspec do |expectations|
13
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
14
+ end
15
+
16
+ config.mock_with :rspec do |mocks|
17
+ mocks.verify_partial_doubles = true
18
+ end
19
+
20
+ config.disable_monkey_patching!
21
+ config.order = :random
22
+ Kernel.srand config.seed
23
+ end
@@ -0,0 +1,11 @@
1
+ class ChefVault
2
+ class TestFixtures
3
+ class Bar
4
+ def foo
5
+ { 'baz' => 1 }
6
+ end
7
+
8
+ alias_method :gzonk, :foo
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class ChefVault
2
+ class TestFixtures
3
+ class Foo
4
+ def bar
5
+ { 'baz' => 2 }
6
+ end
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,358 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chef-vault-testfixtures
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - James FitzGibbon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: chef-vault
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: little-plugger
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: chef
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '11.14'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '11.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rdoc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: hoe
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.13'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.13'
97
+ - !ruby/object:Gem::Dependency
98
+ name: hoe-gemspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.3'
125
+ - !ruby/object:Gem::Dependency
126
+ name: guard
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.12'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.12'
139
+ - !ruby/object:Gem::Dependency
140
+ name: guard-rspec
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '4.2'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '4.2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: guard-rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '0.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: guard-rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.2'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.2'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.29'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.29'
195
+ - !ruby/object:Gem::Dependency
196
+ name: simplecov
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.9'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.9'
209
+ - !ruby/object:Gem::Dependency
210
+ name: simplecov-console
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '0.2'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '0.2'
223
+ - !ruby/object:Gem::Dependency
224
+ name: pry-byebug
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '3.0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '3.0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: pry-rescue
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: '1.3'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: '1.3'
251
+ - !ruby/object:Gem::Dependency
252
+ name: pry-stack_explorer
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: '0.4'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: '0.4'
265
+ - !ruby/object:Gem::Dependency
266
+ name: yard
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: '0.8'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: '0.8'
279
+ description: |-
280
+ chef-vault-testfixtures provides an RSpec shared context that
281
+ dynamically stubs access to chef-vault encrypted data bags.
282
+
283
+ chef-vault is a gem to manage distribution and control of keys to
284
+ decrypt Chef encrypted data bags.
285
+
286
+ When testing a cookbook that uses chef-vault, encryption is generally
287
+ out of scope, which results in a large amount of stubs or mocks so that you get back fixture data without performing decryption.
288
+
289
+ This gem makes testing Chef cookbooks easier using ChefSpec by
290
+ dynamically stubbing attempts to access vault data to return invalid
291
+ (i.e. not real passwords for any of your environments) that are properly
292
+ formatted (e.g. a vault item containing an RSA key really contains one)
293
+
294
+ The intended use case is that for each group of distinct secrets
295
+ (e.g. an application stack, or a development team) you create one or
296
+ more plugins. The plugins contain data that is specific to your
297
+ application.
298
+
299
+ Since plugins can be whitelisted or blacklisted when the shared
300
+ context is created, this makes it easy to only include the appropriate
301
+ secrets in a given cookbook's tests.
302
+
303
+ Attempts to access secrets that would not be available to a node
304
+ during a real chef-client run will not be mocked, which will cause
305
+ the double to raise an 'unexpected message received' error.
306
+ email:
307
+ - james.i.fitzgibbon@nordstrom.com
308
+ executables: []
309
+ extensions: []
310
+ extra_rdoc_files:
311
+ - History.md
312
+ - Manifest.txt
313
+ - README.md
314
+ files:
315
+ - ".rspec"
316
+ - ".rubocop.yml"
317
+ - ".yardopts"
318
+ - Gemfile
319
+ - Guardfile
320
+ - History.md
321
+ - Manifest.txt
322
+ - README.md
323
+ - Rakefile
324
+ - chef-vault-testfixtures.gemspec
325
+ - lib/chef-vault/test_fixtures.rb
326
+ - lib/hoe/markdown.rb
327
+ - spec/lib/chef-vault/test_fixtures_spec.rb
328
+ - spec/spec_helper.rb
329
+ - spec/support/chef-vault/test_fixtures/bar.rb
330
+ - spec/support/chef-vault/test_fixtures/foo.rb
331
+ homepage: https://github.com/Nordstrom/chef-vault-testfixtures
332
+ licenses:
333
+ - apache2
334
+ metadata: {}
335
+ post_install_message:
336
+ rdoc_options:
337
+ - "--main"
338
+ - README.md
339
+ require_paths:
340
+ - lib
341
+ required_ruby_version: !ruby/object:Gem::Requirement
342
+ requirements:
343
+ - - ">="
344
+ - !ruby/object:Gem::Version
345
+ version: '0'
346
+ required_rubygems_version: !ruby/object:Gem::Requirement
347
+ requirements:
348
+ - - ">="
349
+ - !ruby/object:Gem::Version
350
+ version: '0'
351
+ requirements: []
352
+ rubyforge_project:
353
+ rubygems_version: 2.4.4
354
+ signing_key:
355
+ specification_version: 4
356
+ summary: chef-vault-testfixtures provides an RSpec shared context that dynamically
357
+ stubs access to chef-vault encrypted data bags
358
+ test_files: []