chef-vault 2.4.0 → 2.5.0
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 +4 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +97 -0
- data/Changelog.md +34 -0
- data/DEMO.md +13 -6
- data/README.md +9 -4
- data/Rakefile +47 -10
- data/THEORY.md +361 -0
- data/bin/chef-vault +5 -5
- data/chef-vault.gemspec +11 -2
- data/features/clean_unknown_clients.feature +28 -3
- data/features/step_definitions/chef-databag.rb +5 -0
- data/features/step_definitions/chef-repo.rb +46 -8
- data/features/step_definitions/chef-vault.rb +69 -15
- data/features/support/env.rb +2 -2
- data/features/vault_create.feature +54 -0
- data/features/vault_list.feature +26 -0
- data/features/vault_show.feature +46 -0
- data/features/vault_update.feature +17 -0
- data/features/wrong_private_key.feature +14 -0
- data/lib/chef-vault.rb +0 -1
- data/lib/chef-vault/certificate.rb +1 -1
- data/lib/chef-vault/chef_patch/api_client.rb +1 -1
- data/lib/chef-vault/chef_patch/user.rb +1 -1
- data/lib/chef-vault/exceptions.rb +33 -12
- data/lib/chef-vault/item.rb +262 -209
- data/lib/chef-vault/item_keys.rb +90 -88
- data/lib/chef-vault/user.rb +1 -1
- data/lib/chef-vault/version.rb +2 -2
- data/lib/chef/knife/decrypt.rb +1 -2
- data/lib/chef/knife/encrypt_create.rb +1 -2
- data/lib/chef/knife/encrypt_delete.rb +1 -2
- data/lib/chef/knife/encrypt_remove.rb +1 -2
- data/lib/chef/knife/encrypt_rotate_keys.rb +1 -2
- data/lib/chef/knife/encrypt_update.rb +1 -2
- data/lib/chef/knife/mixin/compat.rb +3 -3
- data/lib/chef/knife/mixin/helper.rb +6 -8
- data/lib/chef/knife/vault_admins.rb +1 -2
- data/lib/chef/knife/vault_base.rb +2 -2
- data/lib/chef/knife/vault_create.rb +3 -4
- data/lib/chef/knife/vault_decrypt.rb +3 -4
- data/lib/chef/knife/vault_delete.rb +2 -4
- data/lib/chef/knife/vault_download.rb +1 -2
- data/lib/chef/knife/vault_edit.rb +3 -6
- data/lib/chef/knife/vault_list.rb +53 -0
- data/lib/chef/knife/vault_refresh.rb +1 -2
- data/lib/chef/knife/vault_remove.rb +3 -7
- data/lib/chef/knife/vault_rotate_all_keys.rb +2 -4
- data/lib/chef/knife/vault_rotate_keys.rb +2 -4
- data/lib/chef/knife/vault_show.rb +4 -5
- data/lib/chef/knife/vault_update.rb +7 -9
- data/spec/chef-vault/certificate_spec.rb +0 -2
- data/spec/chef-vault/item_spec.rb +77 -1
- data/spec/chef-vault/user_spec.rb +0 -2
- data/spec/chef-vault_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -3
- metadata +38 -14
data/bin/chef-vault
CHANGED
@@ -3,15 +3,15 @@
|
|
3
3
|
# ./chef-vault - Run chef-vault and decrypt based on parameters
|
4
4
|
#
|
5
5
|
# Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
|
6
|
-
# Copyright:: Copyright (c) 2013 Nordstrom, Inc.
|
6
|
+
# Copyright:: Copyright (c) 2013-15 Nordstrom, Inc.
|
7
7
|
# License:: Apache License, Version 2.0
|
8
8
|
#
|
9
9
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
10
10
|
# you may not use this file except in compliance with the License.
|
11
11
|
# You may obtain a copy of the License at
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# http://www.apache.org/licenses/LICENSE-2.0
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# Unless required by applicable law or agreed to in writing, software
|
16
16
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
17
17
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -34,7 +34,7 @@ options_config = {
|
|
34
34
|
description: "Vault to look in",
|
35
35
|
default: nil,
|
36
36
|
optional: false
|
37
|
-
},
|
37
|
+
},
|
38
38
|
item: {
|
39
39
|
short: "i",
|
40
40
|
long: "item",
|
@@ -57,7 +57,7 @@ options_config.each do |option, config|
|
|
57
57
|
banner << "[--#{config[:long]} #{config[:long].upcase}] "
|
58
58
|
else
|
59
59
|
banner << "--#{config[:long]} #{config[:long].upcase} "
|
60
|
-
end
|
60
|
+
end
|
61
61
|
end
|
62
62
|
|
63
63
|
options = {}
|
data/chef-vault.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
# Chef-Vault Gemspec file
|
3
|
-
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
# Copyright 2013-15, Nordstrom, Inc.
|
4
4
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -38,7 +38,16 @@ Gem::Specification.new do |s|
|
|
38
38
|
s.add_development_dependency 'rspec', '~> 3.1'
|
39
39
|
s.add_development_dependency 'rspec-its', '~> 1.1'
|
40
40
|
s.add_development_dependency 'aruba', '~> 0.6'
|
41
|
-
s.add_development_dependency 'chef', '>= 0.10.10'
|
42
41
|
s.add_development_dependency 'simplecov', '~> 0.9'
|
43
42
|
s.add_development_dependency 'simplecov-console', '~> 0.2'
|
43
|
+
s.add_development_dependency 'rubocop', '~> 0.29'
|
44
|
+
# Chef 12 and higher pull in Ohai 8, which needs Ruby v2
|
45
|
+
# so only in the case of a CI build on ruby v1, we constrain
|
46
|
+
# chef to 11 or lower so that we can maintain CI test coverage
|
47
|
+
# of older versions
|
48
|
+
if ENV.key?('TRAVIS_BUILD') && RUBY_VERSION =~ /^1/
|
49
|
+
s.add_development_dependency 'chef', '~> 11.18'
|
50
|
+
else
|
51
|
+
s.add_development_dependency 'chef', '>= 0.10.10'
|
52
|
+
end
|
44
53
|
end
|
@@ -14,7 +14,11 @@ Feature: clean unknown clients on key rotation
|
|
14
14
|
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
15
15
|
And I delete client 'one' from the Chef server
|
16
16
|
And I remove client 'two' from vault item 'test/item' with the 'clean-unknown-clients' option
|
17
|
-
Then the
|
17
|
+
Then the output should contain "Removing unknown client 'one'"
|
18
|
+
And the vault item 'test/item' should be encrypted for 'three'
|
19
|
+
And the vault item 'test/item' should not be encrypted for 'one,two'
|
20
|
+
And 'three' should be a client for the vault item 'test/item'
|
21
|
+
And 'one,two' should not be a client for the vault item 'test/item'
|
18
22
|
|
19
23
|
Scenario: Prune clients when rotating keys
|
20
24
|
Given a local mode chef repo with nodes 'one,two,three'
|
@@ -22,7 +26,11 @@ Feature: clean unknown clients on key rotation
|
|
22
26
|
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
23
27
|
And I delete client 'one' from the Chef server
|
24
28
|
And I rotate the keys for vault item 'test/item' with the 'clean-unknown-clients' option
|
25
|
-
Then the
|
29
|
+
Then the output should contain "Removing unknown client 'one'"
|
30
|
+
And the vault item 'test/item' should be encrypted for 'two,three'
|
31
|
+
And the vault item 'test/item' should not be encrypted for 'one'
|
32
|
+
And 'two,three' should be a client for the vault item 'test/item'
|
33
|
+
And 'one' should not be a client for the vault item 'test/item'
|
26
34
|
|
27
35
|
Scenario: Prune clients when rotating all keys
|
28
36
|
Given a local mode chef repo with nodes 'one,two,three'
|
@@ -30,4 +38,21 @@ Feature: clean unknown clients on key rotation
|
|
30
38
|
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
31
39
|
And I delete clients 'one,two' from the Chef server
|
32
40
|
And I rotate all keys with the 'clean-unknown-clients' option
|
33
|
-
Then the
|
41
|
+
Then the output should contain "Removing unknown client 'one'"
|
42
|
+
And the output should contain "Removing unknown client 'two'"
|
43
|
+
And the vault item 'test/item' should be encrypted for 'three'
|
44
|
+
And the vault item 'test/item' should not be encrypted for 'one,two'
|
45
|
+
And 'three' should be a client for the vault item 'test/item'
|
46
|
+
And 'one,two' should not be a client for the vault item 'test/item'
|
47
|
+
|
48
|
+
Scenario: Prune clients when node gone but client exists
|
49
|
+
Given a local mode chef repo with nodes 'one,two,three'
|
50
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
51
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
52
|
+
And I delete node 'one' from the Chef server
|
53
|
+
And I rotate the keys for vault item 'test/item' with the 'clean-unknown-clients' option
|
54
|
+
Then the output should contain "Removing unknown client 'one'"
|
55
|
+
And the vault item 'test/item' should be encrypted for 'two,three'
|
56
|
+
And the vault item 'test/item' should not be encrypted for 'one'
|
57
|
+
And 'two,three' should be a client for the vault item 'test/item'
|
58
|
+
And 'one' should not be a client for the vault item 'test/item'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Given
|
1
|
+
Given(/^a local mode chef repo with nodes '(.+?)'(?: with admins '(.+?)')?$/) do |nodelist, adminlist|
|
2
2
|
# create the repo directory hierarchy
|
3
3
|
%w(cookbooks clients nodes data_bags).each do |dir|
|
4
4
|
create_dir dir
|
@@ -9,9 +9,13 @@ local_mode true
|
|
9
9
|
chef_repo_path '.'
|
10
10
|
chef_zero.enabled true
|
11
11
|
EOF
|
12
|
-
# create the admin
|
13
|
-
|
14
|
-
|
12
|
+
# create the admin users and capture their private key we
|
13
|
+
# always create an admin called 'admin' because otherwise subsequent
|
14
|
+
# steps become annoying to determine who the admin is
|
15
|
+
admins = %w(admin)
|
16
|
+
admins.push(adminlist.split(/,/)) if adminlist
|
17
|
+
admins.flatten.each do |admin|
|
18
|
+
create_admin(admin)
|
15
19
|
end
|
16
20
|
# add the admin key to the knife configuration
|
17
21
|
append_to_file 'knife.rb', <<EOF
|
@@ -20,14 +24,48 @@ client_key 'admin.pem'
|
|
20
24
|
EOF
|
21
25
|
# create the requested nodes
|
22
26
|
nodelist.split(/,/).each do |node|
|
23
|
-
|
24
|
-
|
27
|
+
create_client(node)
|
28
|
+
create_node(node)
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
28
|
-
|
32
|
+
Given(/^I create an admin named '(.+)'$/) do |admin|
|
33
|
+
create_admin(admin)
|
34
|
+
end
|
35
|
+
|
36
|
+
Given(/^I delete clients? '(.+)' from the Chef server$/) do |nodelist|
|
29
37
|
nodelist.split(/,/).each do |node|
|
30
|
-
|
38
|
+
delete_client(node)
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|
42
|
+
Given(/^I regenerate the client key for the node '(.+)'$/) do |node|
|
43
|
+
delete_client(node)
|
44
|
+
create_client(node)
|
45
|
+
end
|
46
|
+
|
47
|
+
Given(/^I delete nodes? '(.+)' from the Chef server$/) do |nodelist|
|
48
|
+
nodelist.split(/,/).each { |node| delete_node(node) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_node(name)
|
52
|
+
run_simple "knife node create #{name} -z -d -c knife.rb"
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_admin(admin)
|
56
|
+
create_client(admin, '-a')
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_client(name, args = nil)
|
60
|
+
command = "knife client create #{name} -z -d -c knife.rb #{args} >#{name}.pem"
|
61
|
+
run_simple command
|
62
|
+
write_file("#{name}.pem", stdout_from(command))
|
63
|
+
end
|
64
|
+
|
65
|
+
def delete_client(name)
|
66
|
+
run_simple "knife client delete #{name} -y -z -c knife.rb"
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete_node(name)
|
70
|
+
run_simple "knife node delete #{name} -y -z -c knife.rb"
|
71
|
+
end
|
@@ -1,41 +1,95 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
|
-
|
3
|
+
Given(/^I create a vault item '(.+)\/(.+)' containing the JSON '(.+)' encrypted for '(.+)'(?: with '(.+)' as admins?)?$/) do |vault, item, json, nodelist, admins|
|
4
4
|
write_file 'item.json', json
|
5
5
|
query = nodelist.split(/,/).map{|e| "name:#{e}"}.join(' OR ')
|
6
|
-
|
6
|
+
adminarg = admins.nil? ? '-A admin' : "-A #{admins}"
|
7
|
+
run_simple "knife vault create #{vault} #{item} -z -c knife.rb #{adminarg} -S '#{query}' -J item.json", false
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
+
Given(/^I update the vault item '(.+)\/(.+)' to be encrypted for '(.+)'( with the clean option)?$/) do |vault, item, nodelist, cleanopt|
|
10
11
|
query = nodelist.split(/,/).map{|e| "name:#{e}"}.join(' OR ')
|
11
|
-
run_simple "knife vault update #{vault} #{item} -S '#{query}' #{cleanopt ? '--clean' : ''}"
|
12
|
+
run_simple "knife vault update #{vault} #{item} -z -c knife.rb -S '#{query}' #{cleanopt ? '--clean' : ''}"
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
+
Given(/^I remove clients? '(.+)' from vault item '(.+)\/(.+)' with the '(.+)' options?$/) do |nodelist, vault, item, optionlist|
|
15
16
|
query = nodelist.split(/,/).map{|e| "name:#{e}"}.join(' OR ')
|
16
17
|
options = optionlist.split(/,/).map{|o| "--#{o}"}.join(' ')
|
17
|
-
run_simple "knife vault remove #{vault} #{item} -S '#{query}' #{options}"
|
18
|
+
run_simple "knife vault remove #{vault} #{item} -z -c knife.rb -S '#{query}' #{options}"
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
+
Given(/^I rotate the keys for vault item '(.+)\/(.+)' with the '(.+)' options?$/) do |vault, item, optionlist|
|
21
22
|
options = optionlist.split(/,/).map{|o| "--#{o}"}.join(' ')
|
22
|
-
run_simple "knife vault rotate keys #{vault} #{item} #{options}"
|
23
|
+
run_simple "knife vault rotate keys #{vault} #{item} -c knife.rb -z #{options}"
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
+
Given(/^I rotate all keys with the '(.+)' options?$/) do |optionlist|
|
26
27
|
options = optionlist.split(/,/).map{|o| "--#{o}"}.join(' ')
|
27
|
-
run_simple "knife vault rotate all keys #{options}"
|
28
|
+
run_simple "knife vault rotate all keys -z -c knife.rb #{options}"
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
+
Given(/^I try to decrypt the vault item '(.+)\/(.+)' as '(.+)'$/) do |vault, item, node|
|
32
|
+
run_simple "knife vault show #{vault} #{item} -z -c knife.rb -u #{node} -k #{node}.pem", false
|
33
|
+
end
|
34
|
+
|
35
|
+
Then(/^the vault item '(.+)\/(.+)' should( not)? be encrypted for '(.+)'$/) do |vault, item, neg, nodelist|
|
31
36
|
nodes = nodelist.split(/,/)
|
32
|
-
|
33
|
-
|
37
|
+
command = "knife data bag show #{vault} #{item}_keys -z -c knife.rb -F json"
|
38
|
+
run_simple(command)
|
39
|
+
output = stdout_from(command)
|
40
|
+
data = JSON.parse(output)
|
34
41
|
nodes.each do |node|
|
35
42
|
if neg
|
36
|
-
|
43
|
+
expect(data).not_to include(node)
|
37
44
|
else
|
38
|
-
|
45
|
+
expect(data).to include(node)
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
49
|
+
|
50
|
+
Given(/^'(.+)' should( not)? be a client for the vault item '(.+)\/(.+)'$/) do |nodelist, neg, vault, item|
|
51
|
+
nodes = nodelist.split(/,/)
|
52
|
+
command = "knife data bag show #{vault} #{item}_keys -z -c knife.rb -F json"
|
53
|
+
run_simple(command)
|
54
|
+
output = stdout_from(command)
|
55
|
+
data = JSON.parse(output)
|
56
|
+
nodes.each do |node|
|
57
|
+
if neg
|
58
|
+
expect(data['clients']).not_to include(node)
|
59
|
+
else
|
60
|
+
expect(data['clients']).to include(node)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Given(/^'(.+)' should( not)? be an admin for the vault item '(.+)\/(.+)'$/) do |nodelist, neg, vault, item|
|
66
|
+
nodes = nodelist.split(/,/)
|
67
|
+
command = "knife data bag show #{vault} #{item}_keys -z -c knife.rb -F json"
|
68
|
+
run_simple(command)
|
69
|
+
output = stdout_from(command)
|
70
|
+
data = JSON.parse(output)
|
71
|
+
nodes.each do |node|
|
72
|
+
if neg
|
73
|
+
expect(data['admins']).not_to include(node)
|
74
|
+
else
|
75
|
+
expect(data['admins']).to include(node)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
Given(/^I list the vaults$/) do
|
81
|
+
run_simple('knife vault list')
|
82
|
+
end
|
83
|
+
|
84
|
+
Given(/^I can('t)? decrypt the vault item '(.+)\/(.+)' as '(.+)'$/) do |neg, vault, item, client|
|
85
|
+
run_simple "knife vault show #{vault} #{item} -c knife.rb -z -u #{client} -k #{client}.pem", false
|
86
|
+
if neg
|
87
|
+
assert_not_exit_status(0)
|
88
|
+
else
|
89
|
+
assert_exit_status(0)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
Given(/^I add '(.+)' as an admin for the vault item '(.+)\/(.+)'$/) do |newadmin, vault, item|
|
94
|
+
run_simple "knife vault update #{vault} #{item} -c knife.rb -z -A #{newadmin}"
|
95
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -7,8 +7,8 @@ require 'aruba/cucumber'
|
|
7
7
|
# Travis runs tests in a limited environment which takes a long time to invoke
|
8
8
|
# the knife command. Up the timeout when we're in a travis build based on the
|
9
9
|
# environment variable set in .travis.yml
|
10
|
-
if ENV['TRAVIS_BUILD']
|
10
|
+
#if ENV['TRAVIS_BUILD']
|
11
11
|
Before do
|
12
12
|
@aruba_timeout_seconds = 15
|
13
13
|
end
|
14
|
-
end
|
14
|
+
#end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Feature: knife vault create
|
2
|
+
|
3
|
+
'knife vault create' creates two Chef data bag items: an
|
4
|
+
encrypted data bag item encrypted with a randomized shared
|
5
|
+
secret, and a side-along data bag item suffixed with _keys
|
6
|
+
that contains an set of asymmetrically encrypted copies of
|
7
|
+
the shared secret using the public keys of a set of admins
|
8
|
+
and/or clients
|
9
|
+
|
10
|
+
Scenario: create vault with all known clients
|
11
|
+
Given a local mode chef repo with nodes 'one,two,three'
|
12
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
13
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
14
|
+
And 'one,two,three' should be a client for the vault item 'test/item'
|
15
|
+
|
16
|
+
Scenario: create vault with all unknown clients
|
17
|
+
Given a local mode chef repo with nodes 'two,three'
|
18
|
+
And I delete clients 'two,three' from the Chef server
|
19
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'two,three'
|
20
|
+
Then the vault item 'test/item' should not be encrypted for 'one,two,three'
|
21
|
+
And the output should contain "node 'two' has no private key; skipping"
|
22
|
+
And the output should contain "node 'three' has no private key; skipping"
|
23
|
+
And 'two,three' should not be a client for the vault item 'test/item'
|
24
|
+
|
25
|
+
Scenario: create vault with mix of known and unknown clients
|
26
|
+
Given a local mode chef repo with nodes 'one,two,three'
|
27
|
+
And I delete client 'three' from the Chef server
|
28
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
29
|
+
Then the vault item 'test/item' should be encrypted for 'one,two'
|
30
|
+
And the output should contain "node 'three' has no private key; skipping"
|
31
|
+
And 'one,two' should be a client for the vault item 'test/item'
|
32
|
+
And 'three' should not be a client for the vault item 'test/item'
|
33
|
+
|
34
|
+
Scenario: create vault with mix of known and unknown nodes
|
35
|
+
Given a local mode chef repo with nodes 'one,two'
|
36
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
37
|
+
Then the vault item 'test/item' should be encrypted for 'one,two'
|
38
|
+
And 'one,two' should be a client for the vault item 'test/item'
|
39
|
+
And 'three' should not be a client for the vault item 'test/item'
|
40
|
+
|
41
|
+
Scenario: create vault with several admins
|
42
|
+
Given a local mode chef repo with nodes 'one,two' with admins 'alice,bob'
|
43
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
44
|
+
Then the vault item 'test/item' should be encrypted for 'one,two'
|
45
|
+
And 'one,two' should be a client for the vault item 'test/item'
|
46
|
+
And 'three' should not be a client for the vault item 'test/item'
|
47
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
48
|
+
And 'bob' should not be an admin for the vault item 'test/item'
|
49
|
+
|
50
|
+
Scenario: create vault with an unknown admin
|
51
|
+
Given a local mode chef repo with nodes 'one,two'
|
52
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
53
|
+
Then the exit status should not be 0
|
54
|
+
And the output should contain "FATAL: Could not find alice in users or clients!"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Feature: list data bags that are vaults
|
2
|
+
|
3
|
+
knife vault list should list all data bags that appear to
|
4
|
+
be vaults. This is not an exact science; we assume that
|
5
|
+
any data bag containing an even number of items and for
|
6
|
+
which all items are pairs of thing/thing_keys is a vault
|
7
|
+
|
8
|
+
Scenario: List bags that are vaults
|
9
|
+
Given a local mode chef repo with nodes 'one,two,three'
|
10
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
11
|
+
And I list the vaults
|
12
|
+
Then the output should match /(?m:^test$)/
|
13
|
+
|
14
|
+
Scenario: Skip data bags that are not vaults
|
15
|
+
Given a local mode chef repo with nodes 'one,two,three'
|
16
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three'
|
17
|
+
And I create a data bag 'lessthantwokeys' containing the JSON '{"id": "item", "foo": "bar"}'
|
18
|
+
And I create a data bag 'oddnumberofkeys' containing the JSON '{"id": "item", "one": 1, "two": 2, "three":3}'
|
19
|
+
And I create a data bag 'unbalanced' containing the JSON '{"id": "item", "one": 1, "one_keys": 1, "two_keys": 1, "three_keys": 1}'
|
20
|
+
And I create a data bag 'mismatched' containing the JSON '{"id": "item", "one": 1, "one_keys": 1, "two_keys": 1, "three": 1}'
|
21
|
+
And I list the vaults
|
22
|
+
Then the output should match /(?m:^test$)/
|
23
|
+
And the output should not match /(?m:^lessthantwokeys$)/
|
24
|
+
And the output should not match /(?m:^oddnumberofkeys$)/
|
25
|
+
And the output should not match /(?m:^unbalanced$)/
|
26
|
+
And the output should not match /(?m:^mismatched$)/
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Feature: knife vault show
|
2
|
+
|
3
|
+
'knife vault show' displays the contents of a Chef encrypted
|
4
|
+
data bag by fetching the asymmetrically encrypted shared
|
5
|
+
secret and decrypting it using the private key of the user
|
6
|
+
or node
|
7
|
+
|
8
|
+
Scenario: successful decrypt as admin
|
9
|
+
Given a local mode chef repo with nodes 'one,two,three' with admins 'alice,bob'
|
10
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
11
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three,alice'
|
12
|
+
And 'one,two,three' should be a client for the vault item 'test/item'
|
13
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
14
|
+
And 'bob' should not be an admin for the vault item 'test/item'
|
15
|
+
And I can decrypt the vault item 'test/item' as 'alice'
|
16
|
+
And the output should match /^foo: bar$/
|
17
|
+
|
18
|
+
Scenario: successful decrypt as node
|
19
|
+
Given a local mode chef repo with nodes 'one,two,three' with admins 'alice,bob'
|
20
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
21
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three,alice'
|
22
|
+
And 'one,two,three' should be a client for the vault item 'test/item'
|
23
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
24
|
+
And 'bob' should not be an admin for the vault item 'test/item'
|
25
|
+
And I can decrypt the vault item 'test/item' as 'two'
|
26
|
+
And the output should match /^foo: bar$/
|
27
|
+
|
28
|
+
Scenario: failed decrypt as admin
|
29
|
+
Given a local mode chef repo with nodes 'one,two,three' with admins 'alice,bob'
|
30
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
31
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three,alice'
|
32
|
+
And 'one,two,three' should be a client for the vault item 'test/item'
|
33
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
34
|
+
And 'bob' should not be an admin for the vault item 'test/item'
|
35
|
+
And I can't decrypt the vault item 'test/item' as 'bob'
|
36
|
+
And the output should contain "test/item is not encrypted with your public key"
|
37
|
+
|
38
|
+
Scenario: failed decrypt as node
|
39
|
+
Given a local mode chef repo with nodes 'one,two,three' with admins 'alice,bob'
|
40
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two' with 'alice' as admin
|
41
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,alice'
|
42
|
+
And 'one,two' should be a client for the vault item 'test/item'
|
43
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
44
|
+
And 'bob' should not be an admin for the vault item 'test/item'
|
45
|
+
And I can't decrypt the vault item 'test/item' as 'three'
|
46
|
+
And the output should contain "test/item is not encrypted with your public key"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: knife vault create
|
2
|
+
|
3
|
+
'knife vault update' is used to add clients, or administrators
|
4
|
+
and to re-run the search query
|
5
|
+
|
6
|
+
Scenario: add admin to a vault
|
7
|
+
Given a local mode chef repo with nodes 'one,two,three' with admins 'alice,bob'
|
8
|
+
And I create a vault item 'test/item' containing the JSON '{"foo": "bar"}' encrypted for 'one,two,three' with 'alice' as admin
|
9
|
+
Then the vault item 'test/item' should be encrypted for 'one,two,three'
|
10
|
+
And 'one,two,three' should be a client for the vault item 'test/item'
|
11
|
+
And 'alice' should be an admin for the vault item 'test/item'
|
12
|
+
And I can decrypt the vault item 'test/item' as 'alice'
|
13
|
+
And I can't decrypt the vault item 'test/item' as 'bob'
|
14
|
+
And I add 'bob' as an admin for the vault item 'test/item'
|
15
|
+
Then 'alice,bob' should be an admin for the vault item 'test/item'
|
16
|
+
And I can decrypt the vault item 'test/item' as 'alice'
|
17
|
+
And I can decrypt the vault item 'test/item' as 'bob'
|