chef-vault 3.3.0 → 4.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +32 -6
- data/bin/chef-vault +5 -5
- data/chef-vault.gemspec +7 -26
- data/lib/chef/knife/mixin/helper.rb +29 -1
- data/lib/chef/knife/vault_admins.rb +5 -1
- data/lib/chef/knife/vault_base.rb +23 -13
- data/lib/chef/knife/vault_create.rb +26 -23
- data/lib/chef/knife/vault_delete.rb +4 -2
- data/lib/chef/knife/vault_download.rb +2 -2
- data/lib/chef/knife/vault_edit.rb +4 -4
- data/lib/chef/knife/vault_isvault.rb +4 -4
- data/lib/chef/knife/vault_itemtype.rb +4 -4
- data/lib/chef/knife/vault_list.rb +5 -5
- data/lib/chef/knife/vault_refresh.rb +7 -7
- data/lib/chef/knife/vault_remove.rb +19 -16
- data/lib/chef/knife/vault_rotate_all_keys.rb +5 -4
- data/lib/chef/knife/vault_rotate_keys.rb +3 -3
- data/lib/chef/knife/vault_show.rb +8 -10
- data/lib/chef/knife/vault_update.rb +38 -24
- data/lib/chef-vault/actor.rb +9 -7
- data/lib/chef-vault/chef_api.rb +4 -4
- data/lib/chef-vault/exceptions.rb +3 -0
- data/lib/chef-vault/item.rb +57 -21
- data/lib/chef-vault/item_keys.rb +35 -9
- data/lib/chef-vault/mixins.rb +2 -2
- data/lib/chef-vault/version.rb +1 -1
- data/lib/chef-vault.rb +8 -8
- metadata +8 -135
- data/.github/CODEOWNERS +0 -2
- data/.gitignore +0 -33
- data/.rspec +0 -2
- data/.rubocop.yml +0 -6
- data/.simplecov +0 -6
- data/.travis.yml +0 -19
- data/Changelog.md +0 -134
- data/DEMO.md +0 -60
- data/KNIFE_EXAMPLES.md +0 -256
- data/README.md +0 -333
- data/Rakefile +0 -50
- data/THEORY.md +0 -363
- data/UPGRADE.md +0 -55
- data/appveyor.yml +0 -32
- data/features/clean.feature +0 -23
- data/features/clean_on_refresh.feature +0 -27
- data/features/clean_unknown_clients.feature +0 -45
- data/features/detect_and_warn_v1_vault.feature +0 -14
- data/features/isvault.feature +0 -29
- data/features/itemtype.feature +0 -24
- data/features/step_definitions/chef-databag.rb +0 -9
- data/features/step_definitions/chef-repo.rb +0 -72
- data/features/step_definitions/chef-vault.rb +0 -151
- data/features/step_definitions/chef_databagitem.rb +0 -9
- data/features/support/env.rb +0 -14
- data/features/vault_create.feature +0 -63
- data/features/vault_list.feature +0 -31
- data/features/vault_show.feature +0 -45
- data/features/vault_show_vaultname.feature +0 -21
- data/features/vault_update.feature +0 -18
- data/features/verify_id_matches.feature +0 -10
- data/features/wrong_private_key.feature +0 -13
- data/hooks/pre-commit +0 -43
- data/spec/chef-vault/actor_spec.rb +0 -247
- data/spec/chef-vault/certificate_spec.rb +0 -37
- data/spec/chef-vault/chef_api_spec.rb +0 -39
- data/spec/chef-vault/item_keys_spec.rb +0 -263
- data/spec/chef-vault/item_spec.rb +0 -360
- data/spec/chef-vault/user_spec.rb +0 -36
- data/spec/chef-vault_spec.rb +0 -65
- data/spec/spec_helper.rb +0 -91
- data/tasks/github_changelog_generator.rb +0 -30
@@ -1,247 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
RSpec.describe ChefVault::Actor do
|
4
|
-
let(:actor_name) { "actor" }
|
5
|
-
let(:public_key_string) do
|
6
|
-
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyMXT9IOV9pkQsxsnhSx8\n8RX6GW3caxkjcXFfHg6E7zUVBFAsfw4B1D+eHAks3qrDB7UrUxsmCBXwU4dQHaQy\ngAn5Sv0Jc4CejDNL2EeCBLZ4TF05odHmuzyDdPkSZP6utpR7+uF7SgVQedFGySIB\nih86aM+HynhkJqgJYhoxkrdo/JcWjpk7YEmWb6p4esnvPWOpbcjIoFs4OjavWBOF\niTfpkS0SkygpLi/iQu9RQfd4hDMWCc6yh3Th/1nVMUd+xQCdUK5wxluAWSv8U0zu\nhiIlZNazpCGHp+3QdP3f6rebmQA8pRM8qT5SlOvCYPk79j+IMUVSYrR4/DTZ+VM+\naQIDAQAB\n-----END PUBLIC KEY-----\n"
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:key_response) do
|
10
|
-
{
|
11
|
-
"name" => "default",
|
12
|
-
"public_key" => "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyMXT9IOV9pkQsxsnhSx8\n8RX6GW3caxkjcXFfHg6E7zUVBFAsfw4B1D+eHAks3qrDB7UrUxsmCBXwU4dQHaQy\ngAn5Sv0Jc4CejDNL2EeCBLZ4TF05odHmuzyDdPkSZP6utpR7+uF7SgVQedFGySIB\nih86aM+HynhkJqgJYhoxkrdo/JcWjpk7YEmWb6p4esnvPWOpbcjIoFs4OjavWBOF\niTfpkS0SkygpLi/iQu9RQfd4hDMWCc6yh3Th/1nVMUd+xQCdUK5wxluAWSv8U0zu\nhiIlZNazpCGHp+3QdP3f6rebmQA8pRM8qT5SlOvCYPk79j+IMUVSYrR4/DTZ+VM+\naQIDAQAB\n-----END PUBLIC KEY-----\n",
|
13
|
-
"expiration_date" => "infinity",
|
14
|
-
}
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:http_response_code) do
|
18
|
-
"404"
|
19
|
-
end
|
20
|
-
|
21
|
-
let(:http_error) do
|
22
|
-
http_response = double("http error")
|
23
|
-
allow(http_response).to receive(:code).and_return(http_response_code)
|
24
|
-
Net::HTTPServerException.new("http error message", http_response)
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:api) { double("api") }
|
28
|
-
|
29
|
-
subject(:chef_key) { described_class.new(actor_type, actor_name) }
|
30
|
-
|
31
|
-
describe "#new" do
|
32
|
-
context "when something besides 'clients' or 'users' is passed" do
|
33
|
-
let(:actor_type) { "charmander" }
|
34
|
-
it "throws an error" do
|
35
|
-
expect { described_class.new("charmander", actor_name) }.to raise_error(RuntimeError)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context "when 'clients' is passed" do
|
40
|
-
it "requests a client key" do
|
41
|
-
expect_any_instance_of(described_class).to receive(:get_client_key)
|
42
|
-
described_class.new("clients", actor_name).key
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context "when 'admins' is passed" do
|
47
|
-
it "requests a admin key" do
|
48
|
-
expect_any_instance_of(described_class).to receive(:get_admin_key)
|
49
|
-
described_class.new("admins", actor_name).key
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
shared_examples_for "get_key_handling" do
|
55
|
-
context "when the default key exists for the requested client" do
|
56
|
-
it "sets up a valid key" do
|
57
|
-
expect(chef_key).to receive(:get_key).with(request_actor_type).and_return(public_key_string)
|
58
|
-
expect(chef_key.send(method)).to eq(public_key_string)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context "when get_key returns an http error" do
|
63
|
-
before do
|
64
|
-
allow(chef_key).to receive(:get_key).with(request_actor_type).and_raise(http_error)
|
65
|
-
end
|
66
|
-
|
67
|
-
context "when the error code is not 404 or 403" do
|
68
|
-
let(:http_response_code) { "500" }
|
69
|
-
|
70
|
-
it "raises the original error" do
|
71
|
-
expect { chef_key.send(method) }.to raise_error(http_error)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context "when the error code is 403" do
|
76
|
-
let(:http_response_code) { "403" }
|
77
|
-
|
78
|
-
it "prints information for the user to resolve the issue and raises the original error" do
|
79
|
-
expect(chef_key).to receive(:print_forbidden_error)
|
80
|
-
expect { chef_key.send(method) }.to raise_error(http_error)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "#get_client_key" do
|
87
|
-
let(:request_actor_type) { "clients" }
|
88
|
-
let(:actor_type) { "clients" }
|
89
|
-
let(:method) { :get_client_key }
|
90
|
-
|
91
|
-
it_should_behave_like "get_key_handling"
|
92
|
-
|
93
|
-
context "when get_key returns an http error" do
|
94
|
-
before do
|
95
|
-
allow(chef_key).to receive(:get_key).with(actor_type).and_raise(http_error)
|
96
|
-
end
|
97
|
-
|
98
|
-
context "when the error code is 404" do
|
99
|
-
let(:http_response_code) { "404" }
|
100
|
-
|
101
|
-
it "raises ChefVault::Exceptions::ClientNotFound" do
|
102
|
-
expect { chef_key.get_client_key }.to raise_error(ChefVault::Exceptions::ClientNotFound)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end # get_client_key
|
107
|
-
|
108
|
-
describe "#get_admin_key" do
|
109
|
-
let(:request_actor_type) { "users" }
|
110
|
-
let(:actor_type) { "admins" }
|
111
|
-
let(:method) { :get_admin_key }
|
112
|
-
|
113
|
-
it_should_behave_like "get_key_handling"
|
114
|
-
|
115
|
-
context "when the first get_key for users returns an http error" do
|
116
|
-
before do
|
117
|
-
allow(chef_key).to receive(:get_key).with(request_actor_type).and_raise(http_error)
|
118
|
-
end
|
119
|
-
|
120
|
-
context "when the error code from the users get is a 404" do
|
121
|
-
let(:http_response_code) { "404" }
|
122
|
-
|
123
|
-
context "when the second get_key for clients returns an http error" do
|
124
|
-
|
125
|
-
let(:http_error_2) do
|
126
|
-
http_response = double("http error")
|
127
|
-
allow(http_response).to receive(:code).and_return(http_response_code_2)
|
128
|
-
Net::HTTPServerException.new("http error message", http_response)
|
129
|
-
end
|
130
|
-
|
131
|
-
before do
|
132
|
-
allow(chef_key).to receive(:get_key).with("clients").and_raise(http_error_2)
|
133
|
-
end
|
134
|
-
|
135
|
-
context "when it is a 404" do
|
136
|
-
let(:http_response_code_2) { "404" }
|
137
|
-
|
138
|
-
it "rasies ChefVault::Exceptions::AdminNotFound" do
|
139
|
-
expect { chef_key.get_admin_key }.to raise_error(ChefVault::Exceptions::AdminNotFound)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context "when it is a 403" do
|
144
|
-
let(:http_response_code_2) { "403" }
|
145
|
-
|
146
|
-
it "raises the original error" do
|
147
|
-
expect { chef_key.get_admin_key }.to raise_error(http_error_2)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
context "when it is not a 404" do
|
152
|
-
let(:http_response_code_2) { "500" }
|
153
|
-
|
154
|
-
it "raises the original error" do
|
155
|
-
expect { chef_key.get_admin_key }.to raise_error(http_error_2)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end # when the second get_key for clients returns an http error
|
159
|
-
|
160
|
-
context "when the second get_key for clients exists with the same name as the admin requested" do
|
161
|
-
it "strangely returns the client key as an admin key" do
|
162
|
-
expect(chef_key).to receive(:get_key).with(request_actor_type).and_return(public_key_string)
|
163
|
-
expect(chef_key.send(method)).to eq(public_key_string)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end # when the first get_key for users returns an http erro
|
167
|
-
end
|
168
|
-
end # get_admin_key
|
169
|
-
|
170
|
-
describe "#get_key" do
|
171
|
-
|
172
|
-
shared_examples_for "a properly retrieved and error handled key fetch" do
|
173
|
-
# mock out the API
|
174
|
-
before do
|
175
|
-
allow(chef_key).to receive(:api).and_return(api)
|
176
|
-
[:rest_v0, :rest_v1, :org_scoped_rest_v0, :org_scoped_rest_v1].each do |method|
|
177
|
-
allow(api).to receive(method)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
context "when keys/default returns 200 for org scoped endpoint" do
|
182
|
-
before do
|
183
|
-
allow(api.org_scoped_rest_v1).to receive(:get).with("#{request_actor_type}/#{actor_name}/keys/default").and_return(key_response)
|
184
|
-
end
|
185
|
-
|
186
|
-
it "returns the public_key" do
|
187
|
-
expect(chef_key.get_key(request_actor_type)).to eql(public_key_string)
|
188
|
-
end
|
189
|
-
|
190
|
-
it "hits the proper endpoint" do
|
191
|
-
expect(api.org_scoped_rest_v1).to receive(:get).with("#{request_actor_type}/#{actor_name}/keys/default")
|
192
|
-
chef_key.get_key(request_actor_type)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
context "when a 500 is returned" do
|
197
|
-
let(:http_response_code) { "500" }
|
198
|
-
before do
|
199
|
-
allow(api.org_scoped_rest_v1).to receive(:get).with("#{request_actor_type}/#{actor_name}/keys/default").and_raise(http_error)
|
200
|
-
end
|
201
|
-
|
202
|
-
it "raises the http error" do
|
203
|
-
expect { chef_key.get_key(request_actor_type) }.to raise_error(http_error)
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
context "when keys/default returns 404" do
|
208
|
-
let(:http_response_code) { "404" }
|
209
|
-
let(:chef_object) { double("chef object") }
|
210
|
-
|
211
|
-
before do
|
212
|
-
allow(api.org_scoped_rest_v1).to receive(:get).with("#{request_actor_type}/#{actor_name}/keys/default").and_raise(http_error)
|
213
|
-
allow(chef_object_type).to receive(:load).with(actor_name).and_return(chef_object)
|
214
|
-
allow(chef_object).to receive(:public_key).and_return(public_key_string)
|
215
|
-
end
|
216
|
-
|
217
|
-
it "tries to load the object via Chef::<object>_v1" do
|
218
|
-
expect(chef_object_type).to receive(:load).with(actor_name)
|
219
|
-
chef_key.get_key(request_actor_type)
|
220
|
-
end
|
221
|
-
|
222
|
-
context "when the Chef::<object>_v1 object loads properly" do
|
223
|
-
it "returns the public key" do
|
224
|
-
expect(chef_key.get_key(request_actor_type)).to eql(public_key_string)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end # shared_examples_for
|
229
|
-
|
230
|
-
context "when a client is passed" do
|
231
|
-
let(:request_actor_type) { "clients" }
|
232
|
-
let(:actor_type) { "clients" }
|
233
|
-
let(:chef_object_type) { Chef::ApiClient }
|
234
|
-
|
235
|
-
it_behaves_like "a properly retrieved and error handled key fetch"
|
236
|
-
end
|
237
|
-
|
238
|
-
context "when an admin is passed" do
|
239
|
-
let(:request_actor_type) { "users" }
|
240
|
-
let(:actor_type) { "admins" }
|
241
|
-
let(:chef_object_type) { Chef::User }
|
242
|
-
|
243
|
-
it_behaves_like "a properly retrieved and error handled key fetch"
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|
247
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
RSpec.describe ChefVault::Certificate do
|
2
|
-
let(:item) { double(ChefVault::Item) }
|
3
|
-
let(:cert) { ChefVault::Certificate.new("foo", "bar") }
|
4
|
-
|
5
|
-
before do
|
6
|
-
allow(ChefVault::Item).to receive(:load).with("foo", "bar") { item }
|
7
|
-
allow(item).to receive(:[]).with("id") { "bar" }
|
8
|
-
allow(item).to receive(:[]).with("contents") { "baz" }
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "#new" do
|
12
|
-
it "loads item" do
|
13
|
-
expect(ChefVault::Item).to receive(:load).with("foo", "bar")
|
14
|
-
|
15
|
-
ChefVault::Certificate.new("foo", "bar")
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#[]" do
|
20
|
-
it "given an 'id' parameter, returns its value" do
|
21
|
-
expect(cert["id"]).to eq "bar"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "decrypt_contents" do
|
26
|
-
it "echoes warning" do
|
27
|
-
expect(ChefVault::Log).to receive(:warn).with("This method is deprecated, please switch to item['value'] calls")
|
28
|
-
cert.decrypt_contents
|
29
|
-
end
|
30
|
-
|
31
|
-
it "returns items contents" do
|
32
|
-
expect(item).to receive(:[]).with("contents")
|
33
|
-
|
34
|
-
expect(cert.decrypt_contents).to eq "baz"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
RSpec.describe ChefVault::ChefApi do
|
2
|
-
let(:root_url) { "https://localhost" }
|
3
|
-
let(:scoped_url) { "https://localhost/organizations/fakeorg" }
|
4
|
-
let(:api_v0_hash) { { :api_version => "0" } }
|
5
|
-
let(:api_v1_hash) { { :api_version => "1" } }
|
6
|
-
|
7
|
-
before do
|
8
|
-
Chef::Config[:chef_server_root] = root_url
|
9
|
-
Chef::Config[:chef_server_url] = scoped_url
|
10
|
-
end
|
11
|
-
|
12
|
-
describe "#rest_v0" do
|
13
|
-
it "returns an instance of Chef::ServerAPI set to use API version 0 scoped to root" do
|
14
|
-
expect(Chef::ServerAPI).to receive(:new).with(root_url, api_v0_hash)
|
15
|
-
subject.rest_v0
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "#rest_v1" do
|
20
|
-
it "returns an instance of Chef::ServerAPI set to use API version 0 scoped to root" do
|
21
|
-
expect(Chef::ServerAPI).to receive(:new).with(root_url, api_v1_hash)
|
22
|
-
subject.rest_v1
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "#org_scoped_rest_v0" do
|
27
|
-
it "returns an instance of Chef::ServerAPI set to use API version 0 scoped to root" do
|
28
|
-
expect(Chef::ServerAPI).to receive(:new).with(scoped_url, api_v0_hash)
|
29
|
-
subject.org_scoped_rest_v0
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "#org_scoped_rest_v1" do
|
34
|
-
it "returns an instance of Chef::ServerAPI set to use API version 0 scoped to root" do
|
35
|
-
expect(Chef::ServerAPI).to receive(:new).with(scoped_url, api_v1_hash)
|
36
|
-
subject.org_scoped_rest_v1
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,263 +0,0 @@
|
|
1
|
-
RSpec.describe ChefVault::ItemKeys do
|
2
|
-
describe "#new" do
|
3
|
-
let(:keys) { ChefVault::ItemKeys.new("foo", "bar") }
|
4
|
-
let(:shared_secret) { "super_secret" }
|
5
|
-
let(:public_key_string) do
|
6
|
-
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyMXT9IOV9pkQsxsnhSx8\n8RX6GW3caxkjcXFfHg6E7zUVBFAsfw4B1D+eHAks3qrDB7UrUxsmCBXwU4dQHaQy\ngAn5Sv0Jc4CejDNL2EeCBLZ4TF05odHmuzyDdPkSZP6utpR7+uF7SgVQedFGySIB\nih86aM+HynhkJqgJYhoxkrdo/JcWjpk7YEmWb6p4esnvPWOpbcjIoFs4OjavWBOF\niTfpkS0SkygpLi/iQu9RQfd4hDMWCc6yh3Th/1nVMUd+xQCdUK5wxluAWSv8U0zu\nhiIlZNazpCGHp+3QdP3f6rebmQA8pRM8qT5SlOvCYPk79j+IMUVSYrR4/DTZ+VM+\naQIDAQAB\n-----END PUBLIC KEY-----\n"
|
7
|
-
end
|
8
|
-
|
9
|
-
it "'foo' is assigned to @data_bag" do
|
10
|
-
expect(keys.data_bag).to eq "foo"
|
11
|
-
end
|
12
|
-
|
13
|
-
it "sets the keys id to 'bar'" do
|
14
|
-
expect(keys["id"]).to eq "bar"
|
15
|
-
end
|
16
|
-
|
17
|
-
it "initializes the keys[admin] to an empty array" do
|
18
|
-
expect(keys["admins"]).to eq []
|
19
|
-
end
|
20
|
-
|
21
|
-
it "initializes the keys[clients] to an empty array" do
|
22
|
-
expect(keys["admins"]).to eq []
|
23
|
-
end
|
24
|
-
|
25
|
-
shared_context "key mgmt operations" do
|
26
|
-
|
27
|
-
shared_examples_for "proper key management" do
|
28
|
-
let(:chef_key) { ChefVault::Actor.new(type, name) }
|
29
|
-
before do
|
30
|
-
allow(chef_key).to receive(:key) { public_key_string }
|
31
|
-
keys.add(chef_key, shared_secret)
|
32
|
-
end
|
33
|
-
|
34
|
-
describe "#add" do
|
35
|
-
after do
|
36
|
-
keys.delete(chef_key)
|
37
|
-
end
|
38
|
-
|
39
|
-
context "when key is already there" do
|
40
|
-
context "when skip_reencryption is not specified (default to false)" do
|
41
|
-
it "encodes key in the data bag item under the actor's name and the name in the raw data" do
|
42
|
-
expect(described_class).to receive(:encode_key).with(public_key_string, shared_secret).and_return("encrypted_result")
|
43
|
-
keys.add(chef_key, shared_secret)
|
44
|
-
expect(keys[name]).to eq("encrypted_result")
|
45
|
-
expect(keys[type].include?(name)).to eq(true)
|
46
|
-
expect(keys.include?(name)).to eq(true)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context "when skip_reencryption is true" do
|
51
|
-
it "keeps the encoded key in the data bag item under the actor's name and the name in the raw data" do
|
52
|
-
expect(described_class).not_to receive(:encode_key).with(public_key_string, shared_secret)
|
53
|
-
keys.skip_reencryption = true
|
54
|
-
keys.add(chef_key, shared_secret)
|
55
|
-
expect(keys[name]).not_to be_empty
|
56
|
-
expect(keys[type].include?(name)).to eq(true)
|
57
|
-
expect(keys.include?(name)).to eq(true)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context "when keys not already there" do
|
63
|
-
before do
|
64
|
-
keys.delete(chef_key)
|
65
|
-
end
|
66
|
-
it "stores the encoded key in the data bag item under the actor's name and the name in the raw data" do
|
67
|
-
expect(described_class).to receive(:encode_key).with(public_key_string, shared_secret).and_return("encrypted_result")
|
68
|
-
keys.add(chef_key, shared_secret)
|
69
|
-
expect(keys[name]).to eq("encrypted_result")
|
70
|
-
expect(keys[type].include?(name)).to eq(true)
|
71
|
-
expect(keys.include?(name)).to eq(true)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "#delete" do
|
77
|
-
before do
|
78
|
-
keys.add(chef_key, shared_secret)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "removes the actor's name from the data bag and from the array for the actor's type" do
|
82
|
-
keys.delete(chef_key)
|
83
|
-
expect(keys.has_key?(chef_key.name)).to eq(false)
|
84
|
-
expect(keys[type].include?(name)).to eq(false)
|
85
|
-
expect(keys.include?(name)).to eq(false)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context "when a client is added" do
|
91
|
-
let(:name) { "client_name" }
|
92
|
-
let(:type) { "clients" }
|
93
|
-
it_should_behave_like "proper key management"
|
94
|
-
end
|
95
|
-
|
96
|
-
context "when a admin is added" do
|
97
|
-
let(:name) { "admin_name" }
|
98
|
-
let(:type) { "admins" }
|
99
|
-
it_should_behave_like "proper key management"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context "when running with chef-zero" do
|
104
|
-
let(:server) { chef_zero }
|
105
|
-
before { server.start_background }
|
106
|
-
after { server.stop }
|
107
|
-
|
108
|
-
include_context "key mgmt operations"
|
109
|
-
|
110
|
-
describe "#save" do
|
111
|
-
let(:client_name) { "client_name" }
|
112
|
-
let(:chef_key) { ChefVault::Actor.new("clients", client_name) }
|
113
|
-
before { allow(chef_key).to receive(:key) { public_key_string } }
|
114
|
-
|
115
|
-
it "should save the key data" do
|
116
|
-
keys.add(chef_key, shared_secret)
|
117
|
-
keys.save("bar")
|
118
|
-
expect(Chef::DataBagItem.load("foo", "bar").to_hash).to include("id" => "bar")
|
119
|
-
expect(keys[client_name]).not_to be_empty
|
120
|
-
keys.delete(chef_key)
|
121
|
-
keys.save("bar")
|
122
|
-
expect(keys[client_name]).to be_nil
|
123
|
-
end
|
124
|
-
|
125
|
-
it "should save the key data in sparse mode" do
|
126
|
-
keys.add(chef_key, shared_secret)
|
127
|
-
keys.mode("sparse")
|
128
|
-
keys.save("bar")
|
129
|
-
expect(Chef::DataBagItem.load("foo", "bar").to_hash).to include("id" => "bar")
|
130
|
-
expect(Chef::DataBagItem.load("foo", "bar_key_client_name").to_hash).to include("id" => "bar_key_client_name")
|
131
|
-
expect(keys[client_name]).not_to be_empty
|
132
|
-
keys.delete(chef_key)
|
133
|
-
keys.save("bar")
|
134
|
-
expect(keys[client_name]).to be_nil
|
135
|
-
keys.mode("default")
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
describe "#destroy" do
|
140
|
-
let(:client_name) { "client_name" }
|
141
|
-
let(:chef_key) { ChefVault::Actor.new("clients", client_name) }
|
142
|
-
before { allow(chef_key).to receive(:key) { public_key_string } }
|
143
|
-
|
144
|
-
it "should destroy the keys" do
|
145
|
-
keys.add(chef_key, shared_secret)
|
146
|
-
keys.save("bar")
|
147
|
-
keys.destroy
|
148
|
-
expect { Chef::DataBagItem.load("foo", "bar") }.to raise_error(Net::HTTPServerException)
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should destroy the keys in sparse mode" do
|
152
|
-
keys.add(chef_key, shared_secret)
|
153
|
-
keys.mode("sparse")
|
154
|
-
keys.save("bar")
|
155
|
-
keys.destroy
|
156
|
-
expect { Chef::DataBagItem.load("foo", "bar") }.to raise_error(Net::HTTPServerException)
|
157
|
-
expect { Chef::DataBagItem.load("foo", "bar_key_client_name") }.to raise_error(Net::HTTPServerException)
|
158
|
-
keys.mode("default")
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
context "when running with chef-solo" do
|
164
|
-
before { Chef::Config[:solo_legacy_mode] = true }
|
165
|
-
after { Chef::Config[:solo_legacy_mode] = false }
|
166
|
-
|
167
|
-
include_context "key mgmt operations"
|
168
|
-
|
169
|
-
describe "#find_solo_path" do
|
170
|
-
context "when data_bag_path is an array" do
|
171
|
-
before do
|
172
|
-
allow(File).to receive(:exist?)
|
173
|
-
Chef::Config[:data_bag_path] = ["/tmp/data_bag", "/tmp/site_data_bag"]
|
174
|
-
end
|
175
|
-
|
176
|
-
it "should return an existing item" do
|
177
|
-
expect(File).to receive(:exist?).with("/tmp/site_data_bag/foo/bar.json").and_return(true)
|
178
|
-
dbp, dbi = keys.find_solo_path("bar")
|
179
|
-
expect(dbp).to eql("/tmp/site_data_bag/foo")
|
180
|
-
expect(dbi).to eql("/tmp/site_data_bag/foo/bar.json")
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should return the first item if none exist" do
|
184
|
-
dbp, dbi = keys.find_solo_path("bar")
|
185
|
-
expect(dbp).to eql("/tmp/data_bag/foo")
|
186
|
-
expect(dbi).to eql("/tmp/data_bag/foo/bar.json")
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context "when data_bag_path is a string" do
|
191
|
-
it "should return the path to the bag and the item" do
|
192
|
-
Chef::Config[:data_bag_path] = "/tmp/data_bag"
|
193
|
-
dbp, dbi = keys.find_solo_path("bar")
|
194
|
-
expect(dbp).to eql("/tmp/data_bag/foo")
|
195
|
-
expect(dbi).to eql("/tmp/data_bag/foo/bar.json")
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
describe "#save" do
|
201
|
-
let(:client_name) { "client_name" }
|
202
|
-
let(:chef_key) { ChefVault::Actor.new("clients", client_name) }
|
203
|
-
let(:data_bag_path) { Dir.mktmpdir("vault_item_keys") }
|
204
|
-
|
205
|
-
before do
|
206
|
-
Chef::Config[:data_bag_path] = data_bag_path
|
207
|
-
allow(chef_key).to receive(:key) { public_key_string }
|
208
|
-
end
|
209
|
-
|
210
|
-
it "should save the key data" do
|
211
|
-
keys.add(chef_key, shared_secret)
|
212
|
-
keys.save("bar")
|
213
|
-
expect(File.read(File.join(data_bag_path, "foo", "bar.json"))).to match(/"id":.*"bar"/)
|
214
|
-
expect(keys[client_name]).not_to be_empty
|
215
|
-
keys.delete(chef_key)
|
216
|
-
keys.save("bar")
|
217
|
-
expect(keys[client_name]).to be_nil
|
218
|
-
end
|
219
|
-
|
220
|
-
it "should save the key data in sparse mode" do
|
221
|
-
keys.add(chef_key, shared_secret)
|
222
|
-
keys.mode("sparse")
|
223
|
-
keys.save("bar")
|
224
|
-
expect(File.read(File.join(data_bag_path, "foo", "bar.json"))).to match(/"id":.*"bar"/)
|
225
|
-
expect(File.read(File.join(data_bag_path, "foo", "bar_key_client_name.json"))).to match(/"id":.*"bar_key_client_name"/)
|
226
|
-
expect(keys[client_name]).not_to be_empty
|
227
|
-
keys.delete(chef_key)
|
228
|
-
keys.save("bar")
|
229
|
-
expect(keys[client_name]).to be_nil
|
230
|
-
keys.mode("default")
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
describe "#destroy" do
|
235
|
-
let(:client_name) { "client_name" }
|
236
|
-
let(:chef_key) { ChefVault::Actor.new("clients", client_name) }
|
237
|
-
let(:data_bag_path) { Dir.mktmpdir("vault_item_keys") }
|
238
|
-
|
239
|
-
before do
|
240
|
-
Chef::Config[:data_bag_path] = data_bag_path
|
241
|
-
allow(chef_key).to receive(:key) { public_key_string }
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should destroy the keys" do
|
245
|
-
keys.add(chef_key, shared_secret)
|
246
|
-
keys.save("bar")
|
247
|
-
keys.destroy
|
248
|
-
expect(File.exist?(File.join(data_bag_path, "foo", "bar.json"))).to be(false)
|
249
|
-
end
|
250
|
-
|
251
|
-
it "should destroy the keys in sparse mode" do
|
252
|
-
keys.add(chef_key, shared_secret)
|
253
|
-
keys.mode("sparse")
|
254
|
-
keys.save("bar")
|
255
|
-
keys.destroy
|
256
|
-
expect(File.exist?(File.join(data_bag_path, "foo", "bar.json"))).to be(false)
|
257
|
-
expect(File.exist?(File.join(data_bag_path, "foo", "bar_key_client_name.json"))).to be(false)
|
258
|
-
keys.mode("default")
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|