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
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::DataBagItemObject do
4
+ let(:resource) { double('chef-resource') }
5
+ let(:data_bag) { double('data-bag') }
6
+ subject { described_class.new(resource, data_bag) }
7
+
8
+ describe "#from_hash" do
9
+ context "when JSON has a 'raw_data' field" do
10
+ let(:response) do
11
+ {
12
+ "name" => "data_bag_item_ridley-test_appconfig",
13
+ "raw_data" => {
14
+ "id" => "appconfig",
15
+ "host" => "host.local"
16
+ },
17
+ "json_class" => "Chef::DataBagItem",
18
+ "data_bag" => "ridley-test",
19
+ "chef_type" => "data_bag_item"
20
+ }
21
+ end
22
+
23
+ it "returns a new object from attributes in the 'raw_data' field" do
24
+ subject.from_hash(response).attributes.should eql(response["raw_data"])
25
+ end
26
+ end
27
+
28
+ context "when JSON does not contain a 'raw_data' field" do
29
+ let(:response) do
30
+ {
31
+ "id" => "appconfig",
32
+ "host" => "host.local"
33
+ }
34
+ end
35
+
36
+ it "returns a new object from the hash" do
37
+ subject.from_hash(response).attributes.should eql(response)
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#decrypt" do
43
+ before(:each) do
44
+ resource.stub(encrypted_data_bag_secret: File.read(fixtures_path.join("encrypted_data_bag_secret").to_s))
45
+ end
46
+
47
+ it "decrypts an encrypted value" do
48
+ subject.attributes[:test] = "Xk0E8lV9r4BhZzcg4wal0X4w9ZexN3azxMjZ9r1MCZc="
49
+ subject.decrypt
50
+ subject.attributes[:test][:database][:username].should == "test"
51
+ end
52
+
53
+ it "does not decrypt the id field" do
54
+ id = "dbi_id"
55
+ subject.attributes[:id] = id
56
+ subject.decrypt
57
+ subject.attributes[:id].should == id
58
+ end
59
+ end
60
+
61
+ describe "#decrypt_value" do
62
+ context "when no encrypted_data_bag_secret has been configured" do
63
+ before do
64
+ resource.stub(encrypted_data_bag_secret: nil)
65
+ end
66
+
67
+ it "raises an EncryptedDataBagSecretNotSet error" do
68
+ expect {
69
+ subject.decrypt_value("Xk0E8lV9r4BhZzcg4wal0X4w9ZexN3azxMjZ9r1MCZc=")
70
+ }.to raise_error(Ridley::Errors::EncryptedDataBagSecretNotSet)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::DataBagObject do
4
+ let(:item_resource) { double('item-resource') }
5
+ let(:resource) { double('db-resource', item_resource: item_resource) }
6
+ subject { described_class.new(resource) }
7
+
8
+ its(:item) { should be_a(Ridley::DataBagObject::DataBagItemProxy) }
9
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::EnvironmentObject do
4
+ subject { described_class.new(double('registry')) }
5
+
6
+ describe "#set_override_attribute" do
7
+ it "sets an override node attribute at the nested path" do
8
+ subject.set_override_attribute('deep.nested.item', true)
9
+
10
+ subject.override_attributes.should have_key("deep")
11
+ subject.override_attributes["deep"].should have_key("nested")
12
+ subject.override_attributes["deep"]["nested"].should have_key("item")
13
+ subject.override_attributes["deep"]["nested"]["item"].should be_true
14
+ end
15
+
16
+ context "when the override attribute is already set" do
17
+ it "test" do
18
+ subject.override_attributes = {
19
+ deep: {
20
+ nested: {
21
+ item: false
22
+ }
23
+ }
24
+ }
25
+ subject.set_override_attribute('deep.nested.item', true)
26
+
27
+ subject.override_attributes["deep"]["nested"]["item"].should be_true
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#set_default_attribute" do
33
+ it "sets an override node attribute at the nested path" do
34
+ subject.set_default_attribute('deep.nested.item', true)
35
+
36
+ subject.default_attributes.should have_key("deep")
37
+ subject.default_attributes["deep"].should have_key("nested")
38
+ subject.default_attributes["deep"]["nested"].should have_key("item")
39
+ subject.default_attributes["deep"]["nested"]["item"].should be_true
40
+ end
41
+
42
+ context "when the override attribute is already set" do
43
+ it "test" do
44
+ subject.default_attributes = {
45
+ deep: {
46
+ nested: {
47
+ item: false
48
+ }
49
+ }
50
+ }
51
+ subject.set_default_attribute('deep.nested.item', true)
52
+
53
+ subject.default_attributes["deep"]["nested"]["item"].should be_true
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::NodeObject do
4
+ let(:resource) { double('resource') }
5
+ let(:instance) { described_class.new(resource) }
6
+ subject { instance }
7
+
8
+ describe "#set_chef_attribute" do
9
+ it "sets an normal node attribute at the nested path" do
10
+ subject.set_chef_attribute('deep.nested.item', true)
11
+
12
+ subject.normal.should have_key("deep")
13
+ subject.normal["deep"].should have_key("nested")
14
+ subject.normal["deep"]["nested"].should have_key("item")
15
+ subject.normal["deep"]["nested"]["item"].should be_true
16
+ end
17
+
18
+ context "when the normal attribute is already set" do
19
+ it "test" do
20
+ subject.normal = {
21
+ deep: {
22
+ nested: {
23
+ item: false
24
+ }
25
+ }
26
+ }
27
+ subject.set_chef_attribute('deep.nested.item', true)
28
+
29
+ subject.normal["deep"]["nested"]["item"].should be_true
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#cloud?" do
35
+ it "returns true if the cloud automatic attribute is set" do
36
+ subject.automatic = {
37
+ "cloud" => Hash.new
38
+ }
39
+
40
+ subject.cloud?.should be_true
41
+ end
42
+
43
+ it "returns false if the cloud automatic attribute is not set" do
44
+ subject.automatic.delete(:cloud)
45
+
46
+ subject.cloud?.should be_false
47
+ end
48
+ end
49
+
50
+ describe "#eucalyptus?" do
51
+ it "returns true if the node is a cloud node using the eucalyptus provider" do
52
+ subject.automatic = {
53
+ "cloud" => {
54
+ "provider" => "eucalyptus"
55
+ }
56
+ }
57
+
58
+ subject.eucalyptus?.should be_true
59
+ end
60
+
61
+ it "returns false if the node is not a cloud node" do
62
+ subject.automatic.delete(:cloud)
63
+
64
+ subject.eucalyptus?.should be_false
65
+ end
66
+
67
+ it "returns false if the node is a cloud node but not using the eucalyptus provider" do
68
+ subject.automatic = {
69
+ "cloud" => {
70
+ "provider" => "ec2"
71
+ }
72
+ }
73
+
74
+ subject.eucalyptus?.should be_false
75
+ end
76
+ end
77
+
78
+ describe "#ec2?" do
79
+ it "returns true if the node is a cloud node using the ec2 provider" do
80
+ subject.automatic = {
81
+ "cloud" => {
82
+ "provider" => "ec2"
83
+ }
84
+ }
85
+
86
+ subject.ec2?.should be_true
87
+ end
88
+
89
+ it "returns false if the node is not a cloud node" do
90
+ subject.automatic.delete(:cloud)
91
+
92
+ subject.ec2?.should be_false
93
+ end
94
+
95
+ it "returns false if the node is a cloud node but not using the ec2 provider" do
96
+ subject.automatic = {
97
+ "cloud" => {
98
+ "provider" => "rackspace"
99
+ }
100
+ }
101
+
102
+ subject.ec2?.should be_false
103
+ end
104
+ end
105
+
106
+ describe "#rackspace?" do
107
+ it "returns true if the node is a cloud node using the rackspace provider" do
108
+ subject.automatic = {
109
+ "cloud" => {
110
+ "provider" => "rackspace"
111
+ }
112
+ }
113
+
114
+ subject.rackspace?.should be_true
115
+ end
116
+
117
+ it "returns false if the node is not a cloud node" do
118
+ subject.automatic.delete(:cloud)
119
+
120
+ subject.rackspace?.should be_false
121
+ end
122
+
123
+ it "returns false if the node is a cloud node but not using the rackspace provider" do
124
+ subject.automatic = {
125
+ "cloud" => {
126
+ "provider" => "ec2"
127
+ }
128
+ }
129
+
130
+ subject.rackspace?.should be_false
131
+ end
132
+ end
133
+
134
+ describe "#cloud_provider" do
135
+ it "returns the cloud provider if the node is a cloud node" do
136
+ subject.automatic = {
137
+ "cloud" => {
138
+ "provider" => "ec2"
139
+ }
140
+ }
141
+
142
+ subject.cloud_provider.should eql("ec2")
143
+ end
144
+
145
+ it "returns nil if the node is not a cloud node" do
146
+ subject.automatic.delete(:cloud)
147
+
148
+ subject.cloud_provider.should be_nil
149
+ end
150
+ end
151
+
152
+ describe "#public_ipv4" do
153
+ it "returns the public ipv4 address if the node is a cloud node" do
154
+ subject.automatic = {
155
+ "cloud" => {
156
+ "provider" => "ec2",
157
+ "public_ipv4" => "10.0.0.1"
158
+ }
159
+ }
160
+
161
+ subject.public_ipv4.should eql("10.0.0.1")
162
+ end
163
+
164
+ it "returns the ipaddress if the node is not a cloud node" do
165
+ subject.automatic = {
166
+ "ipaddress" => "192.168.1.1"
167
+ }
168
+ subject.automatic.delete(:cloud)
169
+
170
+ subject.public_ipv4.should eql("192.168.1.1")
171
+ end
172
+ end
173
+
174
+ describe "#public_hostname" do
175
+ it "returns the public hostname if the node is a cloud node" do
176
+ subject.automatic = {
177
+ "cloud" => {
178
+ "public_hostname" => "reset.cloud.riotgames.com"
179
+ }
180
+ }
181
+
182
+ subject.public_hostname.should eql("reset.cloud.riotgames.com")
183
+ end
184
+
185
+ it "returns the FQDN if the node is not a cloud node" do
186
+ subject.automatic = {
187
+ "fqdn" => "reset.internal.riotgames.com"
188
+ }
189
+ subject.automatic.delete(:cloud)
190
+
191
+ subject.public_hostname.should eql("reset.internal.riotgames.com")
192
+ end
193
+ end
194
+
195
+ describe "#chef_run" do
196
+ it "sends the message #chef_run to the resource with the public_hostname of this instance" do
197
+ resource.should_receive(:chef_run).with(instance.public_hostname)
198
+
199
+ subject.chef_run
200
+ end
201
+ end
202
+
203
+ describe "#put_secret" do
204
+ it "sends the message #put_secret to the resource with the public_hostname of this instance" do
205
+ resource.should_receive(:put_secret).with(instance.public_hostname)
206
+
207
+ subject.put_secret
208
+ end
209
+ end
210
+
211
+ describe "#merge_data" do
212
+ before(:each) do
213
+ subject.name = "reset.riotgames.com"
214
+ subject.should_receive(:update)
215
+ end
216
+
217
+ it "appends items to the run_list" do
218
+ subject.merge_data(run_list: ["cook::one", "cook::two"])
219
+
220
+ subject.run_list.should =~ ["cook::one", "cook::two"]
221
+ end
222
+
223
+ it "ensures the run_list is unique if identical items are given" do
224
+ subject.run_list = [ "cook::one" ]
225
+ subject.merge_data(run_list: ["cook::one", "cook::two"])
226
+
227
+ subject.run_list.should =~ ["cook::one", "cook::two"]
228
+ end
229
+
230
+ it "deep merges attributes into the normal attributes" do
231
+ subject.normal = {
232
+ one: {
233
+ two: {
234
+ four: :deep
235
+ }
236
+ }
237
+ }
238
+ subject.merge_data(attributes: {
239
+ one: {
240
+ two: {
241
+ three: :deep
242
+ }
243
+ }
244
+ })
245
+
246
+ subject.normal[:one][:two].should have_key(:four)
247
+ subject.normal[:one][:two][:four].should eql(:deep)
248
+ subject.normal[:one][:two].should have_key(:three)
249
+ subject.normal[:one][:two][:three].should eql(:deep)
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ridley::RoleObject do
4
+ subject { described_class.new(double('registry')) }
5
+
6
+ describe "#set_override_attribute" do
7
+ it "sets an override node attribute at the nested path" do
8
+ subject.set_override_attribute('deep.nested.item', true)
9
+
10
+ subject.override_attributes.should have_key("deep")
11
+ subject.override_attributes["deep"].should have_key("nested")
12
+ subject.override_attributes["deep"]["nested"].should have_key("item")
13
+ subject.override_attributes["deep"]["nested"]["item"].should be_true
14
+ end
15
+
16
+ context "when the override attribute is already set" do
17
+ it "test" do
18
+ subject.override_attributes = {
19
+ deep: {
20
+ nested: {
21
+ item: false
22
+ }
23
+ }
24
+ }
25
+ subject.set_override_attribute('deep.nested.item', true)
26
+
27
+ subject.override_attributes["deep"]["nested"]["item"].should be_true
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#set_default_attribute" do
33
+ it "sets an override node attribute at the nested path" do
34
+ subject.set_default_attribute('deep.nested.item', true)
35
+
36
+ subject.default_attributes.should have_key("deep")
37
+ subject.default_attributes["deep"].should have_key("nested")
38
+ subject.default_attributes["deep"]["nested"].should have_key("item")
39
+ subject.default_attributes["deep"]["nested"]["item"].should be_true
40
+ end
41
+
42
+ context "when the override attribute is already set" do
43
+ it "test" do
44
+ subject.default_attributes = {
45
+ deep: {
46
+ nested: {
47
+ item: false
48
+ }
49
+ }
50
+ }
51
+ subject.set_default_attribute('deep.nested.item', true)
52
+
53
+ subject.default_attributes["deep"]["nested"]["item"].should be_true
54
+ end
55
+ end
56
+ end
57
+ end