chef-vault 1.2.5 → 2.0.1.pre
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 +15 -0
- data/Changelog.md +17 -0
- data/KNIFE_EXAMPLES.md +169 -0
- data/README.md +83 -106
- data/bin/chef-vault +25 -19
- data/lib/chef-vault.rb +17 -9
- data/lib/chef-vault/certificate.rb +7 -28
- data/lib/chef-vault/chef_patch/api_client.rb +40 -0
- data/lib/chef-vault/chef_patch/user.rb +33 -0
- data/lib/chef-vault/exceptions.rb +27 -0
- data/lib/chef-vault/item.rb +243 -0
- data/lib/chef-vault/item_keys.rb +121 -0
- data/lib/chef-vault/user.rb +7 -28
- data/lib/chef-vault/version.rb +1 -1
- data/lib/chef/knife/Decrypt.rb +64 -0
- data/lib/chef/knife/encrypt_create.rb +91 -0
- data/lib/chef/knife/encrypt_delete.rb +62 -0
- data/lib/chef/knife/encrypt_remove.rb +100 -0
- data/lib/chef/knife/encrypt_rotate_keys.rb +62 -0
- data/lib/chef/knife/encrypt_update.rb +90 -0
- data/lib/{chef-vault/chef/offline.rb → chef/knife/mixin/compat.rb} +15 -11
- data/lib/chef/knife/mixin/helper.rb +50 -0
- data/spec/chef-vault_spec.rb +19 -30
- data/spec/item_keys_spec.rb +29 -0
- data/spec/item_spec.rb +33 -0
- metadata +23 -21
- data/lib/chef/knife/DecryptCert.rb +0 -59
- data/lib/chef/knife/DecryptPassword.rb +0 -58
- data/lib/chef/knife/EncryptCert.rb +0 -185
- data/lib/chef/knife/EncryptPassword.rb +0 -182
- data/lib/chef/knife/compat.rb +0 -71
@@ -1,4 +1,4 @@
|
|
1
|
-
# Description: ChefVault::
|
1
|
+
# Description: ChefVault::Mixin::KnifeCompat module
|
2
2
|
# Copyright 2013, Nordstrom, Inc.
|
3
3
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -13,17 +13,21 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
|
16
|
-
|
17
|
-
class ChefOffline
|
18
|
-
attr_accessor :config_file
|
19
|
-
|
20
|
-
def initialize(config_file)
|
21
|
-
@config_file = config_file
|
22
|
-
end
|
16
|
+
# Make a wraper to chef10/11 "shef/shell" changes
|
23
17
|
|
24
|
-
|
25
|
-
|
26
|
-
|
18
|
+
class ChefVault
|
19
|
+
module Mixin
|
20
|
+
module KnifeCompat
|
21
|
+
require 'chef/version'
|
22
|
+
def extend_context_object(obj)
|
23
|
+
if Chef::VERSION.to_i >= 11
|
24
|
+
require "chef/shell/ext"
|
25
|
+
Shell::Extensions.extend_context_object(obj)
|
26
|
+
else
|
27
|
+
require 'chef/shef/ext'
|
28
|
+
Shef::Extensions.extend_context_object(obj)
|
29
|
+
end
|
30
|
+
end
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Description: ChefVault::Mixin::Mode module
|
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
|
+
class ChefVault
|
17
|
+
module Mixin
|
18
|
+
module Helper
|
19
|
+
def set_mode(mode)
|
20
|
+
if mode == "client"
|
21
|
+
Chef::Config[:solo] = false
|
22
|
+
else
|
23
|
+
Chef::Config[:solo] = true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def merge_values(json, file)
|
28
|
+
values = {}
|
29
|
+
values.merge!(values_from_file(file)) if file
|
30
|
+
values.merge!(values_from_json(json)) if json
|
31
|
+
|
32
|
+
values
|
33
|
+
end
|
34
|
+
|
35
|
+
def values_from_file(file)
|
36
|
+
json = File.open(file){ |file| file.read() }
|
37
|
+
|
38
|
+
values_from_json(json)
|
39
|
+
end
|
40
|
+
|
41
|
+
def values_from_json(json)
|
42
|
+
begin
|
43
|
+
JSON.parse(json)
|
44
|
+
rescue JSON::ParserError
|
45
|
+
raise JSON::ParserError, "#{json} is not valid JSON!"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/chef-vault_spec.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ChefVault do
|
4
|
-
|
5
4
|
describe '#new' do
|
6
|
-
context 'with only a
|
5
|
+
context 'with only a vault parameter specified' do
|
7
6
|
before(:each) do
|
8
7
|
@vault = ChefVault.new('foo')
|
9
8
|
end
|
@@ -12,26 +11,27 @@ describe ChefVault do
|
|
12
11
|
expect(@vault).to be_an_instance_of ChefVault
|
13
12
|
end
|
14
13
|
|
15
|
-
it '
|
16
|
-
expect(@vault.
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'defaults to nil for the chef_config_file' do
|
20
|
-
expect(@vault.chef_config_file).to be_nil
|
14
|
+
it 'sets vault to foo' do
|
15
|
+
expect(@vault.vault).to eq "foo"
|
21
16
|
end
|
22
17
|
end
|
23
18
|
|
24
|
-
context 'with
|
19
|
+
context 'with a vault and config file parameter specified' do
|
25
20
|
before(:each) do
|
26
|
-
|
21
|
+
IO.stub(:read).with('knife.rb').and_return("node_name 'bar'")
|
22
|
+
@vault = ChefVault.new('foo', 'knife.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'is an instance of ChefVault' do
|
26
|
+
expect(@vault).to be_an_instance_of ChefVault
|
27
27
|
end
|
28
28
|
|
29
|
-
it '
|
30
|
-
expect(@vault.
|
29
|
+
it 'sets vault to foo' do
|
30
|
+
expect(@vault.vault).to eq "foo"
|
31
31
|
end
|
32
32
|
|
33
|
-
it '
|
34
|
-
expect(
|
33
|
+
it 'sets Chef::Config[:node_name] to bar' do
|
34
|
+
expect(Chef::Config[:node_name]).to eq "bar"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -43,25 +43,14 @@ describe ChefVault do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
describe '#
|
47
|
-
before(:each) do
|
48
|
-
@vault = ChefVault.new('foo')
|
49
|
-
@user = @vault.user('mysql')
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'is an instance of ChefVault::User' do
|
53
|
-
expect(@user).to be_an_instance_of ChefVault::User
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe '#certificate' do
|
46
|
+
describe '#self.load_config' do
|
58
47
|
before(:each) do
|
59
|
-
|
60
|
-
|
48
|
+
IO.stub(:read).with('knife.rb').and_return("node_name 'bar'")
|
49
|
+
ChefVault.load_config("knife.rb")
|
61
50
|
end
|
62
51
|
|
63
|
-
it
|
64
|
-
expect(
|
52
|
+
it "sets Chef::Config[:node_name] to bar" do
|
53
|
+
expect(Chef::Config[:node_name]).to eq "bar"
|
65
54
|
end
|
66
55
|
end
|
67
56
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefVault::ItemKeys do
|
4
|
+
describe '#new' do
|
5
|
+
before(:each) do
|
6
|
+
@keys = ChefVault::ItemKeys.new("foo", "bar")
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is an instance of ChefVault::ItemKeys' do
|
10
|
+
expect(@keys).to be_an_instance_of ChefVault::ItemKeys
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets data_bag to foo' do
|
14
|
+
expect(@keys.data_bag).to eq "foo"
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets keys["id"] to bar' do
|
18
|
+
expect(@keys["id"]).to eq "bar"
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sets keys["admins"] to []' do
|
22
|
+
expect(@keys["admins"]).to eq []
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'sets keys["clients"] to []' do
|
26
|
+
expect(@keys["clients"]).to eq []
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/item_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ChefVault::Item do
|
4
|
+
describe '#new' do
|
5
|
+
before(:each) do
|
6
|
+
@item = ChefVault::Item.new("foo", "bar")
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is an instance of ChefVault::Item' do
|
10
|
+
expect(@item).to be_an_instance_of ChefVault::Item
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets data_bag to foo' do
|
14
|
+
expect(@item.data_bag).to eq "foo"
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets item["id"] to bar' do
|
18
|
+
expect(@item["id"]).to eq "bar"
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'sets item.keys to ChefVault::ItemKeys' do
|
22
|
+
expect(@item.keys).to be_an_instance_of ChefVault::ItemKeys
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'sets item.keys.data_bag to foo' do
|
26
|
+
expect(@item.keys.data_bag).to eq "foo"
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets item.keys["id"] to bar_keys' do
|
30
|
+
expect(@item.keys["id"]).to eq "bar_keys"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-vault
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.1.pre
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kevin Moser
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-08-20 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: chef
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ! '>='
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ! '>='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ! '>='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ! '>='
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ! '>='
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -73,6 +66,7 @@ files:
|
|
73
66
|
- CONTRIBUTING.md
|
74
67
|
- Changelog.md
|
75
68
|
- Gemfile
|
69
|
+
- KNIFE_EXAMPLES.md
|
76
70
|
- LICENSE
|
77
71
|
- README.md
|
78
72
|
- Rakefile
|
@@ -80,39 +74,47 @@ files:
|
|
80
74
|
- chef-vault.gemspec
|
81
75
|
- lib/chef-vault.rb
|
82
76
|
- lib/chef-vault/certificate.rb
|
83
|
-
- lib/chef-vault/
|
77
|
+
- lib/chef-vault/chef_patch/api_client.rb
|
78
|
+
- lib/chef-vault/chef_patch/user.rb
|
79
|
+
- lib/chef-vault/exceptions.rb
|
80
|
+
- lib/chef-vault/item.rb
|
81
|
+
- lib/chef-vault/item_keys.rb
|
84
82
|
- lib/chef-vault/user.rb
|
85
83
|
- lib/chef-vault/version.rb
|
86
|
-
- lib/chef/knife/
|
87
|
-
- lib/chef/knife/
|
88
|
-
- lib/chef/knife/
|
89
|
-
- lib/chef/knife/
|
90
|
-
- lib/chef/knife/
|
84
|
+
- lib/chef/knife/Decrypt.rb
|
85
|
+
- lib/chef/knife/encrypt_create.rb
|
86
|
+
- lib/chef/knife/encrypt_delete.rb
|
87
|
+
- lib/chef/knife/encrypt_remove.rb
|
88
|
+
- lib/chef/knife/encrypt_rotate_keys.rb
|
89
|
+
- lib/chef/knife/encrypt_update.rb
|
90
|
+
- lib/chef/knife/mixin/compat.rb
|
91
|
+
- lib/chef/knife/mixin/helper.rb
|
91
92
|
- spec/chef-vault_spec.rb
|
93
|
+
- spec/item_keys_spec.rb
|
94
|
+
- spec/item_spec.rb
|
92
95
|
- spec/spec_helper.rb
|
93
96
|
homepage:
|
94
97
|
licenses:
|
95
98
|
- Apache License, v2.0
|
99
|
+
metadata: {}
|
96
100
|
post_install_message:
|
97
101
|
rdoc_options: []
|
98
102
|
require_paths:
|
99
103
|
- lib
|
100
104
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
-
none: false
|
102
105
|
requirements:
|
103
106
|
- - ! '>='
|
104
107
|
- !ruby/object:Gem::Version
|
105
108
|
version: '0'
|
106
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
-
none: false
|
108
110
|
requirements:
|
109
|
-
- - ! '
|
111
|
+
- - ! '>'
|
110
112
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
113
|
+
version: 1.3.1
|
112
114
|
requirements: []
|
113
115
|
rubyforge_project:
|
114
|
-
rubygems_version:
|
116
|
+
rubygems_version: 2.0.7
|
115
117
|
signing_key:
|
116
|
-
specification_version:
|
118
|
+
specification_version: 4
|
117
119
|
summary: Data encryption support for chef using data bags
|
118
120
|
test_files: []
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# Description: Chef-Vault DecryptCert 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'
|
17
|
-
|
18
|
-
class DecryptCert < Chef::Knife
|
19
|
-
deps do
|
20
|
-
require 'chef/search/query'
|
21
|
-
require 'json'
|
22
|
-
require File.expand_path('../compat', __FILE__)
|
23
|
-
include ChefVault::Compat
|
24
|
-
end
|
25
|
-
|
26
|
-
banner "knife decrypt cert --name NAME"
|
27
|
-
|
28
|
-
option :name,
|
29
|
-
:short => '-N NAME',
|
30
|
-
:long => '--name NAME',
|
31
|
-
:description => 'Certificate data bag name'
|
32
|
-
|
33
|
-
def run
|
34
|
-
unless config[:name]
|
35
|
-
puts("You must supply a certificate to decrypt")
|
36
|
-
exit 1
|
37
|
-
end
|
38
|
-
extend_context_object(self)
|
39
|
-
|
40
|
-
data_bag = "certs"
|
41
|
-
data_bag_path = "./data_bags/#{data_bag}"
|
42
|
-
|
43
|
-
name = config[:name].gsub(".", "_")
|
44
|
-
|
45
|
-
user_private_key = OpenSSL::PKey::RSA.new(open(Chef::Config[:client_key]).read())
|
46
|
-
key = JSON.parse(IO.read("#{data_bag_path}/#{name}_keys.json"))
|
47
|
-
unless key[Chef::Config[:node_name]]
|
48
|
-
puts("Can't find a key for #{Chef::Config[:node_name]}... You can't decrypt!")
|
49
|
-
exit 1
|
50
|
-
end
|
51
|
-
|
52
|
-
data_bag_shared_key = user_private_key.private_decrypt(Base64.decode64(key[Chef::Config[:node_name]]))
|
53
|
-
|
54
|
-
certificate = JSON.parse(open("#{data_bag_path}/#{name}.json").read())
|
55
|
-
certificate = Chef::EncryptedDataBagItem.new certificate, data_bag_shared_key
|
56
|
-
|
57
|
-
puts("certificate:\n#{certificate['contents']}")
|
58
|
-
end
|
59
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# Description: Chef-Vault DecryptPassword 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'
|
17
|
-
|
18
|
-
class DecryptPassword < Chef::Knife
|
19
|
-
deps do
|
20
|
-
require 'chef/search/query'
|
21
|
-
require 'json'
|
22
|
-
require File.expand_path('../compat', __FILE__)
|
23
|
-
include ChefVault::Compat
|
24
|
-
end
|
25
|
-
|
26
|
-
banner "knife decrypt password --username USERNAME"
|
27
|
-
|
28
|
-
option :username,
|
29
|
-
:short => '-U USERNAME',
|
30
|
-
:long => '--username USERNAME',
|
31
|
-
:description => 'username of account to encrypt'
|
32
|
-
|
33
|
-
def run
|
34
|
-
unless config[:username]
|
35
|
-
puts("You must supply a username to decrypt")
|
36
|
-
exit 1
|
37
|
-
end
|
38
|
-
extend_context_object(self)
|
39
|
-
|
40
|
-
data_bag_path = "./data_bags/passwords"
|
41
|
-
|
42
|
-
username = config[:username]
|
43
|
-
|
44
|
-
user_private_key = OpenSSL::PKey::RSA.new(open(Chef::Config[:client_key]).read())
|
45
|
-
key = JSON.parse(IO.read("#{data_bag_path}/#{username}_keys.json"))
|
46
|
-
unless key[Chef::Config[:node_name]]
|
47
|
-
puts("Can't find a key for #{Chef::Config[:node_name]}... You can't decrypt!")
|
48
|
-
exit 1
|
49
|
-
end
|
50
|
-
|
51
|
-
data_bag_shared_key = user_private_key.private_decrypt(Base64.decode64(key[Chef::Config[:node_name]]))
|
52
|
-
|
53
|
-
credential = JSON.parse(open("#{data_bag_path}/#{username}.json").read())
|
54
|
-
credential = Chef::EncryptedDataBagItem.new credential, data_bag_shared_key
|
55
|
-
|
56
|
-
puts("username: #{credential['username']}, password: #{credential['password']}")
|
57
|
-
end
|
58
|
-
end
|