ridley 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -151,7 +151,7 @@ CONFIG
151
151
 
152
152
  IO.read(encrypted_data_bag_secret_path).chomp
153
153
  rescue Errno::ENOENT => encrypted_data_bag_secret
154
- raise Errors::EncryptedDataBagSecretNotFound, "Error bootstrapping: Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}"
154
+ raise Errors::EncryptedDataBagSecretNotFound, "Error bootstrapping: Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}'"
155
155
  end
156
156
 
157
157
  private
@@ -156,6 +156,19 @@ module Ridley
156
156
  self.url_prefix.to_s
157
157
  end
158
158
 
159
+ # The encrypted data bag secret for this connection.
160
+ #
161
+ # @raise [Ridley::Errors::EncryptedDataBagSecretNotFound]
162
+ #
163
+ # @return [String, nil]
164
+ def encrypted_data_bag_secret
165
+ return nil if encrypted_data_bag_secret_path.nil?
166
+
167
+ IO.read(encrypted_data_bag_secret_path).chomp
168
+ rescue Errno::ENOENT => e
169
+ raise Errors::EncryptedDataBagSecretNotFound, "Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}'"
170
+ end
171
+
159
172
  private
160
173
 
161
174
  attr_reader :conn
@@ -4,19 +4,23 @@ module Ridley
4
4
  class DBIChainLink
5
5
  attr_reader :data_bag
6
6
  attr_reader :connection
7
+ attr_reader :klass
7
8
 
8
9
  # @param [Ridley::DataBag] data_bag
9
- def initialize(data_bag, connection)
10
+ def initialize(data_bag, connection, options = {})
11
+ options[:encrypted] ||= false
12
+
10
13
  @data_bag = data_bag
11
14
  @connection = connection
15
+ @klass = options[:encrypted] ? Ridley::EncryptedDataBagItem : Ridley::DataBagItem
12
16
  end
13
17
 
14
18
  def new(*args)
15
- Ridley::DataBagItem.send(:new, connection, data_bag, *args)
19
+ klass.send(:new, connection, data_bag, *args)
16
20
  end
17
21
 
18
22
  def method_missing(fun, *args, &block)
19
- Ridley::DataBagItem.send(fun, connection, data_bag, *args, &block)
23
+ klass.send(fun, connection, data_bag, *args, &block)
20
24
  end
21
25
  end
22
26
 
@@ -56,7 +60,11 @@ module Ridley
56
60
  validates_presence_of :name
57
61
 
58
62
  def item
59
- @dbi_link ||= DBIChainLink.new(self, connection)
63
+ DBIChainLink.new(self, connection)
64
+ end
65
+
66
+ def encrypted_item
67
+ DBIChainLink.new(self, connection, encrypted: true)
60
68
  end
61
69
  end
62
70
 
@@ -164,6 +164,25 @@ module Ridley
164
164
  true
165
165
  end
166
166
 
167
+ # Decrypts this data bag item.
168
+ #
169
+ # @return [Hash] decrypted attributes
170
+ def decrypt
171
+ decrypted_hash = Hash[attributes.map { |key, value| [key, decrypt_value(value)] }]
172
+ self.attributes = HashWithIndifferentAccess.new(decrypted_hash)
173
+ end
174
+
175
+ def decrypt_value(value)
176
+ decoded_value = Base64.decode64(value)
177
+
178
+ cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
179
+ cipher.decrypt
180
+ cipher.pkcs5_keyivgen(connection.encrypted_data_bag_secret)
181
+ decrypted_value = cipher.update(decoded_value) + cipher.final
182
+
183
+ YAML.load(decrypted_value)
184
+ end
185
+
167
186
  # @param [#to_hash] hash
168
187
  #
169
188
  # @return [Object]
@@ -0,0 +1,54 @@
1
+ module Ridley
2
+ class EncryptedDataBagItem
3
+ class << self
4
+ # Finds a data bag item and decrypts it.
5
+ #
6
+ # @param [Ridley::Connection] connection
7
+ # @param [Ridley::DataBag] data_bag
8
+ # @param [String, #chef_id] object
9
+ #
10
+ # @return [nil, Ridley::DataBagItem]
11
+ def find(connection, data_bag, object)
12
+ find!(connection, data_bag, object)
13
+ rescue Errors::HTTPNotFound
14
+ nil
15
+ end
16
+
17
+ # Finds a data bag item and decrypts it. Throws an exception if the item doesn't exist.
18
+ #
19
+ # @param [Ridley::Connection] connection
20
+ # @param [Ridley::DataBag] data_bag
21
+ # @param [String, #chef_id] object
22
+ #
23
+ # @raise [Errors::HTTPNotFound]
24
+ # if a resource with the given chef_id is not found
25
+ #
26
+ # @return [nil, Ridley::DataBagItem]
27
+ def find!(connection, data_bag, object)
28
+ data_bag_item = DataBagItem.find!(connection, data_bag, object)
29
+ data_bag_item.decrypt
30
+ new(connection, data_bag, data_bag_item.attributes)
31
+ end
32
+ end
33
+
34
+ attr_reader :data_bag
35
+ attr_reader :attributes
36
+
37
+ # @param [Ridley::Connection] connection
38
+ # @param [Ridley::DataBag] data_bag
39
+ # @param [#to_hash] attributes
40
+ def initialize(connection, data_bag, attributes = {})
41
+ @connection = connection
42
+ @data_bag = data_bag
43
+ @attributes = attributes
44
+ end
45
+
46
+ def to_s
47
+ self.attributes
48
+ end
49
+
50
+ private
51
+
52
+ attr_reader :connection
53
+ end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -0,0 +1 @@
1
+ NTE5C5gzbe3F7fGBlrT/YTuMQuHlxaOWhY81KsgYXJ0mzDsDMFvCpfi4CUXu5M7n/Umgsf8jdHw/IIkJLZcXgk+Ll75kDU/VI5FyRzib0U0SX4JB8JLM7wRFgRpuk3GD27LnYR1APmLncE7R6ZSJc6iaFHcEL2MdR+hv0nhUZPUqITxYHyrYvqNSfroyxldQ/cvnrIMBS8JrpjIsLdYhcgL6mPJiakl4fM36cFk6Wl2Mxw7vOvGXRSR5l+t42pGDhtOjE3os5reLVoWkYoiQ1fpx3NrOdxsVuz17+3jMLBlmni2SGf2wncui2r9PqCrVbUbaCi6aNV1+SRbeh5kxBxjWSzw59BNXtna4vSK6hFPsT6tfXlOi67Q2vwjjAqltAVStGas/VZyU7DRzxMkbnPPtue+7Pajqe/TfSNWA5SX2cHtkG2X3EqZ8ftOa9p+b/VJlUnnnV2ilVfgjCW2q6XXMbC0C5yIbrDZm+aCJyhueA0j+ZHWM4k07OAuB7FRcuJJBs8H2StEx2o22OdAYUBcN5PRGlOAEBemL+sZAztbex2NjjOYV90806UFvSJLPixVWJgDTSA5OvXtNvUQYDYSGRQ/BmH86aA5gJ60AM9vEVB0BfPi946m9D4LZ/2uK6fqq3zVIV1s0EgfYHYUVz0oaf3srofc5YUAP3Ge/VLE=
@@ -5,13 +5,15 @@ describe Ridley::Connection do
5
5
  let(:client_name) { "reset" }
6
6
  let(:client_key) { fixtures_path.join("reset.pem").to_s }
7
7
  let(:organization) { "vialstudios" }
8
+ let(:encrypted_data_bag_secret_path) { fixtures_path.join("reset.pem").to_s }
8
9
 
9
10
  let(:config) do
10
11
  {
11
12
  server_url: server_url,
12
13
  client_name: client_name,
13
14
  client_key: client_key,
14
- organization: organization
15
+ organization: organization,
16
+ encrypted_data_bag_secret_path: encrypted_data_bag_secret_path
15
17
  }
16
18
  end
17
19
 
@@ -195,4 +197,32 @@ describe Ridley::Connection do
195
197
  end
196
198
  end
197
199
  end
200
+
201
+ describe "#encrypted_data_bag_secret" do
202
+ it "returns a string" do
203
+ subject.encrypted_data_bag_secret.should be_a(String)
204
+ end
205
+
206
+ context "when a encrypted_data_bag_secret_path is not provided" do
207
+ before(:each) do
208
+ subject.stub(:encrypted_data_bag_secret_path) { nil }
209
+ end
210
+
211
+ it "returns nil" do
212
+ subject.encrypted_data_bag_secret.should be_nil
213
+ end
214
+ end
215
+
216
+ context "when the file is not found at the given encrypted_data_bag_secret_path" do
217
+ before(:each) do
218
+ subject.stub(:encrypted_data_bag_secret_path) { fixtures_path.join("not.txt").to_s }
219
+ end
220
+
221
+ it "raises an EncryptedDataBagSecretNotFound erorr" do
222
+ lambda {
223
+ subject.encrypted_data_bag_secret
224
+ }.should raise_error(Ridley::Errors::EncryptedDataBagSecretNotFound)
225
+ end
226
+ end
227
+ end
198
228
  end
@@ -39,4 +39,15 @@ describe Ridley::DataBagItem do
39
39
  end
40
40
  end
41
41
  end
42
+
43
+ describe "#decrypt" do
44
+ it "decrypts an encrypted item" do
45
+ encrypted_data_bag_secret = File.read(fixtures_path.join("encrypted_data_bag_secret").to_s)
46
+ connection.stub(:encrypted_data_bag_secret).and_return(encrypted_data_bag_secret)
47
+
48
+ subject.attributes[:test] = "Xk0E8lV9r4BhZzcg4wal0X4w9ZexN3azxMjZ9r1MCZc="
49
+ subject.decrypt
50
+ subject.attributes[:test][:database][:username].should == "test"
51
+ end
52
+ end
42
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ridley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-07 00:00:00.000000000 Z
12
+ date: 2012-11-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -237,6 +237,7 @@ files:
237
237
  - lib/ridley/resources/cookbook.rb
238
238
  - lib/ridley/resources/data_bag.rb
239
239
  - lib/ridley/resources/data_bag_item.rb
240
+ - lib/ridley/resources/encrypted_data_bag_item.rb
240
241
  - lib/ridley/resources/environment.rb
241
242
  - lib/ridley/resources/node.rb
242
243
  - lib/ridley/resources/role.rb
@@ -258,6 +259,7 @@ files:
258
259
  - spec/acceptance/role_resource_spec.rb
259
260
  - spec/acceptance/sandbox_resource_spec.rb
260
261
  - spec/acceptance/search_resource_spec.rb
262
+ - spec/fixtures/encrypted_data_bag_secret
261
263
  - spec/fixtures/recipe_one.rb
262
264
  - spec/fixtures/recipe_two.rb
263
265
  - spec/fixtures/reset.pem
@@ -303,7 +305,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
303
305
  version: '0'
304
306
  segments:
305
307
  - 0
306
- hash: -2376654314041873047
308
+ hash: -1699037666768544565
307
309
  requirements: []
308
310
  rubyforge_project:
309
311
  rubygems_version: 1.8.23
@@ -321,6 +323,7 @@ test_files:
321
323
  - spec/acceptance/role_resource_spec.rb
322
324
  - spec/acceptance/sandbox_resource_spec.rb
323
325
  - spec/acceptance/search_resource_spec.rb
326
+ - spec/fixtures/encrypted_data_bag_secret
324
327
  - spec/fixtures/recipe_one.rb
325
328
  - spec/fixtures/recipe_two.rb
326
329
  - spec/fixtures/reset.pem