chef-vault 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|