ridley 0.10.2 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/README.md +147 -216
  2. data/lib/ridley.rb +2 -0
  3. data/lib/ridley/bootstrap_bindings/unix_template_binding.rb +21 -25
  4. data/lib/ridley/bootstrap_bindings/windows_template_binding.rb +29 -34
  5. data/lib/ridley/bootstrapper.rb +2 -2
  6. data/lib/ridley/bootstrapper/context.rb +5 -5
  7. data/lib/ridley/chef.rb +0 -1
  8. data/lib/ridley/chef/cookbook.rb +0 -9
  9. data/lib/ridley/chef_object.rb +128 -0
  10. data/lib/ridley/chef_objects.rb +3 -0
  11. data/lib/ridley/chef_objects/client_object.rb +55 -0
  12. data/lib/ridley/chef_objects/cookbook_object.rb +190 -0
  13. data/lib/ridley/chef_objects/data_bag_item_obect.rb +104 -0
  14. data/lib/ridley/chef_objects/data_bag_object.rb +31 -0
  15. data/lib/ridley/chef_objects/environment_object.rb +59 -0
  16. data/lib/ridley/chef_objects/node_object.rb +161 -0
  17. data/lib/ridley/chef_objects/role_object.rb +62 -0
  18. data/lib/ridley/chef_objects/sandbox_object.rb +58 -0
  19. data/lib/ridley/client.rb +76 -45
  20. data/lib/ridley/connection.rb +1 -1
  21. data/lib/ridley/errors.rb +8 -1
  22. data/lib/ridley/host_connector.rb +26 -6
  23. data/lib/ridley/host_connector/ssh.rb +3 -3
  24. data/lib/ridley/host_connector/ssh/worker.rb +7 -9
  25. data/lib/ridley/host_connector/winrm/worker.rb +4 -5
  26. data/lib/ridley/mixin/bootstrap_binding.rb +1 -12
  27. data/lib/ridley/resource.rb +51 -171
  28. data/lib/ridley/resources/client_resource.rb +18 -68
  29. data/lib/ridley/resources/cookbook_resource.rb +181 -381
  30. data/lib/ridley/resources/data_bag_item_resource.rb +55 -161
  31. data/lib/ridley/resources/data_bag_resource.rb +20 -61
  32. data/lib/ridley/resources/environment_resource.rb +9 -64
  33. data/lib/ridley/resources/node_resource.rb +135 -311
  34. data/lib/ridley/resources/role_resource.rb +1 -57
  35. data/lib/ridley/resources/sandbox_resource.rb +80 -65
  36. data/lib/ridley/resources/search_resource.rb +99 -0
  37. data/lib/ridley/sandbox_uploader.rb +12 -52
  38. data/lib/ridley/version.rb +1 -1
  39. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  40. data/spec/acceptance/client_resource_spec.rb +15 -37
  41. data/spec/acceptance/data_bag_item_resource_spec.rb +8 -14
  42. data/spec/acceptance/data_bag_resource_spec.rb +1 -1
  43. data/spec/acceptance/environment_resource_spec.rb +13 -22
  44. data/spec/acceptance/node_resource_spec.rb +10 -29
  45. data/spec/acceptance/role_resource_spec.rb +14 -13
  46. data/spec/acceptance/sandbox_resource_spec.rb +2 -2
  47. data/spec/support/shared_examples/ridley_resource.rb +2 -23
  48. data/spec/unit/ridley/bootstrap_bindings/unix_template_binding_spec.rb +3 -4
  49. data/spec/unit/ridley/bootstrap_bindings/windows_template_binding_spec.rb +3 -5
  50. data/spec/unit/ridley/bootstrapper/context_spec.rb +2 -3
  51. data/spec/unit/ridley/bootstrapper_spec.rb +1 -1
  52. data/spec/unit/ridley/chef_object_spec.rb +240 -0
  53. data/spec/unit/ridley/chef_objects/client_object_spec.rb +11 -0
  54. data/spec/unit/ridley/chef_objects/cookbook_object_spec.rb +93 -0
  55. data/spec/unit/ridley/chef_objects/data_bag_item_object_spec.rb +74 -0
  56. data/spec/unit/ridley/chef_objects/data_bag_object_spec.rb +9 -0
  57. data/spec/unit/ridley/chef_objects/environment_object_spec.rb +57 -0
  58. data/spec/unit/ridley/chef_objects/node_object_spec.rb +252 -0
  59. data/spec/unit/ridley/chef_objects/role_object_spec.rb +57 -0
  60. data/spec/unit/ridley/chef_objects/sandbox_object_spec.rb +66 -0
  61. data/spec/unit/ridley/client_spec.rb +51 -51
  62. data/spec/unit/ridley/host_connector/ssh/worker_spec.rb +4 -4
  63. data/spec/unit/ridley/host_connector/ssh_spec.rb +26 -24
  64. data/spec/unit/ridley/host_connector/winrm/worker_spec.rb +3 -4
  65. data/spec/unit/ridley/host_connector/winrm_spec.rb +4 -4
  66. data/spec/unit/ridley/host_connector_spec.rb +40 -3
  67. data/spec/unit/ridley/mixin/bootstrap_binding_spec.rb +1 -1
  68. data/spec/unit/ridley/resource_spec.rb +81 -109
  69. data/spec/unit/ridley/resources/client_resource_spec.rb +18 -33
  70. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +56 -230
  71. data/spec/unit/ridley/resources/data_bag_item_resource_spec.rb +2 -57
  72. data/spec/unit/ridley/resources/data_bag_resource_spec.rb +12 -7
  73. data/spec/unit/ridley/resources/environment_resource_spec.rb +10 -118
  74. data/spec/unit/ridley/resources/node_resource_spec.rb +83 -394
  75. data/spec/unit/ridley/resources/role_resource_spec.rb +2 -56
  76. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +139 -136
  77. data/spec/unit/ridley/resources/search_resource_spec.rb +234 -0
  78. data/spec/unit/ridley/sandbox_uploader_spec.rb +13 -58
  79. metadata +36 -17
  80. data/lib/ridley/chef/chefignore.rb +0 -76
  81. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +0 -55
  82. data/lib/ridley/resources/search.rb +0 -101
  83. data/spec/fixtures/chefignore +0 -8
  84. data/spec/unit/ridley/chef/chefignore_spec.rb +0 -40
  85. data/spec/unit/ridley/resources/search_spec.rb +0 -221
@@ -11,27 +11,12 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
11
11
  it "sends a get request for the class' resource_path using the given client" do
12
12
  response.stub(:body) { Hash.new }
13
13
  client.connection.should_receive(:get).with(subject.resource_path).and_return(response)
14
-
14
+
15
15
  subject.all(client)
16
16
  end
17
17
  end
18
18
 
19
19
  describe "::find" do
20
- it "delegates to find!" do
21
- id = double('id')
22
- subject.should_receive(:find!).with(client, id)
23
-
24
- subject.find(client, id)
25
- end
26
-
27
- context "when the resource is not found" do
28
- it "returns nil" do
29
- pending
30
- end
31
- end
32
- end
33
-
34
- describe "::find!" do
35
20
  it "sends a get request to the given client to the resource_path of the class for the given chef_id" do
36
21
  chef_id = "ridley_test"
37
22
  response.stub(:body) { Hash.new }
@@ -39,12 +24,6 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
39
24
 
40
25
  subject.find(client, chef_id)
41
26
  end
42
-
43
- context "when the resource is not found" do
44
- it "raises a Ridley::Errors::HTTPNotFound error" do
45
- pending
46
- end
47
- end
48
27
  end
49
28
 
50
29
  describe "::create" do
@@ -137,7 +116,7 @@ shared_examples_for "a Ridley Resource" do |resource_klass|
137
116
  end
138
117
 
139
118
  describe "#update" do
140
- context "when the object is valid" do
119
+ context "when the object is valid" do
141
120
  let(:updated) do
142
121
  updated = double('updated')
143
122
  updated.stub(:[]).and_return(Hash.new)
@@ -1,19 +1,18 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Ridley::UnixTemplateBinding do
4
-
5
4
  let(:options) do
6
5
  {
7
6
  server_url: "https://api.opscode.com/organizations/vialstudios",
8
7
  validator_client: "chef-validator",
9
8
  validator_path: fixtures_path.join("reset.pem").to_s,
10
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s
9
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem"))
11
10
  }
12
11
  end
13
-
12
+
14
13
  describe "ClassMethods" do
15
14
  subject { described_class }
16
-
15
+
17
16
  describe "::new" do
18
17
  context "when no sudo option is passed through" do
19
18
  it "sets a default value of 'true' to 'sudo'" do
@@ -6,14 +6,14 @@ describe Ridley::WindowsTemplateBinding do
6
6
  server_url: "https://api.opscode.com/organizations/vialstudios",
7
7
  validator_client: "chef-validator",
8
8
  validator_path: fixtures_path.join("reset.pem").to_s,
9
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s,
9
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem")),
10
10
  chef_version: "11.4.0"
11
11
  }
12
12
  end
13
-
13
+
14
14
  describe "ClassMethods" do
15
15
  subject { described_class }
16
-
16
+
17
17
  describe "::new" do
18
18
  context "when a chef_version is passed through" do
19
19
  it "sets the chef_version attribute to the same value" do
@@ -33,7 +33,6 @@ describe Ridley::WindowsTemplateBinding do
33
33
  subject { Ridley::WindowsTemplateBinding.new(options) }
34
34
 
35
35
  describe "MixinMethods" do
36
-
37
36
  describe "#templates_path" do
38
37
  it "returns a pathname" do
39
38
  subject.templates_path.should be_a(Pathname)
@@ -65,7 +64,6 @@ describe Ridley::WindowsTemplateBinding do
65
64
  end
66
65
  end
67
66
 
68
-
69
67
  describe "#boot_command" do
70
68
  it "returns a string" do
71
69
  subject.boot_command.should be_a(String)
@@ -8,7 +8,7 @@ describe Ridley::Bootstrapper::Context do
8
8
  server_url: "https://api.opscode.com/organizations/vialstudios",
9
9
  validator_client: "chef-validator",
10
10
  validator_path: fixtures_path.join("reset.pem").to_s,
11
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s
11
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem"))
12
12
  }
13
13
  end
14
14
 
@@ -16,7 +16,6 @@ describe Ridley::Bootstrapper::Context do
16
16
  subject { Ridley::Bootstrapper::Context }
17
17
 
18
18
  describe "::create" do
19
-
20
19
  context "when the best connection is SSH" do
21
20
  it "sets template_binding to a Ridley::UnixTemplateBinding" do
22
21
  Ridley::HostConnector.stub(:best_connector_for).and_return(Ridley::HostConnector::SSH)
@@ -29,7 +28,7 @@ describe Ridley::Bootstrapper::Context do
29
28
  it "sets template_binding to a Ridley::WindowsTemplateBinding" do
30
29
  Ridley::HostConnector.stub(:best_connector_for).and_return(Ridley::HostConnector::WinRM)
31
30
  context = subject.create(host, options)
32
- context.template_binding.should be_a(Ridley::WindowsTemplateBinding)
31
+ context.template_binding.should be_a(Ridley::WindowsTemplateBinding)
33
32
  end
34
33
  end
35
34
 
@@ -14,7 +14,7 @@ describe Ridley::Bootstrapper do
14
14
  server_url: "https://api.opscode.com/organizations/vialstudios",
15
15
  validator_client: "vialstudios-validator",
16
16
  validator_path: fixtures_path.join("reset.pem").to_s,
17
- encrypted_data_bag_secret_path: fixtures_path.join("reset.pem").to_s
17
+ encrypted_data_bag_secret: File.read(fixtures_path.join("reset.pem"))
18
18
  }
19
19
  end
20
20
 
@@ -0,0 +1,240 @@
1
+ describe Ridley::ChefObject do
2
+ let(:resource) { double('chef-resource') }
3
+
4
+ describe "ClassMethods" do
5
+ subject { Class.new(described_class) }
6
+
7
+ describe "::new" do
8
+ it "mass assigns the given attributes" do
9
+ new_attrs = {
10
+ name: "a name"
11
+ }
12
+
13
+ subject.any_instance.should_receive(:mass_assign).with(new_attrs)
14
+ subject.new(resource, new_attrs)
15
+ end
16
+ end
17
+
18
+ describe "::set_chef_type" do
19
+ it "sets the chef_type attr on the class" do
20
+ subject.set_chef_type("environment")
21
+
22
+ subject.chef_type.should eql("environment")
23
+ end
24
+ end
25
+
26
+ describe "::set_chef_json_class" do
27
+ it "sets the chef_json_class attr on the class" do
28
+ subject.set_chef_json_class("Chef::Environment")
29
+
30
+ subject.chef_json_class.should eql("Chef::Environment")
31
+ end
32
+ end
33
+
34
+ describe "::set_chef_id" do
35
+ it "sets the chef_id attribute on the class" do
36
+ subject.set_chef_id(:environment)
37
+
38
+ subject.chef_id.should eql(:environment)
39
+ end
40
+ end
41
+
42
+ describe "::chef_type" do
43
+ it "returns the underscored name of the including class if nothing is set" do
44
+ subject.chef_type.should eql(subject.class.name.underscore)
45
+ end
46
+ end
47
+
48
+ describe "::chef_json_class" do
49
+ it "returns the chef_json if nothing has been set" do
50
+ subject.chef_json_class.should be_nil
51
+ end
52
+ end
53
+
54
+ describe "::chef_id" do
55
+ it "returns nil if nothing is set" do
56
+ subject.chef_id.should be_nil
57
+ end
58
+ end
59
+ end
60
+
61
+ subject do
62
+ Class.new(described_class).new(resource)
63
+ end
64
+
65
+ describe "#save" do
66
+ context "when the object is valid" do
67
+ before(:each) { subject.stub(:valid?).and_return(true) }
68
+
69
+ it "sends a create message to the implementing class" do
70
+ updated = double('updated')
71
+ updated.stub(:_attributes_).and_return(Hash.new)
72
+ resource.should_receive(:create).with(subject).and_return(updated)
73
+
74
+ subject.save
75
+ end
76
+
77
+ context "when there is an HTTPConflict" do
78
+ it "sends the update message to self" do
79
+ updated = double('updated')
80
+ updated.stub(:[]).and_return(Hash.new)
81
+ updated.stub(:_attributes_).and_return(Hash.new)
82
+ resource.should_receive(:create).and_raise(Ridley::Errors::HTTPConflict.new(updated))
83
+ subject.should_receive(:update).and_return(updated)
84
+
85
+ subject.save
86
+ end
87
+ end
88
+ end
89
+
90
+ context "when the object is invalid" do
91
+ before(:each) { subject.stub(:valid?).and_return(false) }
92
+
93
+ it "raises an InvalidResource error" do
94
+ lambda {
95
+ subject.save
96
+ }.should raise_error(Ridley::Errors::InvalidResource)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "#update" do
102
+ context "when the object is valid" do
103
+ let(:updated) do
104
+ updated = double('updated')
105
+ updated.stub(:[]).and_return(Hash.new)
106
+ updated.stub(:_attributes_).and_return(Hash.new)
107
+ updated
108
+ end
109
+
110
+ before(:each) { subject.stub(:valid?).and_return(true) }
111
+
112
+ it "sends an update message to the implementing class" do
113
+ resource.should_receive(:update).with(subject).and_return(updated)
114
+ subject.update
115
+ end
116
+
117
+ it "returns true" do
118
+ resource.should_receive(:update).with(subject).and_return(updated)
119
+ subject.update.should eql(true)
120
+ end
121
+ end
122
+
123
+ context "when the object is invalid" do
124
+ before(:each) { subject.stub(:valid?).and_return(false) }
125
+
126
+ it "raises an InvalidResource error" do
127
+ lambda {
128
+ subject.update
129
+ }.should raise_error(Ridley::Errors::InvalidResource)
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "#chef_id" do
135
+ it "returns the value of the chef_id attribute" do
136
+ subject.class.attribute(:name)
137
+ subject.class.stub(:chef_id) { :name }
138
+ subject.mass_assign(name: "reset")
139
+
140
+ subject.chef_id.should eql("reset")
141
+ end
142
+ end
143
+
144
+ describe "#reload" do
145
+ let(:updated_subject) { double('updated_subject', _attributes_: { fake_attribute: "some_value" }) }
146
+
147
+ before(:each) do
148
+ subject.class.attribute(:fake_attribute)
149
+ resource.should_receive(:find).with(subject).and_return(updated_subject)
150
+ end
151
+
152
+ it "returns itself" do
153
+ subject.reload.should eql(subject)
154
+ end
155
+
156
+ it "sets the attributes of self to include those of the reloaded object" do
157
+ subject.reload
158
+
159
+ subject.get_attribute(:fake_attribute).should eql("some_value")
160
+ end
161
+ end
162
+
163
+ describe "comparable" do
164
+ subject do
165
+ Class.new(described_class) do
166
+ set_chef_id "name"
167
+
168
+ attribute "name"
169
+ attribute "other_extra"
170
+ attribute "extra"
171
+ end
172
+ end
173
+
174
+ let(:one) { subject.new(resource) }
175
+ let(:two) { subject.new(resource) }
176
+
177
+ context "given two objects with the same value for their 'chef_id'" do
178
+ before(:each) do
179
+ one.mass_assign(name: "reset", other_extra: "stuff")
180
+ two.mass_assign(name: "reset", extra: "stuff")
181
+ end
182
+
183
+ it "is equal" do
184
+ one.should be_eql(two)
185
+ end
186
+ end
187
+
188
+ context "given two objects with different values for their 'chef_id'" do
189
+ before(:each) do
190
+ one.mass_assign(name: "jamie", other_extra: "stuff")
191
+ two.mass_assign(name: "winsor", extra: "stuff")
192
+ end
193
+
194
+ it "is not equal" do
195
+ one.should_not be_eql(two)
196
+ end
197
+ end
198
+ end
199
+
200
+ describe "uniqueness" do
201
+ subject do
202
+ Class.new(described_class) do
203
+ set_chef_id "name"
204
+
205
+ attribute "name"
206
+ attribute "other_extra"
207
+ attribute "extra"
208
+ end
209
+ end
210
+
211
+ let(:one) { subject.new(resource) }
212
+ let(:two) { subject.new(resource) }
213
+
214
+ context "given an array of objects with the same value for their 'chef_id'" do
215
+ let(:nodes) do
216
+ one.mass_assign(name: "reset", other_extra: "stuff")
217
+ two.mass_assign(name: "reset", extra: "stuff")
218
+
219
+ [ one, two ]
220
+ end
221
+
222
+ it "returns only one unique element" do
223
+ nodes.uniq.should have(1).item
224
+ end
225
+ end
226
+
227
+ context "given an array of objects with different values for their 'chef_id'" do
228
+ let(:nodes) do
229
+ one.mass_assign(name: "jamie", other_extra: "stuff")
230
+ two.mass_assign(name: "winsor", extra: "stuff")
231
+
232
+ [ one, two ]
233
+ end
234
+
235
+ it "returns all of the elements" do
236
+ nodes.uniq.should have(2).item
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::ClientObject do
4
+ describe "#to_json" do
5
+ pending
6
+ end
7
+
8
+ describe "#regenerate_key" do
9
+ pending
10
+ end
11
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::CookbookObject do
4
+ let(:connection) { double('chef-connection') }
5
+ subject { described_class.new(double('registry')) }
6
+ before { subject.stub(connection: connection) }
7
+
8
+ describe "#download" do
9
+ it "downloads each file" do
10
+ subject.stub(:manifest) do
11
+ {
12
+ resources: [],
13
+ providers: [],
14
+ recipes: [
15
+ {
16
+ checksum: "aa3505d3eb8ce328ea84a4333df05b07",
17
+ name: "default.rb",
18
+ path: "recipes/default.rb",
19
+ specificity: "default",
20
+ url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/aa3505d3eb8ce328ea84a4333df05b07"
21
+ }
22
+ ],
23
+ definitions: [],
24
+ libraries: [],
25
+ attributes: [],
26
+ files: [
27
+ {
28
+ checksum: "85bc3bb921efade3f2566a668ab4b639",
29
+ name: "README",
30
+ path: "files/default/plugins/README",
31
+ specificity: "plugins",
32
+ url: "https://chef.lax1.riotgames.com/organizations/reset/cookbooks/ohai/1.0.2/files/85bc3bb921efade3f2566a668ab4b639"
33
+ }
34
+ ],
35
+ templates: [],
36
+ root_files: []
37
+ }
38
+ end
39
+
40
+ subject.should_receive(:download_file).with(:recipes, "recipes/default.rb", anything)
41
+ subject.should_receive(:download_file).with(:files, "files/default/plugins/README", anything)
42
+
43
+ subject.download
44
+ end
45
+ end
46
+
47
+ describe "#download_file" do
48
+ let(:destination) { tmp_path.join('fake.file').to_s }
49
+
50
+ before(:each) do
51
+ subject.stub(:root_files) { [ { path: 'metadata.rb', url: "http://test.it/file" } ] }
52
+ end
53
+
54
+ it "downloads the file from the file's url" do
55
+ connection.should_receive(:stream).with("http://test.it/file", destination)
56
+
57
+ subject.download_file(:root_file, "metadata.rb", destination)
58
+ end
59
+
60
+ context "when given an unknown filetype" do
61
+ it "raises an UnknownCookbookFileType error" do
62
+ expect {
63
+ subject.download_file(:not_existant, "default.rb", destination)
64
+ }.to raise_error(Ridley::Errors::UnknownCookbookFileType)
65
+ end
66
+ end
67
+
68
+ context "when the cookbook doesn't have the specified file" do
69
+ before(:each) do
70
+ subject.stub(:root_files) { Array.new }
71
+ end
72
+
73
+ it "returns nil" do
74
+ subject.download_file(:root_file, "metadata.rb", destination).should be_nil
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "#manifest" do
80
+ it "returns a Hash" do
81
+ subject.manifest.should be_a(Hash)
82
+ end
83
+
84
+ it "has a key for each item in FILE_TYPES" do
85
+ subject.manifest.keys.should =~ described_class::FILE_TYPES
86
+ end
87
+
88
+ it "contains an empty array for each key" do
89
+ subject.manifest.should each be_a(Array)
90
+ subject.manifest.values.should each be_empty
91
+ end
92
+ end
93
+ end