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