chef-vault 2.1.0 → 2.2.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 +8 -8
- data/.gitignore +2 -0
- data/CONTRIBUTING.md +3 -3
- data/Changelog.md +11 -1
- data/KNIFE_EXAMPLES.md +102 -72
- data/README.md +37 -35
- data/lib/chef-vault/item.rb +30 -18
- data/lib/chef-vault/item_keys.rb +15 -6
- data/lib/chef-vault/version.rb +1 -1
- data/lib/chef/knife/decrypt.rb +33 -0
- data/lib/chef/knife/encrypt_create.rb +25 -74
- data/lib/chef/knife/encrypt_delete.rb +10 -39
- data/lib/chef/knife/encrypt_remove.rb +18 -75
- data/lib/chef/knife/encrypt_rotate_keys.rb +10 -39
- data/lib/chef/knife/encrypt_update.rb +25 -73
- data/lib/chef/knife/vault_base.rb +46 -0
- data/lib/chef/knife/vault_create.rb +95 -0
- data/lib/chef/knife/vault_decrypt.rb +59 -0
- data/lib/chef/knife/vault_delete.rb +49 -0
- data/lib/chef/knife/vault_edit.rb +70 -0
- data/lib/chef/knife/vault_remove.rb +86 -0
- data/lib/chef/knife/vault_rotate_all_keys.rb +57 -0
- data/lib/chef/knife/vault_rotate_keys.rb +49 -0
- data/lib/chef/knife/vault_show.rb +89 -0
- data/lib/chef/knife/vault_update.rb +87 -0
- data/spec/chef-vault_spec.rb +11 -36
- data/spec/item_keys_spec.rb +6 -18
- data/spec/item_spec.rb +16 -21
- metadata +13 -3
- data/lib/chef/knife/Decrypt.rb +0 -71
@@ -0,0 +1,86 @@
|
|
1
|
+
# Description: Chef-Vault VaultRemove class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife/vault_base'
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class VaultRemove < Knife
|
21
|
+
|
22
|
+
include Chef::Knife::VaultBase
|
23
|
+
|
24
|
+
banner "knife vault remove VAULT ITEM VALUES (options)"
|
25
|
+
|
26
|
+
option :search,
|
27
|
+
:short => '-S SEARCH',
|
28
|
+
:long => '--search SEARCH',
|
29
|
+
:description => 'Chef SOLR search for clients'
|
30
|
+
|
31
|
+
option :admins,
|
32
|
+
:short => '-A ADMINS',
|
33
|
+
:long => '--admins ADMINS',
|
34
|
+
:description => 'Chef users to be added as admins'
|
35
|
+
|
36
|
+
def run
|
37
|
+
vault = @name_args[0]
|
38
|
+
item = @name_args[1]
|
39
|
+
values = @name_args[2]
|
40
|
+
search = config[:search]
|
41
|
+
admins = config[:admins]
|
42
|
+
json_file = config[:json]
|
43
|
+
|
44
|
+
set_mode(config[:vault_mode])
|
45
|
+
|
46
|
+
if vault && item && ((values || json_file) || (search || admins))
|
47
|
+
begin
|
48
|
+
vault_item = ChefVault::Item.load(vault, item)
|
49
|
+
remove_items = []
|
50
|
+
|
51
|
+
if values || json_file
|
52
|
+
begin
|
53
|
+
json = JSON.parse(values)
|
54
|
+
json.each do |key, value|
|
55
|
+
remove_items << key
|
56
|
+
end
|
57
|
+
rescue JSON::ParserError
|
58
|
+
remove_items = values.split(",")
|
59
|
+
rescue Exception => e
|
60
|
+
raise e
|
61
|
+
end
|
62
|
+
|
63
|
+
remove_items.each do |key|
|
64
|
+
key.strip!
|
65
|
+
vault_item.remove(key)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
vault_item.clients(search, :delete) if search
|
70
|
+
vault_item.admins(admins, :delete) if admins
|
71
|
+
|
72
|
+
vault_item.rotate_keys!
|
73
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
74
|
+
ChefVault::Exceptions::ItemNotFound
|
75
|
+
|
76
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
77
|
+
"#{vault}/#{item} does not exist, "\
|
78
|
+
"use 'knife vault create' to create."
|
79
|
+
end
|
80
|
+
else
|
81
|
+
show_usage
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Description: Chef-Vault VaultRotateAllKeys class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife/vault_base'
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class VaultRotateAllKeys < Knife
|
21
|
+
|
22
|
+
include Chef::Knife::VaultBase
|
23
|
+
|
24
|
+
banner "knife vault rotate all keys"
|
25
|
+
|
26
|
+
def run
|
27
|
+
set_mode(config[:vault_mode])
|
28
|
+
rotate_all_keys
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def rotate_all_keys
|
34
|
+
vaults = Chef::DataBag.list.keys
|
35
|
+
vaults.each { |vault| rotate_vault_keys(vault) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def rotate_vault_keys(vault)
|
39
|
+
vault_items(vault).each do |item|
|
40
|
+
rotate_vault_item_keys(vault, item)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def vault_items(vault)
|
45
|
+
Chef::DataBag.load(vault).keys.inject([]) do |array, key|
|
46
|
+
array << key.sub('_keys', '') if key.match(/.+_keys$/)
|
47
|
+
array
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def rotate_vault_item_keys(vault, item)
|
52
|
+
puts "Rotating keys for: #{vault} #{item}"
|
53
|
+
ChefVault::Item.load(vault, item).rotate_keys!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Description: Chef-Vault VaultRotateKeys class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife/vault_base'
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class VaultRotateKeys < Knife
|
21
|
+
|
22
|
+
include Chef::Knife::VaultBase
|
23
|
+
|
24
|
+
banner "knife vault rotate keys VAULT ITEM (options)"
|
25
|
+
|
26
|
+
def run
|
27
|
+
vault = @name_args[0]
|
28
|
+
item = @name_args[1]
|
29
|
+
|
30
|
+
if vault && item
|
31
|
+
set_mode(config[:vault_mode])
|
32
|
+
|
33
|
+
begin
|
34
|
+
item = ChefVault::Item.load(vault, item)
|
35
|
+
item.rotate_keys!
|
36
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
37
|
+
ChefVault::Exceptions::ItemNotFound
|
38
|
+
|
39
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
40
|
+
"#{vault}/#{item} does not exist, "\
|
41
|
+
"use 'knife vault create' to create."
|
42
|
+
end
|
43
|
+
else
|
44
|
+
show_usage
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# Description: Chef-Vault VaultShow class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife/vault_base'
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class VaultShow < Knife
|
21
|
+
|
22
|
+
include Chef::Knife::VaultBase
|
23
|
+
|
24
|
+
banner "knife vault show VAULT ITEM [VALUES] (options)"
|
25
|
+
|
26
|
+
option :mode,
|
27
|
+
:short => '-M MODE',
|
28
|
+
:long => '--mode MODE',
|
29
|
+
:description => 'Chef mode to run in default - solo'
|
30
|
+
|
31
|
+
option :print,
|
32
|
+
:short => '-p TYPE',
|
33
|
+
:long => '--print TYPE',
|
34
|
+
:description => 'Print extra vault data, can be search, admins, clients or all'
|
35
|
+
|
36
|
+
def run
|
37
|
+
vault = @name_args[0]
|
38
|
+
item = @name_args[1]
|
39
|
+
values = @name_args[2]
|
40
|
+
|
41
|
+
if vault && item
|
42
|
+
set_mode(config[:vault_mode])
|
43
|
+
print_values(vault, item, values)
|
44
|
+
else
|
45
|
+
show_usage
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def print_values(vault, item, values)
|
50
|
+
vault_item = ChefVault::Item.load(vault, item)
|
51
|
+
|
52
|
+
extra_data = {}
|
53
|
+
|
54
|
+
if config[:print]
|
55
|
+
case config[:print]
|
56
|
+
when 'search'
|
57
|
+
extra_data["search_query"] = vault_item.search
|
58
|
+
when 'admins'
|
59
|
+
extra_data["admins"] = vault_item.admins
|
60
|
+
when 'clients'
|
61
|
+
extra_data["clients"] = vault_item.clients
|
62
|
+
when 'all'
|
63
|
+
extra_data["search_query"] = vault_item.search
|
64
|
+
extra_data["admins"] = vault_item.admins
|
65
|
+
extra_data["clients"] = vault_item.clients
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if values
|
70
|
+
included_values = %W( id )
|
71
|
+
|
72
|
+
values.split(",").each do |value|
|
73
|
+
value.strip! # remove white space
|
74
|
+
included_values << value
|
75
|
+
end
|
76
|
+
|
77
|
+
filtered_data = Hash[vault_item.raw_data.find_all{|k,v| included_values.include?(k)}]
|
78
|
+
|
79
|
+
output_data = filtered_data.merge(extra_data)
|
80
|
+
else
|
81
|
+
all_data = vault_item.raw_data
|
82
|
+
|
83
|
+
output_data = all_data.merge(extra_data)
|
84
|
+
end
|
85
|
+
output(output_data)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Description: Chef-Vault VaultUpdate class
|
2
|
+
# Copyright 2013, Nordstrom, Inc.
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'chef/knife/vault_base'
|
17
|
+
|
18
|
+
class Chef
|
19
|
+
class Knife
|
20
|
+
class VaultUpdate < Knife
|
21
|
+
|
22
|
+
include Chef::Knife::VaultBase
|
23
|
+
|
24
|
+
banner "knife vault update VAULT ITEM VALUES (options)"
|
25
|
+
|
26
|
+
option :search,
|
27
|
+
:short => '-S SEARCH',
|
28
|
+
:long => '--search SEARCH',
|
29
|
+
:description => 'Chef SOLR search for clients'
|
30
|
+
|
31
|
+
option :admins,
|
32
|
+
:short => '-A ADMINS',
|
33
|
+
:long => '--admins ADMINS',
|
34
|
+
:description => 'Chef users to be added as admins'
|
35
|
+
|
36
|
+
option :json,
|
37
|
+
:short => '-J FILE',
|
38
|
+
:long => '--json FILE',
|
39
|
+
:description => 'File containing JSON data to encrypt'
|
40
|
+
|
41
|
+
option :file,
|
42
|
+
:long => '--file FILE',
|
43
|
+
:description => 'File to be added to vault item as file-content'
|
44
|
+
|
45
|
+
def run
|
46
|
+
vault = @name_args[0]
|
47
|
+
item = @name_args[1]
|
48
|
+
values = @name_args[2]
|
49
|
+
search = config[:search]
|
50
|
+
admins = config[:admins]
|
51
|
+
json_file = config[:json]
|
52
|
+
file = config[:file]
|
53
|
+
|
54
|
+
set_mode(config[:vault_mode])
|
55
|
+
|
56
|
+
if vault && item && ((values || json_file || file) || (search || admins))
|
57
|
+
begin
|
58
|
+
vault_item = ChefVault::Item.load(vault, item)
|
59
|
+
|
60
|
+
merge_values(values, json_file).each do |key, value|
|
61
|
+
vault_item[key] = value
|
62
|
+
end
|
63
|
+
|
64
|
+
if file
|
65
|
+
vault_item["file-name"] = File.basename(file)
|
66
|
+
vault_item["file-content"] = File.open(file){ |file| file.read() }
|
67
|
+
end
|
68
|
+
|
69
|
+
vault_item.search(search) if search
|
70
|
+
vault_item.clients(search) if search
|
71
|
+
vault_item.admins(admins) if admins
|
72
|
+
|
73
|
+
vault_item.save
|
74
|
+
rescue ChefVault::Exceptions::KeysNotFound,
|
75
|
+
ChefVault::Exceptions::ItemNotFound
|
76
|
+
|
77
|
+
raise ChefVault::Exceptions::ItemNotFound,
|
78
|
+
"#{vault}/#{item} does not exist, "\
|
79
|
+
"use 'knife vault create' to create."
|
80
|
+
end
|
81
|
+
else
|
82
|
+
show_usage
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/spec/chef-vault_spec.rb
CHANGED
@@ -1,56 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ChefVault do
|
4
|
+
subject(:vault) { ChefVault.new('foo') }
|
5
|
+
|
4
6
|
describe '#new' do
|
5
7
|
context 'with only a vault parameter specified' do
|
6
|
-
|
7
|
-
@vault = ChefVault.new('foo')
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'is an instance of ChefVault' do
|
11
|
-
expect(@vault).to be_an_instance_of ChefVault
|
12
|
-
end
|
8
|
+
it { should be_an_instance_of ChefVault }
|
13
9
|
|
14
|
-
|
15
|
-
expect(@vault.vault).to eq "foo"
|
16
|
-
end
|
10
|
+
its(:vault) { should eq "foo" }
|
17
11
|
end
|
18
12
|
|
19
13
|
context 'with a vault and config file parameter specified' do
|
20
|
-
before
|
14
|
+
before do
|
21
15
|
IO.stub(:read).with('knife.rb').and_return("node_name 'bar'")
|
22
|
-
@vault = ChefVault.new('foo', 'knife.rb')
|
23
16
|
end
|
24
17
|
|
25
|
-
|
26
|
-
expect(@vault).to be_an_instance_of ChefVault
|
27
|
-
end
|
18
|
+
let(:vault) { ChefVault.new('foo', 'knife.rb') }
|
28
19
|
|
29
|
-
it
|
30
|
-
expect(@vault.vault).to eq "foo"
|
31
|
-
end
|
20
|
+
it { should be_an_instance_of ChefVault }
|
32
21
|
|
33
|
-
|
34
|
-
expect(Chef::Config[:node_name]).to eq "bar"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#version' do
|
40
|
-
it 'returns the version number' do
|
41
|
-
vault = ChefVault.new('foo')
|
42
|
-
expect(vault.version).to eq ChefVault::VERSION
|
43
|
-
end
|
44
|
-
end
|
22
|
+
its(:vault) { should eq "foo" }
|
45
23
|
|
46
|
-
|
47
|
-
before(:each) do
|
48
|
-
IO.stub(:read).with('knife.rb').and_return("node_name 'bar'")
|
49
|
-
ChefVault.load_config("knife.rb")
|
24
|
+
specify { expect { Chef::Config[:node_name ].should eq "bar" } }
|
50
25
|
end
|
51
26
|
|
52
|
-
|
53
|
-
|
27
|
+
describe '#version' do
|
28
|
+
its(:version) { should eq ChefVault::VERSION }
|
54
29
|
end
|
55
30
|
end
|
56
31
|
end
|
data/spec/item_keys_spec.rb
CHANGED
@@ -2,28 +2,16 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ChefVault::ItemKeys do
|
4
4
|
describe '#new' do
|
5
|
-
|
6
|
-
@keys = ChefVault::ItemKeys.new("foo", "bar")
|
7
|
-
end
|
5
|
+
subject(:keys) { ChefVault::ItemKeys.new("foo", "bar") }
|
8
6
|
|
9
|
-
it
|
10
|
-
expect(@keys).to be_an_instance_of ChefVault::ItemKeys
|
11
|
-
end
|
7
|
+
it { should be_an_instance_of ChefVault::ItemKeys }
|
12
8
|
|
13
|
-
|
14
|
-
expect(@keys.data_bag).to eq "foo"
|
15
|
-
end
|
9
|
+
its(:data_bag) { should eq "foo" }
|
16
10
|
|
17
|
-
|
18
|
-
expect(@keys["id"]).to eq "bar"
|
19
|
-
end
|
11
|
+
specify { keys["id"].should eq "bar" }
|
20
12
|
|
21
|
-
|
22
|
-
expect(@keys["admins"]).to eq []
|
23
|
-
end
|
13
|
+
specify { keys["admins"].should eq [] }
|
24
14
|
|
25
|
-
|
26
|
-
expect(@keys["clients"]).to eq []
|
27
|
-
end
|
15
|
+
specify { keys["clients"].should eq [] }
|
28
16
|
end
|
29
17
|
end
|