ridley 0.7.0.rc1 → 0.7.0.rc3

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.
@@ -47,7 +47,7 @@ module Ridley
47
47
  end
48
48
 
49
49
  new_attributes = client.connection.post("#{data_bag.class.resource_path}/#{data_bag.name}", resource.to_json).body
50
- resource.from_hash(resource.attributes.deep_merge(new_attributes))
50
+ resource.mass_assign(new_attributes)
51
51
  resource
52
52
  end
53
53
 
@@ -98,6 +98,9 @@ module Ridley
98
98
  type: String,
99
99
  required: true
100
100
 
101
+ alias_method :attributes=, :mass_assign
102
+ alias_method :attributes, :_attributes_
103
+
101
104
  # @param [Ridley::Client] client
102
105
  # @param [Ridley::DataBagResource] data_bag
103
106
  # @param [#to_hash] new_attrs
@@ -124,7 +127,7 @@ module Ridley
124
127
  def save
125
128
  raise Errors::InvalidResource.new(self.errors) unless valid?
126
129
 
127
- mass_assign(self.class.create(client, data_bag, self).attributes)
130
+ mass_assign(self.class.create(client, data_bag, self)._attributes_)
128
131
  true
129
132
  rescue Errors::HTTPConflict
130
133
  self.update
@@ -135,7 +138,7 @@ module Ridley
135
138
  #
136
139
  # @return [Hash] decrypted attributes
137
140
  def decrypt
138
- decrypted_hash = Hash[attributes.map { |key, value| [key, key == "id" ? value : decrypt_value(value)] }]
141
+ decrypted_hash = Hash[_attributes_.map { |key, value| [key, key == "id" ? value : decrypt_value(value)] }]
139
142
  mass_assign(decrypted_hash)
140
143
  end
141
144
 
@@ -154,7 +157,7 @@ module Ridley
154
157
  #
155
158
  # @return [Object]
156
159
  def reload
157
- mass_assign(self.class.find(client, data_bag, self).attributes)
160
+ mass_assign(self.class.find(client, data_bag, self)._attributes_)
158
161
  self
159
162
  end
160
163
 
@@ -168,7 +171,7 @@ module Ridley
168
171
  def update
169
172
  raise Errors::InvalidResource.new(self.errors) unless valid?
170
173
 
171
- mass_assign(sself.class.update(client, data_bag, self).attributes)
174
+ mass_assign(sself.class.update(client, data_bag, self)._attributes_)
172
175
  true
173
176
  end
174
177
 
@@ -176,14 +179,10 @@ module Ridley
176
179
  #
177
180
  # @return [Object]
178
181
  def from_hash(hash)
179
- hash = HashWithIndifferentAccess.new(hash.to_hash)
182
+ hash = Hashie::Mash.new(hash.to_hash)
180
183
 
181
184
  mass_assign(hash.has_key?(:raw_data) ? hash[:raw_data] : hash)
182
185
  self
183
186
  end
184
-
185
- def to_s
186
- self.attributes
187
- end
188
187
  end
189
188
  end
@@ -26,7 +26,7 @@ module Ridley
26
26
  #
27
27
  # @return [nil, Ridley::DataBagItemResource]
28
28
  def find!(client, data_bag, object)
29
- data_bag_item = DataBagItem.find!(client, data_bag, object)
29
+ data_bag_item = DataBagItemResource.find!(client, data_bag, object)
30
30
  data_bag_item.decrypt
31
31
  new(client, data_bag, data_bag_item.attributes)
32
32
  end
@@ -109,7 +109,7 @@ module Ridley
109
109
  upload_path = url.path
110
110
  url.path = ""
111
111
 
112
- Faraday.new(url) do |c|
112
+ Faraday.new(url, client.options.slice(*Connection::VALID_OPTIONS)) do |c|
113
113
  c.request :chef_auth, client.client_name, client.client_key
114
114
  c.adapter :net_http
115
115
  end.put(upload_path, contents, headers)
@@ -1,3 +1,3 @@
1
1
  module Ridley
2
- VERSION = "0.7.0.rc1"
2
+ VERSION = "0.7.0.rc3"
3
3
  end
@@ -19,12 +19,13 @@ Gem::Specification.new do |s|
19
19
 
20
20
  s.add_runtime_dependency 'json', '>= 1.5.0'
21
21
  s.add_runtime_dependency 'multi_json', '>= 1.0.4'
22
- s.add_runtime_dependency 'chozo', '>= 0.4.1'
23
- s.add_runtime_dependency 'mixlib-log'
24
- s.add_runtime_dependency 'mixlib-authentication'
22
+ s.add_runtime_dependency 'chozo', '>= 0.5.0'
23
+ s.add_runtime_dependency 'mixlib-log', '>= 1.3.0'
24
+ s.add_runtime_dependency 'mixlib-authentication', '>= 1.3.0'
25
25
  s.add_runtime_dependency 'addressable'
26
26
  s.add_runtime_dependency 'faraday', '>= 0.8.4'
27
27
  s.add_runtime_dependency 'activesupport', '>= 3.2.0'
28
+ s.add_runtime_dependency 'solve', '>= 0.4.1'
28
29
  s.add_runtime_dependency 'celluloid'
29
30
  s.add_runtime_dependency 'net-ssh'
30
31
  s.add_runtime_dependency 'erubis'
@@ -22,6 +22,10 @@ def setup_rspec
22
22
  Ridley.logger = nil
23
23
  Celluloid.logger = nil
24
24
  end
25
+
26
+ config.before(:each) do
27
+ clean_tmp_path
28
+ end
25
29
  end
26
30
  end
27
31
 
@@ -106,7 +106,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
106
106
 
107
107
  it "sends a create message to the implementing class" do
108
108
  updated = double('updated')
109
- updated.stub(:attributes).and_return(Hash.new)
109
+ updated.stub(:_attributes_).and_return(Hash.new)
110
110
  subject.class.should_receive(:create).with(client, subject).and_return(updated)
111
111
 
112
112
  subject.save
@@ -116,7 +116,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
116
116
  it "sends the update message to self" do
117
117
  updated = double('updated')
118
118
  updated.stub(:[]).and_return(Hash.new)
119
- updated.stub(:attributes).and_return(Hash.new)
119
+ updated.stub(:_attributes_).and_return(Hash.new)
120
120
  subject.class.should_receive(:create).and_raise(Ridley::Errors::HTTPConflict.new(updated))
121
121
  subject.should_receive(:update).and_return(updated)
122
122
 
@@ -141,7 +141,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
141
141
  let(:updated) do
142
142
  updated = double('updated')
143
143
  updated.stub(:[]).and_return(Hash.new)
144
- updated.stub(:attributes).and_return(Hash.new)
144
+ updated.stub(:_attributes_).and_return(Hash.new)
145
145
  updated
146
146
  end
147
147
 
@@ -173,14 +173,14 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
173
173
  it "returns the value of the chef_id attribute" do
174
174
  subject.class.attribute(:name)
175
175
  subject.class.stub(:chef_id) { :name }
176
- subject.attributes = { name: "reset" }
176
+ subject.mass_assign(name: "reset")
177
177
 
178
178
  subject.chef_id.should eql("reset")
179
179
  end
180
180
  end
181
181
 
182
182
  describe "#reload" do
183
- let(:updated_subject) { double('updated_subject', attributes: { fake_attribute: "some_value" }) }
183
+ let(:updated_subject) { double('updated_subject', _attributes_: { fake_attribute: "some_value" }) }
184
184
 
185
185
  before(:each) do
186
186
  subject.class.attribute(:fake_attribute)
@@ -194,8 +194,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
194
194
  it "sets the attributes of self to include those of the reloaded object" do
195
195
  subject.reload
196
196
 
197
- subject.attributes.should have_key(:fake_attribute)
198
- subject.attributes[:fake_attribute].should eql("some_value")
197
+ subject.get_attribute(:fake_attribute).should eql("some_value")
199
198
  end
200
199
  end
201
200
  end
@@ -4,8 +4,17 @@ module Ridley
4
4
  Pathname.new(File.expand_path('../../../', __FILE__))
5
5
  end
6
6
 
7
+ def clean_tmp_path
8
+ FileUtils.rm_rf(tmp_path)
9
+ FileUtils.mkdir_p(tmp_path)
10
+ end
11
+
7
12
  def fixtures_path
8
13
  app_root_path.join('spec/fixtures')
9
14
  end
15
+
16
+ def tmp_path
17
+ app_root_path.join('spec/tmp')
18
+ end
10
19
  end
11
20
  end
@@ -22,4 +22,27 @@ describe Ridley::Connection do
22
22
  subject.api_type.should eql(:hosted)
23
23
  end
24
24
  end
25
+
26
+ describe "#stream" do
27
+ let(:target) { "http://test.it/file" }
28
+ let(:destination) { tmp_path.join("test.file") }
29
+ let(:contents) { "SOME STRING STUFF\nHERE.\n" }
30
+
31
+ before(:each) do
32
+ stub_request(:get, "http://test.it/file").
33
+ to_return(status: 200, body: contents)
34
+ end
35
+
36
+ it "creates a destination file on disk" do
37
+ subject.stream(target, destination)
38
+
39
+ File.exist?(destination).should be_true
40
+ end
41
+
42
+ it "contains the contents of the response body" do
43
+ subject.stream(target, destination)
44
+
45
+ File.read(destination).should include(contents)
46
+ end
47
+ end
25
48
  end
@@ -3,12 +3,28 @@ require 'spec_helper'
3
3
  describe Ridley::Middleware::ChefAuth do
4
4
  let(:server_url) { "https://api.opscode.com/organizations/vialstudios/" }
5
5
 
6
+ describe "ClassMethods" do
7
+ subject { described_class }
8
+
9
+ describe "#authentication_headers" do
10
+ let(:client_name) { "reset" }
11
+ let(:client_key) { fixtures_path.join("reset.pem") }
12
+
13
+ it "returns a Hash of authentication headers" do
14
+ options = {
15
+ http_method: "GET",
16
+ host: "https://api.opscode.com",
17
+ path: "/something.file"
18
+ }
19
+ subject.authentication_headers(client_name, client_key, options).should be_a(Hash)
20
+ end
21
+ end
22
+ end
23
+
6
24
  subject do
7
25
  Faraday.new(server_url) do |conn|
8
26
  conn.request :chef_auth, "reset", "/Users/reset/.chef/reset.pem"
9
27
  conn.adapter Faraday.default_adapter
10
28
  end
11
29
  end
12
-
13
- pending
14
30
  end
@@ -82,20 +82,6 @@ describe Ridley::Resource do
82
82
  Class.new(Ridley::Resource).new(connection)
83
83
  end
84
84
 
85
- describe "#attributes=" do
86
- subject do
87
- Class.new(Ridley::Resource) do
88
- attribute :name
89
- end.new(connection)
90
- end
91
-
92
- it "assigns the hash of attributes to the objects attributes" do
93
- subject.attributes = { name: "reset" }
94
-
95
- subject.attributes[:name].should eql("reset")
96
- end
97
- end
98
-
99
85
  describe "comparable" do
100
86
  subject do
101
87
  Class.new(Ridley::Resource) do
@@ -112,8 +98,8 @@ describe Ridley::Resource do
112
98
 
113
99
  context "given two objects with the same value for their 'chef_id'" do
114
100
  before(:each) do
115
- one.attributes = { name: "reset", other_extra: "stuff" }
116
- two.attributes = { name: "reset", extra: "stuff" }
101
+ one.mass_assign(name: "reset", other_extra: "stuff")
102
+ two.mass_assign(name: "reset", extra: "stuff")
117
103
  end
118
104
 
119
105
  it "is equal" do
@@ -123,8 +109,8 @@ describe Ridley::Resource do
123
109
 
124
110
  context "given two objects with different values for their 'chef_id'" do
125
111
  before(:each) do
126
- one.attributes = { name: "jamie", other_extra: "stuff" }
127
- two.attributes = { name: "winsor", extra: "stuff" }
112
+ one.mass_assign(name: "jamie", other_extra: "stuff")
113
+ two.mass_assign(name: "winsor", extra: "stuff")
128
114
  end
129
115
 
130
116
  it "is not equal" do
@@ -149,8 +135,8 @@ describe Ridley::Resource do
149
135
 
150
136
  context "given an array of objects with the same value for their 'chef_id'" do
151
137
  let(:nodes) do
152
- one.attributes = { name: "reset", other_extra: "stuff" }
153
- two.attributes = { name: "reset", extra: "stuff" }
138
+ one.mass_assign(name: "reset", other_extra: "stuff")
139
+ two.mass_assign(name: "reset", extra: "stuff")
154
140
 
155
141
  [ one, two ]
156
142
  end
@@ -162,8 +148,8 @@ describe Ridley::Resource do
162
148
 
163
149
  context "given an array of objects with different values for their 'chef_id'" do
164
150
  let(:nodes) do
165
- one.attributes = { name: "jamie", other_extra: "stuff" }
166
- two.attributes = { name: "winsor", extra: "stuff" }
151
+ one.mass_assign(name: "jamie", other_extra: "stuff")
152
+ two.mass_assign(name: "winsor", extra: "stuff")
167
153
 
168
154
  [ one, two ]
169
155
  end
@@ -1,5 +1,259 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::CookbookResource do
4
- pending
4
+ let(:client) { double('client', connection: double('connection')) }
5
+
6
+ subject { described_class.new(client) }
7
+
8
+ describe "ClassMethods" do
9
+ let(:server_url) { "https://api.opscode.com/organizations/vialstudios" }
10
+ let(:client_name) { "reset" }
11
+ let(:client_key) { fixtures_path.join("reset.pem") }
12
+
13
+ let(:client) do
14
+ Ridley.new(
15
+ server_url: server_url,
16
+ client_name: client_name,
17
+ client_key: client_key
18
+ )
19
+ end
20
+
21
+ describe "::all" do
22
+ subject { described_class.all(client) }
23
+
24
+ before(:each) do
25
+ stub_request(:get, File.join(server_url, "cookbooks")).
26
+ to_return(status: 200, body: {
27
+ "ant" => {
28
+ "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/ant",
29
+ "versions" => [
30
+ {
31
+ "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/ant/0.10.1",
32
+ "version" => "0.10.1"
33
+ }
34
+ ]
35
+ },
36
+ "apache2" => {
37
+ "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/apache2",
38
+ "versions" => [
39
+ {
40
+ "url" => "https://api.opscode.com/organizations/vialstudios/cookbooks/apache2/1.4.0",
41
+ "version" => "1.4.0"
42
+ }
43
+ ]
44
+ }
45
+ }
46
+ )
47
+ end
48
+
49
+ it "returns a Hash" do
50
+ subject.should be_a(Hash)
51
+ end
52
+
53
+ it "contains a key for each cookbook" do
54
+ subject.should include("ant")
55
+ subject.should include("apache2")
56
+ end
57
+
58
+ it "contains an array of versions for each cookbook" do
59
+ subject["ant"].should be_a(Array)
60
+ subject["ant"].should have(1).item
61
+ subject["ant"].should include("0.10.1")
62
+ subject["apache2"].should be_a(Array)
63
+ subject["apache2"].should have(1).item
64
+ subject["apache2"].should include("1.4.0")
65
+ end
66
+ end
67
+
68
+ describe "::delete" do
69
+ let(:name) { "ant" }
70
+ let(:version) { "1.0.0" }
71
+
72
+ it "sends a DELETE to the cookbook version URL" do
73
+ stub_request(:delete, File.join(server_url, "cookbooks", name, version)).
74
+ to_return(status: 200, body: {})
75
+
76
+ described_class.delete(client, name, version)
77
+ end
78
+
79
+ context "when :purge is true" do
80
+ it "appends ?purge=true to the end of the URL" do
81
+ stub_request(:delete, File.join(server_url, "cookbooks", name, "#{version}?purge=true")).
82
+ to_return(status: 200, body: {})
83
+
84
+ described_class.delete(client, name, version, purge: true)
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "::delete_all" do
90
+ let(:name) { "ant" }
91
+ let(:versions) { ["1.0.0", "1.2.0", "2.0.0"] }
92
+ let(:options) { Hash.new }
93
+
94
+ subject { described_class }
95
+
96
+ it "deletes each version of the cookbook" do
97
+ subject.should_receive(:versions).with(client, name).and_return(versions)
98
+
99
+ versions.each do |version|
100
+ subject.should_receive(:delete).with(client, name, version, options)
101
+ end
102
+
103
+ subject.delete_all(client, name, options)
104
+ end
105
+ end
106
+
107
+ describe "::latest_version" do
108
+ let(:name) { "ant" }
109
+ subject { described_class }
110
+
111
+ before(:each) do
112
+ subject.should_receive(:versions).with(client, name).and_return(versions)
113
+ end
114
+
115
+ context "when the cookbook has no versions" do
116
+ let(:versions) { Array.new }
117
+
118
+ it "returns nil" do
119
+ subject.latest_version(client, name).should be_nil
120
+ end
121
+ end
122
+
123
+ context "when the cookbook has versions" do
124
+ let(:versions) do
125
+ [ "1.0.0", "1.2.0", "3.0.0", "1.4.1" ]
126
+ end
127
+
128
+ it "returns nil" do
129
+ subject.latest_version(client, name).should eql("3.0.0")
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "::versions" do
135
+ let(:cookbook) { "artifact" }
136
+ subject { described_class.versions(client, cookbook) }
137
+
138
+ before(:each) do
139
+ stub_request(:get, File.join(server_url, "cookbooks", cookbook)).
140
+ to_return(status: 200, body: {
141
+ cookbook => {
142
+ "versions" => [
143
+ {
144
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.0.0",
145
+ "version" => "1.0.0"
146
+ },
147
+ {
148
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.1.0",
149
+ "version" => "1.1.0"
150
+ },
151
+ {
152
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact/1.2.0",
153
+ "version" => "1.2.0"
154
+ }
155
+ ],
156
+ "url" => "https://api.opscode.com/organizations/ridley/cookbooks/artifact"}
157
+ }
158
+ )
159
+ end
160
+
161
+ it "returns an array" do
162
+ subject.should be_a(Array)
163
+ end
164
+
165
+ it "contains a version string for each cookbook version available" do
166
+ subject.should have(3).versions
167
+ subject.should include("1.0.0")
168
+ subject.should include("1.1.0")
169
+ subject.should include("1.2.0")
170
+ end
171
+ end
172
+ end
173
+
174
+ describe "#download" do
175
+ it "downloads each file" do
176
+ subject.stub(:manifest) do
177
+ {
178
+ resources: [],
179
+ providers: [],
180
+ recipes: [
181
+ {
182
+ checksum: "aa3505d3eb8ce328ea84a4333df05b07",
183
+ name: "default.rb",
184
+ path: "recipes/default.rb",
185
+ specificity: "default",
186
+ url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/aa3505d3eb8ce328ea84a4333df05b07"
187
+ }
188
+ ],
189
+ definitions: [],
190
+ libraries: [],
191
+ attributes: [],
192
+ files: [
193
+ {
194
+ checksum: "85bc3bb921efade3f2566a668ab4b639",
195
+ name: "README",
196
+ path: "files/default/plugins/README",
197
+ specificity: "plugins",
198
+ url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/85bc3bb921efade3f2566a668ab4b639"
199
+ }
200
+ ],
201
+ templates: [],
202
+ root_files: []
203
+ }
204
+ end
205
+
206
+ subject.should_receive(:download_file).with(:recipes, "default.rb", anything)
207
+ subject.should_receive(:download_file).with(:files, "README", anything)
208
+
209
+ subject.download
210
+ end
211
+ end
212
+
213
+ describe "#download_file" do
214
+ let(:destination) { tmp_path.join('fake.file') }
215
+
216
+ before(:each) do
217
+ subject.stub(:root_files) { [ { name: 'metadata.rb', url: "http://test.it/file" } ] }
218
+ end
219
+
220
+ it "downloads the file from the file's url" do
221
+ client.connection.should_receive(:stream).with("http://test.it/file", destination)
222
+
223
+ subject.download_file(:root_file, "metadata.rb", destination)
224
+ end
225
+
226
+ context "when given an unknown filetype" do
227
+ it "raises an UnknownCookbookFileType error" do
228
+ expect {
229
+ subject.download_file(:not_existant, "default.rb", destination)
230
+ }.to raise_error(Ridley::Errors::UnknownCookbookFileType)
231
+ end
232
+ end
233
+
234
+ context "when the cookbook doesn't have the specified file" do
235
+ before(:each) do
236
+ subject.stub(:root_files) { Array.new }
237
+ end
238
+
239
+ it "returns nil" do
240
+ subject.download_file(:root_file, "metadata.rb", destination).should be_nil
241
+ end
242
+ end
243
+ end
244
+
245
+ describe "#manifest" do
246
+ it "returns a Hash" do
247
+ subject.manifest.should be_a(Hash)
248
+ end
249
+
250
+ it "has a key for each item in FILE_TYPES" do
251
+ subject.manifest.keys.should =~ described_class::FILE_TYPES
252
+ end
253
+
254
+ it "contains an empty array for each key" do
255
+ subject.manifest.should each be_a(Array)
256
+ subject.manifest.values.should each be_empty
257
+ end
258
+ end
5
259
  end