ridley 0.7.0.beta → 0.7.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 (54) hide show
  1. data/README.md +51 -54
  2. data/lib/ridley.rb +7 -13
  3. data/lib/ridley/client.rb +251 -0
  4. data/lib/ridley/connection.rb +32 -188
  5. data/lib/ridley/middleware/chef_auth.rb +4 -1
  6. data/lib/ridley/resource.rb +36 -42
  7. data/lib/ridley/resources.rb +3 -0
  8. data/lib/ridley/resources/{client.rb → client_resource.rb} +7 -20
  9. data/lib/ridley/resources/cookbook_resource.rb +121 -0
  10. data/lib/ridley/resources/{data_bag_item.rb → data_bag_item_resource.rb} +52 -63
  11. data/lib/ridley/resources/data_bag_resource.rb +74 -0
  12. data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +55 -0
  13. data/lib/ridley/resources/{environment.rb → environment_resource.rb} +8 -21
  14. data/lib/ridley/resources/{node.rb → node_resource.rb} +24 -37
  15. data/lib/ridley/resources/{role.rb → role_resource.rb} +1 -14
  16. data/lib/ridley/resources/sandbox_resource.rb +86 -0
  17. data/lib/ridley/resources/search.rb +24 -55
  18. data/lib/ridley/sandbox_uploader.rb +118 -0
  19. data/lib/ridley/ssh.rb +2 -2
  20. data/lib/ridley/ssh/worker.rb +2 -1
  21. data/lib/ridley/version.rb +1 -1
  22. data/ridley.gemspec +1 -1
  23. data/spec/acceptance/bootstrapping_spec.rb +1 -1
  24. data/spec/acceptance/client_resource_spec.rb +18 -20
  25. data/spec/acceptance/cookbook_resource_spec.rb +4 -22
  26. data/spec/acceptance/data_bag_item_resource_spec.rb +5 -7
  27. data/spec/acceptance/data_bag_resource_spec.rb +4 -6
  28. data/spec/acceptance/environment_resource_spec.rb +14 -16
  29. data/spec/acceptance/node_resource_spec.rb +12 -14
  30. data/spec/acceptance/role_resource_spec.rb +13 -15
  31. data/spec/acceptance/sandbox_resource_spec.rb +7 -9
  32. data/spec/acceptance/search_resource_spec.rb +6 -8
  33. data/spec/support/shared_examples/ridley_resource.rb +23 -22
  34. data/spec/unit/ridley/client_spec.rb +153 -0
  35. data/spec/unit/ridley/connection_spec.rb +8 -221
  36. data/spec/unit/ridley/resources/{client_spec.rb → client_resource_spec.rb} +4 -4
  37. data/spec/unit/ridley/resources/cookbook_resource_spec.rb +5 -0
  38. data/spec/unit/ridley/resources/{data_bag_item_spec.rb → data_bag_item_resource_spec.rb} +2 -2
  39. data/spec/unit/ridley/resources/{data_bag_spec.rb → data_bag_resource_spec.rb} +3 -3
  40. data/spec/unit/ridley/resources/{environment_spec.rb → environment_resource_spec.rb} +4 -4
  41. data/spec/unit/ridley/resources/{node_spec.rb → node_resource_spec.rb} +4 -4
  42. data/spec/unit/ridley/resources/{role_spec.rb → role_resource_spec.rb} +3 -3
  43. data/spec/unit/ridley/resources/sandbox_resource_spec.rb +172 -0
  44. data/spec/unit/ridley/resources/search_spec.rb +34 -30
  45. data/spec/unit/ridley/sandbox_uploader_spec.rb +99 -0
  46. data/spec/unit/ridley/ssh_spec.rb +2 -2
  47. data/spec/unit/ridley_spec.rb +4 -12
  48. metadata +36 -28
  49. data/lib/ridley/dsl.rb +0 -58
  50. data/lib/ridley/resources/cookbook.rb +0 -51
  51. data/lib/ridley/resources/data_bag.rb +0 -81
  52. data/lib/ridley/resources/encrypted_data_bag_item.rb +0 -54
  53. data/lib/ridley/resources/sandbox.rb +0 -154
  54. data/spec/unit/ridley/resources/cookbook_spec.rb +0 -5
data/README.md CHANGED
@@ -21,9 +21,9 @@ Require Ridley into your application
21
21
 
22
22
  require 'ridley'
23
23
 
24
- ## Creating a new connection
24
+ ## Creating a new Ridley client
25
25
 
26
- conn = Ridley::Connection.new(
26
+ conn = Ridley.new(
27
27
  server_url: "https://api.opscode.com",
28
28
  client_name: "reset",
29
29
  client_key: "/Users/reset/.chef/reset.pem",
@@ -38,15 +38,12 @@ Creating a new connection requires you to specify at minimum:
38
38
 
39
39
  An optional organization option can be specified if you are working with Hosted or Private Chef (OHC/OPC). For a full list of available options see the [yard documentation](http://rubydoc.info/gems/ridley).
40
40
 
41
- __NOTE: You do not want to specify an `organization` if you are connecting to an Open Source Chef server.__
41
+ Connections can also be instantiated by a helper function: `Ridley.new`
42
42
 
43
- Connections can also be instantiated by a helper function: `Ridley.connection`
44
-
45
- Ridley.connection(
43
+ Ridley.new(
46
44
  server_url: "https://api.opscode.com",
47
45
  client_name: "reset",
48
- client_key: "/Users/reset/.chef/reset.pem",
49
- organization: "ridley"
46
+ client_key: "/Users/reset/.chef/reset.pem"
50
47
  )
51
48
 
52
49
  Using a connection object you can interact with collections of resources on a Chef server. Resources are:
@@ -60,7 +57,7 @@ Using a connection object you can interact with collections of resources on a Ch
60
57
 
61
58
  Here is a simple example of instantiating a new connection and listing all of the roles on a Chef server.
62
59
 
63
- conn = Ridley.connection(...)
60
+ conn = Ridley.new(...)
64
61
  conn.role.all => []
65
62
 
66
63
  For more information scroll down to the Manipulating Chef Resources section of this README.
@@ -69,7 +66,7 @@ For more information scroll down to the Manipulating Chef Resources section of t
69
66
 
70
67
  An alternative syntax is provided if you want to perform multiple requests, in order, on a connection.
71
68
 
72
- conn = Ridley.connection(...)
69
+ conn = Ridley.new(...)
73
70
 
74
71
  conn.sync do
75
72
  role.all
@@ -104,18 +101,18 @@ All resource can be listed, created, retrieved, updated, or destroyed. Some reso
104
101
 
105
102
  You use a connection to interact with the resources on the remote Chef server it is pointing to. For example, if you wanted to get a list of all of the roles on your Chef server:
106
103
 
107
- conn = Ridley.connection(...)
104
+ conn = Ridley.new(...)
108
105
  conn.role.all => []
109
106
 
110
- Calling `role.all` on the connection object will return an array of Ridley::Role objects. All of the resources can be listed, not just Roles:
107
+ Calling `role.all` on the connection object will return an array of Ridley::RoleResource objects. All of the resources can be listed, not just Roles:
111
108
 
112
- conn = Ridley.connection(...)
113
- conn.node.all => [<#Ridley::Node>]
114
- conn.role.all => [<#Ridley::Role>]
115
- conn.environment.all => [<#Ridley::Environment>]
116
- conn.client.all => [<#Ridley::Client>]
117
- conn.cookbook.all => [<#Ridley::Cookbook>]
118
- conn.data_bag.all => [<#Ridley::DataBag>]
109
+ conn = Ridley.new(...)
110
+ conn.node.all => [<#Ridley::NodeResource>]
111
+ conn.role.all => [<#Ridley::RoleResource>]
112
+ conn.environment.all => [<#Ridley::EnvironmentResource>]
113
+ conn.client.all => [<#Ridley::ClientResource>]
114
+ conn.cookbook.all => [<#Ridley::CookbookResource>]
115
+ conn.data_bag.all => [<#Ridley::DataBagResource>]
119
116
 
120
117
  ### Creating a resource
121
118
 
@@ -123,24 +120,24 @@ A new resource can be created in a few ways
123
120
 
124
121
  _Create by instantiate and save_
125
122
 
126
- conn = Ridley.connection(...)
123
+ conn = Ridley.new(...)
127
124
  obj = conn.role.new
128
125
 
129
126
  obj.name = "reset"
130
- obj.save => <#Ridley::Role: @name="reset">
127
+ obj.save => <#Ridley::RoleResource: @name="reset">
131
128
 
132
129
  _Create by the `create` function with attribute hash_
133
130
 
134
- conn = Ridley.connection(...)
135
- conn.role.create(name: "reset") => <#Ridley::Role: @name="reset">
131
+ conn = Ridley.new(...)
132
+ conn.role.create(name: "reset") => <#Ridley::RoleResource: @name="reset">
136
133
 
137
134
  _Create by the `create` function with a resource object_
138
135
 
139
- conn = Ridley.connection(...)
136
+ conn = Ridley.new(...)
140
137
  obj = conn.role.new
141
138
 
142
139
  obj.name = "reset"
143
- conn.role.create(obj) => <#Ridley::Role: @name="reset">
140
+ conn.role.create(obj) => <#Ridley::RoleResource: @name="reset">
144
141
 
145
142
  Each of these methods is identical, it is up to you on how you'd like to create new resources.
146
143
 
@@ -152,14 +149,14 @@ Both `find` and `find!` will return a resource but if the resource is not found
152
149
 
153
150
  If you were following allong in the previous section we created a role named `reset`. We'll assume that role has been created in this next example.
154
151
 
155
- conn = Ridley.connection(...)
152
+ conn = Ridley.new(...)
156
153
 
157
- conn.role.find("reset") => <#Ridley::Role: @name="reset">
158
- conn.role.find!("reset") => <#Ridley::Role: @name="reset">
154
+ conn.role.find("reset") => <#Ridley::RoleResource: @name="reset">
155
+ conn.role.find!("reset") => <#Ridley::RoleResource: @name="reset">
159
156
 
160
157
  Now if we attempt to find a role that does not exist on the Chef server
161
158
 
162
- conn = Ridley.connection(...)
159
+ conn = Ridley.new(...)
163
160
 
164
161
  conn.role.find("not_there") => nil
165
162
  conn.role.find!("not_there") =>
@@ -182,24 +179,24 @@ Like creating a resource, updating a resource can also be expressed a few differ
182
179
 
183
180
  _Update by the `update` function with an id and attribute hash_
184
181
 
185
- conn = Ridley.connection(...)
186
- conn.role.update("reset", description: "testing updates!") => <#Ridley::Role: @name="reset", @description="testing updates!">
182
+ conn = Ridley.new(...)
183
+ conn.role.update("reset", description: "testing updates!") => <#Ridley::RoleResource: @name="reset", @description="testing updates!">
187
184
 
188
185
  _Update by the `update` function with a resource object_
189
186
 
190
- conn = Ridley.connection(...)
187
+ conn = Ridley.new(...)
191
188
  obj = conn.role.find("reset")
192
189
  obj.description = "resource object!"
193
190
 
194
- conn.role.update(obj) => <#Ridley::Role: @name="reset", @description="resource object!">
191
+ conn.role.update(obj) => <#Ridley::RoleResource: @name="reset", @description="resource object!">
195
192
 
196
193
  _Update by saving a resource object_
197
194
 
198
- conn = Ridley.connection(...)
195
+ conn = Ridley.new(...)
199
196
  obj = conn.role.find("reset")
200
197
 
201
198
  obj.description = "saving an object!"
202
- obj.save => <#Ridley::Role: @name="reset", @description="saving an object!">
199
+ obj.save => <#Ridley::RoleResource: @name="reset", @description="saving an object!">
203
200
 
204
201
  ### Deleting a resource
205
202
 
@@ -207,19 +204,19 @@ Like creating or updating a resource, there are a few ways deleting a resource c
207
204
 
208
205
  _Delete by the `delete` function with an id_
209
206
 
210
- conn = Ridley.connection(...)
211
- conn.role.delete("reset") => <#Ridley::Role: @name="reset">
207
+ conn = Ridley.new(...)
208
+ conn.role.delete("reset") => <#Ridley::RoleResource: @name="reset">
212
209
 
213
210
  _Delete by the `delete` function with a resource object_
214
211
 
215
- conn = Ridley.connection(...)
212
+ conn = Ridley.new(...)
216
213
  obj = conn.role.find("reset")
217
214
 
218
- conn.role.delete(obj) => <#Ridley::Role: @name="reset">
215
+ conn.role.delete(obj) => <#Ridley::RoleResource: @name="reset">
219
216
 
220
217
  _Delete by the `destroy` function on a resource object_
221
218
 
222
- conn = Ridley.connection(...)
219
+ conn = Ridley.new(...)
223
220
  obj = conn.role.find("reset")
224
221
 
225
222
  obj.destroy => true
@@ -228,21 +225,21 @@ _Delete by the `destroy` function on a resource object_
228
225
 
229
226
  _Regenerate function on a context with an id_
230
227
 
231
- conn = Ridley.connection(...)
232
- conn.client.regenerate_key("jwinsor") => <#Ridley::Client: @name="jwinsor", @private_key="HIDDEN">
228
+ conn = Ridley.new(...)
229
+ conn.client.regenerate_key("jwinsor") => <#Ridley::ClientResource: @name="jwinsor", @private_key="HIDDEN">
233
230
 
234
231
  _Regenerate function on an instantiated resource object_
235
232
 
236
- conn = Ridley.connection(...)
233
+ conn = Ridley.new(...)
237
234
  obj = conn.client.find("jwinsor")
238
235
 
239
- obj.regenerate_key => <#Ridley::Client: @name="jwinsor", @private_key="HIDDEN">
236
+ obj.regenerate_key => <#Ridley::ClientResource: @name="jwinsor", @private_key="HIDDEN">
240
237
 
241
238
  ## Manipulating Data Bags and Data Bag Items
242
239
 
243
240
  A data bag is managed exactly the same as any other Chef resource
244
241
 
245
- conn = Ridley.connection(...)
242
+ conn = Ridley.new(...)
246
243
  conn.data_bag.create("ridley-test")
247
244
 
248
245
  You can create, delete, update, or retrieve a data bag exactly how you would expect if you read through the
@@ -252,15 +249,15 @@ Unlike a role, node, client, or environment, a data bag is a container for other
252
249
 
253
250
  ### Creating a Data Bag Item
254
251
 
255
- conn = Ridley.connection(...)
252
+ conn = Ridley.new(...)
256
253
  data_bag = conn.data_bag.create("ridley-test")
257
254
 
258
255
  data_bag.item.create(id: "appconfig", host: "reset.local", user: "jwinsor") =>
259
- <#Ridley::DataBagItem: @id="appconfig", @host="reset.local", @user="jwinsor">
256
+ <#Ridley::DataBagItemResource: @id="appconfig", @host="reset.local", @user="jwinsor">
260
257
 
261
258
  ### Saving a Data Bag Item
262
259
 
263
- conn = Ridley.connection(...)
260
+ conn = Ridley.new(...)
264
261
  data_bag = conn.data_bag.create("ridley-test")
265
262
 
266
263
  dbi = data_bag.item.new
@@ -270,7 +267,7 @@ Unlike a role, node, client, or environment, a data bag is a container for other
270
267
 
271
268
  ## Searching
272
269
 
273
- conn = Ridley.connection(...)
270
+ conn = Ridley.new(...)
274
271
  conn.search(:node)
275
272
  conn.search(:node, "name:ridley-test.local")
276
273
 
@@ -293,7 +290,7 @@ Given the previous example you could set the default node attribute with the `se
293
290
 
294
291
  Setting the `node[:my_app][:billing][:enabled]` node level attribute on the node "jwinsor-1"
295
292
 
296
- conn = Ridley.connection
293
+ conn = Ridley.new
297
294
  conn.sync do
298
295
  obj = node.find("jwinsor-1")
299
296
  obj.set_attribute("my_app.billing.enabled", false)
@@ -304,7 +301,7 @@ Setting the `node[:my_app][:billing][:enabled]` node level attribute on the node
304
301
 
305
302
  Setting a default environment attribute is just like setting a node level default attribute
306
303
 
307
- conn = Ridley.connection
304
+ conn = Ridley.new
308
305
  conn.sync do
309
306
  obj = environment.find("production")
310
307
  obj.set_default_attribute("my_app.proxy.enabled", false)
@@ -313,7 +310,7 @@ Setting a default environment attribute is just like setting a node level defaul
313
310
 
314
311
  And the same goes for setting an environment level override attribute
315
312
 
316
- conn = Ridley.connection
313
+ conn = Ridley.new
317
314
  conn.sync do
318
315
  obj = environment.find("production")
319
316
  obj.set_override_attribute("my_app.webapp.enabled", false)
@@ -322,7 +319,7 @@ And the same goes for setting an environment level override attribute
322
319
 
323
320
  ### Role Attributes
324
321
 
325
- conn = Ridley.connection
322
+ conn = Ridley.new
326
323
  conn.sync do
327
324
  obj = role.find("why_god_why")
328
325
  obj.set_default_attribute("my_app.proxy.enabled", false)
@@ -337,7 +334,7 @@ And the same goes for setting an environment level override attribute
337
334
 
338
335
  ## Bootstrapping nodes
339
336
 
340
- conn = Ridley.connection(
337
+ conn = Ridley.new(
341
338
  server_url: "https://api.opscode.com",
342
339
  organization: "vialstudios",
343
340
  validator_client: "vialstudios-validator",
@@ -1,5 +1,4 @@
1
1
  require 'chozo'
2
- require 'active_support/core_ext'
3
2
  require 'celluloid'
4
3
  require 'faraday'
5
4
  require 'addressable/uri'
@@ -25,19 +24,13 @@ module Ridley
25
24
  CHEF_VERSION = '10.16.4'.freeze
26
25
 
27
26
  autoload :Bootstrapper, 'ridley/bootstrapper'
28
- autoload :Client, 'ridley/resources/client'
27
+ autoload :Client, 'ridley/client'
29
28
  autoload :Connection, 'ridley/connection'
30
29
  autoload :ChainLink, 'ridley/chain_link'
31
- autoload :Cookbook, 'ridley/resources/cookbook'
32
- autoload :DataBag, 'ridley/resources/data_bag'
33
- autoload :DataBagItem, 'ridley/resources/data_bag_item'
34
30
  autoload :DSL, 'ridley/dsl'
35
- autoload :Environment, 'ridley/resources/environment'
36
31
  autoload :Logging, 'ridley/logging'
37
- autoload :Node, 'ridley/resources/node'
38
32
  autoload :Resource, 'ridley/resource'
39
- autoload :Role, 'ridley/resources/role'
40
- autoload :Search, 'ridley/resources/search'
33
+ autoload :SandboxUploader, 'ridley/sandbox_uploader'
41
34
  autoload :SSH, 'ridley/ssh'
42
35
 
43
36
  class << self
@@ -49,12 +42,12 @@ module Ridley
49
42
  def_delegator "Ridley::Logging", :logger=
50
43
  def_delegator "Ridley::Logging", :set_logger
51
44
 
52
- def connection(*args)
53
- Connection.new(*args)
45
+ def new(*args)
46
+ Client.new(*args)
54
47
  end
55
48
 
56
- def sync(*args, &block)
57
- Connection.sync(*args, &block)
49
+ def open(*args, &block)
50
+ Client.open(*args, &block)
58
51
  end
59
52
 
60
53
  # @return [Pathname]
@@ -67,3 +60,4 @@ end
67
60
  Celluloid.logger = Ridley.logger
68
61
 
69
62
  require 'ridley/middleware'
63
+ require 'ridley/resources'
@@ -0,0 +1,251 @@
1
+ module Ridley
2
+ # @author Jamie Winsor <jamie@vialstudios.com>
3
+ #
4
+ # @example
5
+ # connection = Ridley::Client.new
6
+ # connection.role.all
7
+ #
8
+ # connection.role.find("reset") => Ridley::RoleResource.find(connection, "reset")
9
+ #
10
+ # @example instantiating new resources
11
+ # connection = Ridley::Connection.new
12
+ # connection.role.new(name: "hello") => <#Ridley::RoleResource: @name="hello">
13
+ #
14
+ # New instances of resources can be instantiated by calling new on the Ridley::Context. These messages
15
+ # will be send to the Chef resource's class in Ridley and can be treated as a normal Ruby object. Each
16
+ # instantiated object will have the connection information contained within so you can do things like
17
+ # save a role after changing it's attributes.
18
+ #
19
+ # r = connection.role.new(name: "new-role")
20
+ # r.name => "new-role"
21
+ # r.name = "other-name"
22
+ # r.save
23
+ #
24
+ # connection.role.find("new-role") => <#Ridley::RoleResource: @name="new-role">
25
+ class Client < Celluloid::SupervisionGroup
26
+ class << self
27
+ def open(options = {}, &block)
28
+ cli = new(options)
29
+ cli.evaluate(&block)
30
+ ensure
31
+ cli.terminate if cli && cli.alive?
32
+ end
33
+
34
+ # @raise [ArgumentError]
35
+ #
36
+ # @return [Boolean]
37
+ def validate_options(options)
38
+ missing = (REQUIRED_OPTIONS - options.keys)
39
+
40
+ unless missing.empty?
41
+ missing.collect! { |opt| "'#{opt}'" }
42
+ raise ArgumentError, "Missing required option(s): #{missing.join(', ')}"
43
+ end
44
+
45
+ missing_values = options.slice(*REQUIRED_OPTIONS).select { |key, value| !value.present? }
46
+ unless missing_values.empty?
47
+ values = missing_values.keys.collect { |opt| "'#{opt}'" }
48
+ raise ArgumentError, "Missing value for required option(s): '#{values.join(', ')}'"
49
+ end
50
+ end
51
+ end
52
+
53
+ REQUIRED_OPTIONS = [
54
+ :server_url,
55
+ :client_name,
56
+ :client_key
57
+ ].freeze
58
+
59
+ extend Forwardable
60
+ include Ridley::Logging
61
+
62
+ def_delegator :connection, :build_url
63
+ def_delegator :connection, :scheme
64
+ def_delegator :connection, :host
65
+ def_delegator :connection, :port
66
+ def_delegator :connection, :path_prefix
67
+ def_delegator :connection, :url_prefix
68
+
69
+ def_delegator :connection, :client_key
70
+ def_delegator :connection, :client_key=
71
+ def_delegator :connection, :client_name
72
+ def_delegator :connection, :client_name=
73
+
74
+ attr_accessor :validator_client
75
+ attr_accessor :validator_path
76
+ attr_accessor :encrypted_data_bag_secret_path
77
+ attr_accessor :ssh
78
+
79
+ # @option options [String] :server_url
80
+ # URL to the Chef API
81
+ # @option options [String] :client_name
82
+ # name of the client used to authenticate with the Chef API
83
+ # @option options [String] :client_key
84
+ # filepath to the client's private key used to authenticate with the Chef API
85
+ # @option options [String] :validator_client (nil)
86
+ # @option options [String] :validator_path (nil)
87
+ # @option options [String] :encrypted_data_bag_secret_path (nil)
88
+ # @option options [Hash] :ssh (Hash.new)
89
+ # * :user (String) a shell user that will login to each node and perform the bootstrap command on (required)
90
+ # * :password (String) the password for the shell user that will perform the bootstrap
91
+ # * :keys (Array, String) an array of keys (or a single key) to authenticate the ssh user with instead of a password
92
+ # * :timeout (Float) [5.0] timeout value for SSH bootstrap
93
+ # * :sudo (Boolean) [true] bootstrap with sudo
94
+ # @option options [Hash] :params
95
+ # URI query unencoded key/value pairs
96
+ # @option options [Hash] :headers
97
+ # unencoded HTTP header key/value pairs
98
+ # @option options [Hash] :request
99
+ # request options
100
+ # @option options [Hash] :ssl
101
+ # * :verify (Boolean) [true] set to false to disable SSL verification
102
+ # @option options [URI, String, Hash] :proxy
103
+ # URI, String, or Hash of HTTP proxy options
104
+ def initialize(options = {})
105
+ log.info { "Ridley starting..." }
106
+ options = options.reverse_merge(
107
+ ssh: Hash.new
108
+ ).deep_symbolize_keys
109
+ self.class.validate_options(options)
110
+
111
+ @ssh = options[:ssh]
112
+ @validator_client = options[:validator_client]
113
+
114
+ options[:client_key] = File.expand_path(options[:client_key])
115
+
116
+ if options[:validator_path]
117
+ @validator_path = File.expand_path(options[:validator_path])
118
+ end
119
+
120
+ if options[:encrypted_data_bag_secret_path]
121
+ @encrypted_data_bag_secret_path = File.expand_path(options[:encrypted_data_bag_secret_path])
122
+ end
123
+
124
+ unless options[:client_key].present? && File.exist?(options[:client_key])
125
+ raise Errors::ClientKeyFileNotFound, "client key not found at: '#{options[:client_key]}'"
126
+ end
127
+
128
+ super(Celluloid::Registry.new)
129
+ pool(Ridley::Connection, size: 4, args: [
130
+ options[:server_url],
131
+ options[:client_name],
132
+ options[:client_key],
133
+ options.slice(*Connection::VALID_OPTIONS)
134
+ ], as: :connection_pool)
135
+ end
136
+
137
+ # @return [Ridley::ChainLink]
138
+ def client
139
+ ChainLink.new(Actor.current, Ridley::ClientResource)
140
+ end
141
+
142
+ # @return [Ridley::ChainLink]
143
+ def cookbook
144
+ ChainLink.new(Actor.current, Ridley::CookbookResource)
145
+ end
146
+
147
+ # @return [Ridley::ChainLink]
148
+ def data_bag
149
+ ChainLink.new(Actor.current, Ridley::DataBagResource)
150
+ end
151
+
152
+ # @return [Ridley::ChainLink]
153
+ def environment
154
+ ChainLink.new(Actor.current, Ridley::EnvironmentResource)
155
+ end
156
+
157
+ # @return [Ridley::ChainLink]
158
+ def node
159
+ ChainLink.new(Actor.current, Ridley::NodeResource)
160
+ end
161
+
162
+ # @return [Ridley::ChainLink]
163
+ def role
164
+ ChainLink.new(Actor.current, Ridley::RoleResource)
165
+ end
166
+
167
+ # @return [Ridley::ChainLink]
168
+ def sandbox
169
+ ChainLink.new(Actor.current, Ridley::SandboxResource)
170
+ end
171
+
172
+ # Creates an runs a new Ridley::Search
173
+ #
174
+ # @see Ridley::Search#run
175
+ #
176
+ # @param [String, Symbol] index
177
+ # @param [String, nil] query
178
+ #
179
+ # @option options [String] :sort
180
+ # @option options [Integer] :rows
181
+ # @option options [Integer] :start
182
+ #
183
+ # @return [Hash]
184
+ def search(index, query = nil, options = {})
185
+ Ridley::Search.new(Actor.current, index, query, options).run
186
+ end
187
+
188
+ # Return the array of all possible search indexes for the including connection
189
+ #
190
+ # @example
191
+ # conn = Ridley.new(...)
192
+ # conn.search_indexes =>
193
+ # [:client, :environment, :node, :role, :"ridley-two", :"ridley-one"]
194
+ #
195
+ # @return [Array<Symbol, String>]
196
+ def search_indexes
197
+ Ridley::Search.indexes(Actor.current)
198
+ end
199
+
200
+ # The encrypted data bag secret for this connection.
201
+ #
202
+ # @raise [Ridley::Errors::EncryptedDataBagSecretNotFound]
203
+ #
204
+ # @return [String, nil]
205
+ def encrypted_data_bag_secret
206
+ return nil if encrypted_data_bag_secret_path.nil?
207
+
208
+ IO.read(encrypted_data_bag_secret_path).chomp
209
+ rescue Errno::ENOENT => e
210
+ raise Errors::EncryptedDataBagSecretNotFound, "Encrypted data bag secret provided but not found at '#{encrypted_data_bag_secret_path}'"
211
+ end
212
+
213
+ def server_url
214
+ self.url_prefix.to_s
215
+ end
216
+
217
+ def evaluate(&block)
218
+ unless block_given?
219
+ raise LocalJumpError, "no block given (yield)"
220
+ end
221
+
222
+ @self_before_instance_eval = eval("self", block.binding)
223
+ instance_eval(&block)
224
+ end
225
+ alias_method :sync, :evaluate
226
+
227
+ def finalize
228
+ connection.terminate if connection.alive?
229
+ end
230
+
231
+ def connection
232
+ registry[:connection_pool]
233
+ end
234
+
235
+ private
236
+
237
+ attr_reader :registry
238
+
239
+ def method_missing(method, *args, &block)
240
+ if block_given?
241
+ @self_before_instance_eval ||= eval("self", block.binding)
242
+ end
243
+
244
+ if @self_before_instance_eval.nil?
245
+ super
246
+ end
247
+
248
+ @self_before_instance_eval.send(method, *args, &block)
249
+ end
250
+ end
251
+ end