chef-vault 1.0.1 → 1.1.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.
@@ -81,6 +81,27 @@ you can create a new instance of ChefVault.
81
81
  cert = vault.certificate("domain.com")
82
82
  contents = cert.decrypt_contents
83
83
 
84
+ = USAGE STAND ALONE
85
+
86
+ chef-vault can be used a stand alone binary to decrypt values stored in chef.
87
+ It requires that chef is installed on the system and that you have a valid
88
+ knife.rb. This is useful if you want to mix chef-vault into non-chef recipe
89
+ code, for example some other script where you want to protect a password.
90
+
91
+ It does still require that the data bag has been encrypted for the user's or
92
+ client's pem and pushed to the chef server. It mixes chef into the gem and
93
+ uses it to go grab the data bag.
94
+
95
+ Do chef-vault --help for all available options
96
+
97
+ == Example usage (password)
98
+
99
+ chef-vault -u Administrator -k /etc/chef/knife.rb
100
+
101
+ == Example usage (certificate)
102
+
103
+ chef-vault -c wildcard_domain_com -k /etc/chef/knife.rb
104
+
84
105
  = LICENSE:
85
106
 
86
107
  Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ./chef-vault - Run chef-vault and decrypt based on parameters
4
+ #
5
+ # Author:: Kevin Moser (<kevin.moser@nordstrom.com>)
6
+ # Copyright:: Copyright (c) 2013 Nordstrom, Inc.
7
+ # License:: Apache License, Version 2.0
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ require 'optparse'
22
+
23
+ options_config = {
24
+ chef: {
25
+ short: "k",
26
+ long: "chef-config-file",
27
+ description: "Chef config file",
28
+ default: "/etc/chef/knife.rb",
29
+ optional: false
30
+ },
31
+ user: {
32
+ short: "u",
33
+ long: "username",
34
+ description: "Username to decrypt password for",
35
+ default: nil,
36
+ optional: true
37
+ },
38
+ cert: {
39
+ short: "c",
40
+ long: "certificate",
41
+ description: "Certificate to decrypt contents of",
42
+ default: nil,
43
+ optional: true
44
+ }
45
+ }
46
+
47
+ banner = "Usage: chef-vault "
48
+ options_config.each do |option, config|
49
+ if config[:optional]
50
+ banner << "[--#{config[:long]} #{config[:long].upcase}] "
51
+ else
52
+ banner << "--#{config[:long]} #{config[:long].upcase} "
53
+ end
54
+ end
55
+
56
+ options = {}
57
+ OptionParser.new do |opts|
58
+ opts.banner = banner
59
+
60
+ options_config.each do |option, config|
61
+ description = "#{config[:description]}"
62
+ description << " (#{config[:default]})" if config[:default]
63
+ description << " MANDATORY" unless config[:default]
64
+ opts.on("-#{config[:short]}", "--#{config[:long]} #{config[:long].upcase}", description) do |opt|
65
+ options[option] = opt
66
+ end
67
+ end
68
+ end.parse!
69
+
70
+ options_config.each do |option, config|
71
+ raise OptionParser::MissingArgument if (options[option].nil? && !config[:optional])
72
+ end
73
+
74
+ options_config.each do |option, config|
75
+ options[option] = options[option] ? options[option] : config[:default]
76
+ end
77
+
78
+ require 'rubygems'
79
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
80
+ require 'chef-vault'
81
+
82
+ if options[:user]
83
+ vault = ChefVault.new("passwords", options[:chef])
84
+
85
+ user = vault.user(options[:user])
86
+ puts user.decrypt_password
87
+ else
88
+ vault = ChefVault.new("certs", options[:chef])
89
+ cert = vault.certificate(options[:cert])
90
+ puts cert.decrypt_contents
91
+ end
@@ -13,5 +13,8 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.add_dependency "chef", ">= 0.10.10"
16
- s.require_paths = ["lib"]
16
+ s.require_paths = ["lib"]
17
+
18
+ s.bindir = "bin"
19
+ s.executables = %w( chef-vault )
17
20
  end
@@ -20,13 +20,16 @@ require 'chef'
20
20
  require 'chef-vault/user'
21
21
  require 'chef-vault/certificate'
22
22
  require 'chef-vault/version'
23
+ require 'chef-vault/chef/offline'
23
24
 
24
25
  class ChefVault
25
26
 
26
27
  attr_accessor :data_bag
28
+ attr_accessor :chef_config_file
27
29
 
28
- def initialize(data_bag)
30
+ def initialize(data_bag, chef_config_file=nil)
29
31
  @data_bag = data_bag
32
+ @chef_config_file = chef_config_file
30
33
  end
31
34
 
32
35
  def version
@@ -34,10 +37,10 @@ class ChefVault
34
37
  end
35
38
 
36
39
  def user(username)
37
- ChefVault::User.new(@data_bag, username)
40
+ ChefVault::User.new(@data_bag, username, @chef_config_file)
38
41
  end
39
42
 
40
43
  def certificate(name)
41
- ChefVault::Certificate.new(@data_bag, name)
44
+ ChefVault::Certificate.new(@data_bag, name, @chef_config_file)
42
45
  end
43
46
  end
@@ -2,16 +2,26 @@ class ChefVault
2
2
  class Certificate
3
3
  attr_accessor :name
4
4
 
5
- def initialize(data_bag, name)
5
+ def initialize(data_bag, name, chef_config_file)
6
6
  @name = name
7
7
  @data_bag = data_bag
8
+
9
+ if chef_config_file
10
+ chef = ChefVault::ChefOffline.new(chef_config_file)
11
+ chef.connect
12
+ end
8
13
  end
9
14
 
10
15
  def decrypt_contents
11
16
  # use the private client_key file to create a decryptor
12
17
  private_key = open(Chef::Config[:client_key]).read
13
18
  private_key = OpenSSL::PKey::RSA.new(private_key)
14
- keys = Chef::DataBagItem.load(@data_bag, "#{name}_keys")
19
+
20
+ begin
21
+ keys = Chef::DataBagItem.load(@data_bag, "#{name}_keys")
22
+ rescue
23
+ throw "Could not find data bag item #{name}_keys in data bag #{@data_bag}"
24
+ end
15
25
 
16
26
  unless keys[Chef::Config[:node_name]]
17
27
  throw "#{name} is not encrypted for you! Rebuild the certificate data bag"
@@ -0,0 +1,14 @@
1
+ class ChefVault
2
+ class ChefOffline
3
+ attr_accessor :config_file
4
+
5
+ def initialize(config_file)
6
+ @config_file = config_file
7
+ end
8
+
9
+ def connect
10
+ require 'chef'
11
+ ::Chef::Config.from_file(@config_file)
12
+ end
13
+ end
14
+ end
@@ -2,16 +2,26 @@ class ChefVault
2
2
  class User
3
3
  attr_accessor :username
4
4
 
5
- def initialize(data_bag, username)
5
+ def initialize(data_bag, username, chef_config_file)
6
6
  @username = username
7
7
  @data_bag = data_bag
8
+
9
+ if chef_config_file
10
+ chef = ChefVault::ChefOffline.new(chef_config_file)
11
+ chef.connect
12
+ end
8
13
  end
9
14
 
10
15
  def decrypt_password
11
16
  # use the private client_key file to create a decryptor
12
17
  private_key = open(Chef::Config[:client_key]).read
13
18
  private_key = OpenSSL::PKey::RSA.new(private_key)
14
- keys = Chef::DataBagItem.load(@data_bag, "#{username}_keys")
19
+
20
+ begin
21
+ keys = Chef::DataBagItem.load(@data_bag, "#{username}_keys")
22
+ rescue
23
+ throw "Could not find data bag item #{username}_keys in data bag #{@data_bag}"
24
+ end
15
25
 
16
26
  unless keys[Chef::Config[:node_name]]
17
27
  throw "Password for #{username} is not encrypted for you! Rebuild the password data bag"
@@ -1,4 +1,4 @@
1
1
  class ChefVault
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  MAJOR, MINOR, TINY = VERSION.split('.')
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-vault
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -30,15 +30,18 @@ dependencies:
30
30
  description: Data encryption support for chef using data bags
31
31
  email:
32
32
  - kevin.moser@nordstrom.com
33
- executables: []
33
+ executables:
34
+ - chef-vault
34
35
  extensions: []
35
36
  extra_rdoc_files: []
36
37
  files:
37
38
  - .gitignore
38
39
  - README.rdoc
40
+ - bin/chef-vault
39
41
  - chef-vault.gemspec
40
42
  - lib/chef-vault.rb
41
43
  - lib/chef-vault/certificate.rb
44
+ - lib/chef-vault/chef/offline.rb
42
45
  - lib/chef-vault/user.rb
43
46
  - lib/chef-vault/version.rb
44
47
  - lib/chef/knife/DecryptCert.rb