ridley 0.7.0.beta → 0.7.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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