ridley 0.10.2 → 0.11.0.rc1

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.
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