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.
- data/README.md +51 -54
- data/lib/ridley.rb +7 -13
- data/lib/ridley/client.rb +251 -0
- data/lib/ridley/connection.rb +32 -188
- data/lib/ridley/middleware/chef_auth.rb +4 -1
- data/lib/ridley/resource.rb +36 -42
- data/lib/ridley/resources.rb +3 -0
- data/lib/ridley/resources/{client.rb → client_resource.rb} +7 -20
- data/lib/ridley/resources/cookbook_resource.rb +121 -0
- data/lib/ridley/resources/{data_bag_item.rb → data_bag_item_resource.rb} +52 -63
- data/lib/ridley/resources/data_bag_resource.rb +74 -0
- data/lib/ridley/resources/encrypted_data_bag_item_resource.rb +55 -0
- data/lib/ridley/resources/{environment.rb → environment_resource.rb} +8 -21
- data/lib/ridley/resources/{node.rb → node_resource.rb} +24 -37
- data/lib/ridley/resources/{role.rb → role_resource.rb} +1 -14
- data/lib/ridley/resources/sandbox_resource.rb +86 -0
- data/lib/ridley/resources/search.rb +24 -55
- data/lib/ridley/sandbox_uploader.rb +118 -0
- data/lib/ridley/ssh.rb +2 -2
- data/lib/ridley/ssh/worker.rb +2 -1
- data/lib/ridley/version.rb +1 -1
- data/ridley.gemspec +1 -1
- data/spec/acceptance/bootstrapping_spec.rb +1 -1
- data/spec/acceptance/client_resource_spec.rb +18 -20
- data/spec/acceptance/cookbook_resource_spec.rb +4 -22
- data/spec/acceptance/data_bag_item_resource_spec.rb +5 -7
- data/spec/acceptance/data_bag_resource_spec.rb +4 -6
- data/spec/acceptance/environment_resource_spec.rb +14 -16
- data/spec/acceptance/node_resource_spec.rb +12 -14
- data/spec/acceptance/role_resource_spec.rb +13 -15
- data/spec/acceptance/sandbox_resource_spec.rb +7 -9
- data/spec/acceptance/search_resource_spec.rb +6 -8
- data/spec/support/shared_examples/ridley_resource.rb +23 -22
- data/spec/unit/ridley/client_spec.rb +153 -0
- data/spec/unit/ridley/connection_spec.rb +8 -221
- data/spec/unit/ridley/resources/{client_spec.rb → client_resource_spec.rb} +4 -4
- data/spec/unit/ridley/resources/cookbook_resource_spec.rb +5 -0
- data/spec/unit/ridley/resources/{data_bag_item_spec.rb → data_bag_item_resource_spec.rb} +2 -2
- data/spec/unit/ridley/resources/{data_bag_spec.rb → data_bag_resource_spec.rb} +3 -3
- data/spec/unit/ridley/resources/{environment_spec.rb → environment_resource_spec.rb} +4 -4
- data/spec/unit/ridley/resources/{node_spec.rb → node_resource_spec.rb} +4 -4
- data/spec/unit/ridley/resources/{role_spec.rb → role_resource_spec.rb} +3 -3
- data/spec/unit/ridley/resources/sandbox_resource_spec.rb +172 -0
- data/spec/unit/ridley/resources/search_spec.rb +34 -30
- data/spec/unit/ridley/sandbox_uploader_spec.rb +99 -0
- data/spec/unit/ridley/ssh_spec.rb +2 -2
- data/spec/unit/ridley_spec.rb +4 -12
- metadata +36 -28
- data/lib/ridley/dsl.rb +0 -58
- data/lib/ridley/resources/cookbook.rb +0 -51
- data/lib/ridley/resources/data_bag.rb +0 -81
- data/lib/ridley/resources/encrypted_data_bag_item.rb +0 -54
- data/lib/ridley/resources/sandbox.rb +0 -154
- 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
|
24
|
+
## Creating a new Ridley client
|
25
25
|
|
26
|
-
conn = Ridley
|
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
|
-
|
41
|
+
Connections can also be instantiated by a helper function: `Ridley.new`
|
42
42
|
|
43
|
-
|
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.
|
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.
|
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.
|
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::
|
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.
|
113
|
-
conn.node.all => [<#Ridley::
|
114
|
-
conn.role.all => [<#Ridley::
|
115
|
-
conn.environment.all => [<#Ridley::
|
116
|
-
conn.client.all => [<#Ridley::
|
117
|
-
conn.cookbook.all => [<#Ridley::
|
118
|
-
conn.data_bag.all => [<#Ridley::
|
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.
|
123
|
+
conn = Ridley.new(...)
|
127
124
|
obj = conn.role.new
|
128
125
|
|
129
126
|
obj.name = "reset"
|
130
|
-
obj.save => <#Ridley::
|
127
|
+
obj.save => <#Ridley::RoleResource: @name="reset">
|
131
128
|
|
132
129
|
_Create by the `create` function with attribute hash_
|
133
130
|
|
134
|
-
conn = Ridley.
|
135
|
-
conn.role.create(name: "reset") => <#Ridley::
|
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.
|
136
|
+
conn = Ridley.new(...)
|
140
137
|
obj = conn.role.new
|
141
138
|
|
142
139
|
obj.name = "reset"
|
143
|
-
conn.role.create(obj) => <#Ridley::
|
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.
|
152
|
+
conn = Ridley.new(...)
|
156
153
|
|
157
|
-
conn.role.find("reset") => <#Ridley::
|
158
|
-
conn.role.find!("reset") => <#Ridley::
|
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.
|
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.
|
186
|
-
conn.role.update("reset", description: "testing updates!") => <#Ridley::
|
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.
|
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::
|
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.
|
195
|
+
conn = Ridley.new(...)
|
199
196
|
obj = conn.role.find("reset")
|
200
197
|
|
201
198
|
obj.description = "saving an object!"
|
202
|
-
obj.save => <#Ridley::
|
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.
|
211
|
-
conn.role.delete("reset") => <#Ridley::
|
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.
|
212
|
+
conn = Ridley.new(...)
|
216
213
|
obj = conn.role.find("reset")
|
217
214
|
|
218
|
-
conn.role.delete(obj) => <#Ridley::
|
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.
|
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.
|
232
|
-
conn.client.regenerate_key("jwinsor") => <#Ridley::
|
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.
|
233
|
+
conn = Ridley.new(...)
|
237
234
|
obj = conn.client.find("jwinsor")
|
238
235
|
|
239
|
-
obj.regenerate_key => <#Ridley::
|
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.
|
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.
|
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::
|
256
|
+
<#Ridley::DataBagItemResource: @id="appconfig", @host="reset.local", @user="jwinsor">
|
260
257
|
|
261
258
|
### Saving a Data Bag Item
|
262
259
|
|
263
|
-
conn = Ridley.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
337
|
+
conn = Ridley.new(
|
341
338
|
server_url: "https://api.opscode.com",
|
342
339
|
organization: "vialstudios",
|
343
340
|
validator_client: "vialstudios-validator",
|
data/lib/ridley.rb
CHANGED
@@ -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/
|
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 :
|
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
|
53
|
-
|
45
|
+
def new(*args)
|
46
|
+
Client.new(*args)
|
54
47
|
end
|
55
48
|
|
56
|
-
def
|
57
|
-
|
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
|