chef-vault 2.6.1 → 2.7.1
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 +6 -1
- data/.travis.yml +5 -6
- data/CONTRIBUTING.md +2 -2
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +16 -20
- data/THEORY.md +1 -1
- data/UPGRADE.md +55 -0
- data/bin/chef-vault +8 -8
- data/chef-vault.gemspec +21 -21
- data/features/detect_and_warn_v1_vault.feature +15 -0
- data/features/step_definitions/chef-databag.rb +1 -1
- data/features/step_definitions/chef-repo.rb +7 -7
- data/features/step_definitions/chef-vault.rb +30 -22
- data/features/step_definitions/chef_databagitem.rb +2 -2
- data/features/support/env.rb +3 -3
- data/lib/chef-vault.rb +15 -15
- data/lib/chef-vault/chef_patch/api_client.rb +5 -5
- data/lib/chef-vault/chef_patch/user.rb +5 -5
- data/lib/chef-vault/exceptions.rb +3 -0
- data/lib/chef-vault/item.rb +13 -19
- data/lib/chef-vault/item_keys.rb +13 -13
- data/lib/chef-vault/mixins.rb +36 -0
- data/lib/chef-vault/version.rb +3 -2
- data/lib/chef/knife/decrypt.rb +2 -2
- data/lib/chef/knife/encrypt_create.rb +13 -13
- data/lib/chef/knife/encrypt_delete.rb +2 -2
- data/lib/chef/knife/encrypt_remove.rb +8 -8
- data/lib/chef/knife/encrypt_rotate_keys.rb +2 -2
- data/lib/chef/knife/encrypt_update.rb +13 -13
- data/lib/chef/knife/mixin/compat.rb +2 -2
- data/lib/chef/knife/vault_admins.rb +3 -3
- data/lib/chef/knife/vault_base.rb +9 -9
- data/lib/chef/knife/vault_create.rb +13 -13
- data/lib/chef/knife/vault_decrypt.rb +2 -2
- data/lib/chef/knife/vault_delete.rb +1 -1
- data/lib/chef/knife/vault_download.rb +2 -2
- data/lib/chef/knife/vault_edit.rb +6 -6
- 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 +4 -4
- data/lib/chef/knife/vault_refresh.rb +3 -3
- data/lib/chef/knife/vault_remove.rb +9 -9
- data/lib/chef/knife/vault_rotate_all_keys.rb +4 -4
- data/lib/chef/knife/vault_rotate_keys.rb +3 -3
- data/lib/chef/knife/vault_show.rb +12 -12
- data/lib/chef/knife/vault_update.rb +15 -15
- data/spec/chef-vault/certificate_spec.rb +7 -7
- data/spec/chef-vault/item_keys_spec.rb +53 -6
- data/spec/chef-vault/item_spec.rb +110 -110
- data/spec/chef-vault/user_spec.rb +6 -6
- data/spec/chef-vault_spec.rb +10 -10
- data/spec/spec_helper.rb +3 -3
- metadata +7 -6
- data/.rubocop_todo.yml +0 -101
@@ -1,9 +1,9 @@
|
|
1
1
|
Given(/^I create a data bag item '(.+)\/(.+)' containing the JSON '(.+)'$/) do |databag, _, json|
|
2
|
-
write_file
|
2
|
+
write_file "item.json", json
|
3
3
|
run_simple "knife data bag from file #{databag} item.json -z -c knife.rb", false
|
4
4
|
end
|
5
5
|
|
6
6
|
Given(/^I create an encrypted data bag item '(.+)\/(.+)' containing the JSON '(.+)' with the secret '(.+)'$/) do |databag, _, json, secret|
|
7
|
-
write_file
|
7
|
+
write_file "item.json", json
|
8
8
|
run_simple "knife data bag from file #{databag} item.json -s #{secret} -z -c knife.rb", false
|
9
9
|
end
|
data/features/support/env.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
if ENV[
|
2
|
-
require
|
1
|
+
if ENV["COVERAGE"]
|
2
|
+
require "simplecov"
|
3
3
|
end
|
4
4
|
|
5
|
-
require
|
5
|
+
require "aruba/cucumber"
|
6
6
|
|
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
|
data/lib/chef-vault.rb
CHANGED
@@ -16,21 +16,21 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
29
|
-
require
|
30
|
-
require
|
31
|
-
require
|
32
|
-
require
|
33
|
-
require
|
19
|
+
require "chef/search/query"
|
20
|
+
require "chef/version"
|
21
|
+
require "chef/config"
|
22
|
+
require "chef/api_client"
|
23
|
+
require "chef/data_bag_item"
|
24
|
+
require "chef/encrypted_data_bag_item"
|
25
|
+
require "chef/user"
|
26
|
+
require "chef-vault/version"
|
27
|
+
require "chef-vault/exceptions"
|
28
|
+
require "chef-vault/item"
|
29
|
+
require "chef-vault/item_keys"
|
30
|
+
require "chef-vault/user"
|
31
|
+
require "chef-vault/certificate"
|
32
|
+
require "chef-vault/chef_patch/api_client"
|
33
|
+
require "chef-vault/chef_patch/user"
|
34
34
|
|
35
35
|
class ChefVault
|
36
36
|
attr_accessor :vault
|
@@ -25,15 +25,15 @@ class ChefVault
|
|
25
25
|
response
|
26
26
|
else
|
27
27
|
client = Chef::ApiClient.new
|
28
|
-
client.name(response[
|
28
|
+
client.name(response["clientname"] || response["name"])
|
29
29
|
|
30
|
-
if response[
|
31
|
-
der = OpenSSL::X509::Certificate.new response[
|
30
|
+
if response["certificate"]
|
31
|
+
der = OpenSSL::X509::Certificate.new response["certificate"]
|
32
32
|
client.public_key der.public_key.to_s
|
33
33
|
end
|
34
34
|
|
35
|
-
if response[
|
36
|
-
der = OpenSSL::PKey::RSA.new response[
|
35
|
+
if response["public_key"]
|
36
|
+
der = OpenSSL::PKey::RSA.new response["public_key"]
|
37
37
|
client.public_key der.public_key.to_s
|
38
38
|
end
|
39
39
|
|
@@ -21,11 +21,11 @@ class ChefVault
|
|
21
21
|
# set correctly for Chef 10 server
|
22
22
|
def superclass.from_hash(user_hash)
|
23
23
|
user = Chef::User.new
|
24
|
-
user.name user_hash[
|
25
|
-
user.private_key user_hash[
|
26
|
-
user.password user_hash[
|
27
|
-
user.public_key user_hash[
|
28
|
-
user.admin user_hash[
|
24
|
+
user.name user_hash["username"] ? user_hash["username"] : user_hash["name"]
|
25
|
+
user.private_key user_hash["private_key"] if user_hash.key?("private_key")
|
26
|
+
user.password user_hash["password"] if user_hash.key?("password")
|
27
|
+
user.public_key user_hash["public_key"]
|
28
|
+
user.admin user_hash["admin"]
|
29
29
|
user
|
30
30
|
end
|
31
31
|
end
|
data/lib/chef-vault/item.rb
CHANGED
@@ -14,10 +14,13 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
require
|
17
|
+
require "securerandom"
|
18
|
+
require "chef-vault/mixins"
|
18
19
|
|
19
20
|
class ChefVault
|
20
21
|
class Item < Chef::DataBagItem
|
22
|
+
include ChefVault::Mixins
|
23
|
+
|
21
24
|
# @!attribute [rw] keys
|
22
25
|
# @return [ChefVault::ItemKeys] the keys associated with this vault
|
23
26
|
attr_accessor :keys
|
@@ -60,7 +63,7 @@ class ChefVault
|
|
60
63
|
@encrypted = false
|
61
64
|
opts = {
|
62
65
|
:node_name => Chef::Config[:node_name],
|
63
|
-
:client_key_path => Chef::Config[:client_key]
|
66
|
+
:client_key_path => Chef::Config[:client_key],
|
64
67
|
}.merge(opts)
|
65
68
|
@node_name = opts[:node_name]
|
66
69
|
@client_key_path = opts[:client_key_path]
|
@@ -192,13 +195,13 @@ class ChefVault
|
|
192
195
|
super
|
193
196
|
end
|
194
197
|
|
195
|
-
def save(item_id=@raw_data[
|
198
|
+
def save(item_id=@raw_data["id"])
|
196
199
|
# validate the format of the id before attempting to save
|
197
200
|
validate_id!(item_id)
|
198
201
|
|
199
202
|
# ensure that the ID of the vault hasn't changed since the keys
|
200
203
|
# data bag item was created
|
201
|
-
keys_id = keys[
|
204
|
+
keys_id = keys["id"].match(/^(.+)_keys/)[1]
|
202
205
|
if keys_id != item_id
|
203
206
|
raise ChefVault::Exceptions::IdMismatch,
|
204
207
|
"id mismatch - input JSON has id '#{item_id}' but vault item has id '#{keys_id}'"
|
@@ -217,16 +220,7 @@ class ChefVault
|
|
217
220
|
|
218
221
|
# Now save the encrypted data
|
219
222
|
if Chef::Config[:solo]
|
220
|
-
|
221
|
-
data_bag)
|
222
|
-
data_bag_item_path = File.join(data_bag_path, item_id)
|
223
|
-
|
224
|
-
FileUtils.mkdir(data_bag_path) unless File.exist?(data_bag_path)
|
225
|
-
File.open("#{data_bag_item_path}.json", 'w') do |file|
|
226
|
-
file.write(JSON.pretty_generate(raw_data))
|
227
|
-
end
|
228
|
-
|
229
|
-
raw_data
|
223
|
+
save_solo(item_id)
|
230
224
|
else
|
231
225
|
begin
|
232
226
|
Chef::DataBag.load(data_bag)
|
@@ -317,7 +311,7 @@ class ChefVault
|
|
317
311
|
# and https://github.com/sensu/sensu-chef/blob/2.9.0/libraries/sensu_helpers.rb
|
318
312
|
dbi = Chef::DataBagItem.load(vault, name)
|
319
313
|
encrypted = dbi.detect do |_, v|
|
320
|
-
v.is_a?(Hash) && v.key?(
|
314
|
+
v.is_a?(Hash) && v.key?("encrypted_data")
|
321
315
|
end
|
322
316
|
|
323
317
|
# return a symbol describing the type of item we detected
|
@@ -340,9 +334,9 @@ class ChefVault
|
|
340
334
|
unless search
|
341
335
|
raise ChefVault::Exceptions::SearchNotFound,
|
342
336
|
"#{vault}/#{item} does not have a stored search_query, "\
|
343
|
-
|
337
|
+
"probably because it was created with an older version "\
|
344
338
|
"of chef-vault. Use 'knife vault update' to update the "\
|
345
|
-
|
339
|
+
"databag with the search query."
|
346
340
|
end
|
347
341
|
|
348
342
|
# a bit of a misnomer; this doesn't remove unknown
|
@@ -474,14 +468,14 @@ class ChefVault
|
|
474
468
|
# @param client [Chef::ApiClient] the API client to add
|
475
469
|
# @return [void]
|
476
470
|
def add_client(client)
|
477
|
-
keys.add(client, @secret,
|
471
|
+
keys.add(client, @secret, "clients")
|
478
472
|
end
|
479
473
|
|
480
474
|
# removes a client to the vault item keys
|
481
475
|
# @param client_or_node [Chef::ApiClient,Chef::Node] the API client or node to remove
|
482
476
|
# @return [void]
|
483
477
|
def delete_client_or_node(client_or_node)
|
484
|
-
keys.delete(client_or_node.name,
|
478
|
+
keys.delete(client_or_node.name, "clients")
|
485
479
|
end
|
486
480
|
end
|
487
481
|
end
|
data/lib/chef-vault/item_keys.rb
CHANGED
@@ -14,8 +14,13 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
require "chef-vault/mixins"
|
18
|
+
|
17
19
|
class ChefVault
|
18
20
|
class ItemKeys < Chef::DataBagItem
|
21
|
+
|
22
|
+
include ChefVault::Mixins
|
23
|
+
|
19
24
|
def initialize(vault, name)
|
20
25
|
super() # parentheses required to strip off parameters
|
21
26
|
@data_bag = vault
|
@@ -30,6 +35,10 @@ class ChefVault
|
|
30
35
|
end
|
31
36
|
|
32
37
|
def add(chef_client, data_bag_shared_secret, type)
|
38
|
+
unless @raw_data.key?(type)
|
39
|
+
raise ChefVault::Exceptions::V1Format,
|
40
|
+
"cannot manage a v1 vault. See UPGRADE.md for help"
|
41
|
+
end
|
33
42
|
public_key = OpenSSL::PKey::RSA.new chef_client.public_key
|
34
43
|
self[chef_client.name] =
|
35
44
|
Base64.encode64(public_key.public_encrypt(data_bag_shared_secret))
|
@@ -59,18 +68,9 @@ class ChefVault
|
|
59
68
|
@raw_data["admins"]
|
60
69
|
end
|
61
70
|
|
62
|
-
def save(item_id=@raw_data[
|
71
|
+
def save(item_id=@raw_data["id"])
|
63
72
|
if Chef::Config[:solo]
|
64
|
-
|
65
|
-
data_bag)
|
66
|
-
data_bag_item_path = File.join(data_bag_path, item_id)
|
67
|
-
|
68
|
-
FileUtils.mkdir(data_bag_path) unless File.exist?(data_bag_path)
|
69
|
-
File.open("#{data_bag_item_path}.json", 'w') do |file|
|
70
|
-
file.write(JSON.pretty_generate(raw_data))
|
71
|
-
end
|
72
|
-
|
73
|
-
raw_data
|
73
|
+
save_solo(item_id)
|
74
74
|
else
|
75
75
|
begin
|
76
76
|
Chef::DataBag.load(data_bag)
|
@@ -117,13 +117,13 @@ class ChefVault
|
|
117
117
|
rescue Net::HTTPServerException => http_error
|
118
118
|
if http_error.response.code == "404"
|
119
119
|
raise ChefVault::Exceptions::KeysNotFound,
|
120
|
-
|
120
|
+
"#{vault}/#{name} could not be found"
|
121
121
|
else
|
122
122
|
raise http_error
|
123
123
|
end
|
124
124
|
rescue Chef::Exceptions::ValidationFailed
|
125
125
|
raise ChefVault::Exceptions::KeysNotFound,
|
126
|
-
|
126
|
+
"#{vault}/#{name} could not be found"
|
127
127
|
end
|
128
128
|
|
129
129
|
from_data_bag_item(data_bag_item)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class ChefVault
|
2
|
+
module Mixins
|
3
|
+
# In Chef 12, Chef Solo can have an array of data_bag paths, rather
|
4
|
+
# than just a string. To cope with that, we'll:
|
5
|
+
# 1. Look for an existing data bag item in any of the configured
|
6
|
+
# paths and use that by preference
|
7
|
+
# 1. Otherwise, just use the first location in the array
|
8
|
+
def find_solo_path(item_id)
|
9
|
+
if Chef::Config[:data_bag_path].kind_of?(Array)
|
10
|
+
path = Chef::Config[:data_bag_path].find { |dir|
|
11
|
+
File.exist?(File.join(dir, data_bag, "#{item_id}.json"))
|
12
|
+
}
|
13
|
+
|
14
|
+
path ||= Chef::Config[:data_bag_path].first
|
15
|
+
data_bag_path = File.join(path, data_bag)
|
16
|
+
else
|
17
|
+
data_bag_path = File.join(Chef::Config[:data_bag_path],
|
18
|
+
data_bag)
|
19
|
+
end
|
20
|
+
data_bag_item_path = File.join(data_bag_path, item_id) + ".json"
|
21
|
+
|
22
|
+
[data_bag_path, data_bag_item_path]
|
23
|
+
end
|
24
|
+
|
25
|
+
def save_solo(item_id=@raw_data["id"])
|
26
|
+
data_bag_path, data_bag_item_path = find_solo_path(item_id)
|
27
|
+
|
28
|
+
FileUtils.mkdir(data_bag_path) unless File.exist?(data_bag_path)
|
29
|
+
File.open(data_bag_item_path, "w") do |file|
|
30
|
+
file.write(JSON.pretty_generate(raw_data))
|
31
|
+
end
|
32
|
+
|
33
|
+
raw_data
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/chef-vault/version.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Description: ChefVault VERSION file
|
2
2
|
# Copyright 2013-15, Nordstrom, Inc.
|
3
|
+
# Copyright 2015-2016, Chef Software, Inc.
|
3
4
|
|
4
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
6
|
# you may not use this file except in compliance with the License.
|
@@ -14,6 +15,6 @@
|
|
14
15
|
# limitations under the License.
|
15
16
|
|
16
17
|
class ChefVault
|
17
|
-
VERSION =
|
18
|
-
MAJOR, MINOR, TINY = VERSION.split(
|
18
|
+
VERSION = "2.7.1"
|
19
|
+
MAJOR, MINOR, TINY = VERSION.split(".")
|
19
20
|
end
|
data/lib/chef/knife/decrypt.rb
CHANGED
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_decrypt"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_create"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -24,23 +24,23 @@ class Chef
|
|
24
24
|
banner "knife encrypt create VAULT ITEM VALUES (options)"
|
25
25
|
|
26
26
|
option :search,
|
27
|
-
:short =>
|
28
|
-
:long =>
|
29
|
-
:description =>
|
27
|
+
:short => "-S SEARCH",
|
28
|
+
:long => "--search SEARCH",
|
29
|
+
:description => "Chef SOLR search for clients"
|
30
30
|
|
31
31
|
option :admins,
|
32
|
-
:short =>
|
33
|
-
:long =>
|
34
|
-
:description =>
|
32
|
+
:short => "-A ADMINS",
|
33
|
+
:long => "--admins ADMINS",
|
34
|
+
:description => "Chef users to be added as admins"
|
35
35
|
|
36
36
|
option :json,
|
37
|
-
:short =>
|
38
|
-
:long =>
|
39
|
-
:description =>
|
37
|
+
:short => "-J FILE",
|
38
|
+
:long => "--json FILE",
|
39
|
+
:description => "File containing JSON data to encrypt"
|
40
40
|
|
41
41
|
option :file,
|
42
|
-
:long =>
|
43
|
-
:description =>
|
42
|
+
:long => "--file FILE",
|
43
|
+
:description => "File to be added to vault item as file-content"
|
44
44
|
|
45
45
|
def run
|
46
46
|
$stdout.puts "DEPRECATION WARNING: knife encrypt is deprecated. Please use knife vault instead."
|
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_delete"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_remove"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -24,14 +24,14 @@ class Chef
|
|
24
24
|
banner "knife encrypt remove VAULT ITEM VALUES (options)"
|
25
25
|
|
26
26
|
option :search,
|
27
|
-
:short =>
|
28
|
-
:long =>
|
29
|
-
:description =>
|
27
|
+
:short => "-S SEARCH",
|
28
|
+
:long => "--search SEARCH",
|
29
|
+
:description => "Chef SOLR search for clients"
|
30
30
|
|
31
31
|
option :admins,
|
32
|
-
:short =>
|
33
|
-
:long =>
|
34
|
-
:description =>
|
32
|
+
:short => "-A ADMINS",
|
33
|
+
:long => "--admins ADMINS",
|
34
|
+
:description => "Chef users to be added as admins"
|
35
35
|
|
36
36
|
def run
|
37
37
|
$stdout.puts "DEPRECATION WARNING: knife encrypt is deprecated. Please use knife vault instead."
|
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_rotate_keys"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -13,8 +13,8 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
require
|
17
|
-
require
|
16
|
+
require "chef/knife/vault_base"
|
17
|
+
require "chef/knife/vault_update"
|
18
18
|
|
19
19
|
class Chef
|
20
20
|
class Knife
|
@@ -22,23 +22,23 @@ class Chef
|
|
22
22
|
include Knife::VaultBase
|
23
23
|
|
24
24
|
option :search,
|
25
|
-
:short =>
|
26
|
-
:long =>
|
27
|
-
:description =>
|
25
|
+
:short => "-S SEARCH",
|
26
|
+
:long => "--search SEARCH",
|
27
|
+
:description => "Chef SOLR search for clients"
|
28
28
|
|
29
29
|
option :admins,
|
30
|
-
:short =>
|
31
|
-
:long =>
|
32
|
-
:description =>
|
30
|
+
:short => "-A ADMINS",
|
31
|
+
:long => "--admins ADMINS",
|
32
|
+
:description => "Chef users to be added as admins"
|
33
33
|
|
34
34
|
option :json,
|
35
|
-
:short =>
|
36
|
-
:long =>
|
37
|
-
:description =>
|
35
|
+
:short => "-J FILE",
|
36
|
+
:long => "--json FILE",
|
37
|
+
:description => "File containing JSON data to encrypt"
|
38
38
|
|
39
39
|
option :file,
|
40
|
-
:long =>
|
41
|
-
:description =>
|
40
|
+
:long => "--file FILE",
|
41
|
+
:description => "File to be added to vault item as file-content"
|
42
42
|
|
43
43
|
banner "knife encrypt update VAULT ITEM VALUES (options)"
|
44
44
|
|