ridley 0.0.6 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -0
- data/lib/ridley.rb +1 -1
- data/lib/ridley/resources/role.rb +48 -2
- data/lib/ridley/resources/search.rb +32 -4
- data/lib/ridley/version.rb +1 -1
- data/spec/acceptance/search_resource_spec.rb +0 -18
- data/spec/unit/ridley/resources/role_spec.rb +88 -0
- data/spec/unit/ridley/resources/search_spec.rb +153 -1
- metadata +2 -2
data/README.md
CHANGED
@@ -274,6 +274,13 @@ Unlike a role, node, client, or environment, a data bag is a container for other
|
|
274
274
|
conn.search(:node)
|
275
275
|
conn.search(:node, "name:ridley-test.local")
|
276
276
|
|
277
|
+
Search will return an array of Ridley resource objects if one of the default indices is specified. Chef's default indices are
|
278
|
+
|
279
|
+
* node
|
280
|
+
* role
|
281
|
+
* client
|
282
|
+
* environment
|
283
|
+
|
277
284
|
## Manipulating Attributes
|
278
285
|
|
279
286
|
Using Ridley you can quickly manipulate node or environment attributes. Attributes are identified by a dotted path notation.
|
@@ -300,6 +307,7 @@ Other attribute precedence levels can be set with their own respective set attri
|
|
300
307
|
obj = node.find("jwinsor-1")
|
301
308
|
obj.set_override_attribute("my_app.proxy.enabled", false)
|
302
309
|
obj.set_normal_attribute("my_app.webapp.enabled", false)
|
310
|
+
obj.save
|
303
311
|
end
|
304
312
|
|
305
313
|
### Environment Attributes
|
@@ -322,6 +330,21 @@ And the same goes for setting an environment level override attribute
|
|
322
330
|
obj.save
|
323
331
|
end
|
324
332
|
|
333
|
+
### Role Attributes
|
334
|
+
|
335
|
+
conn = Ridley.connection
|
336
|
+
conn.sync do
|
337
|
+
obj = role.find("why_god_why")
|
338
|
+
obj.set_default_attribute("my_app.proxy.enabled", false)
|
339
|
+
obj.save
|
340
|
+
end
|
341
|
+
|
342
|
+
conn.sync do
|
343
|
+
obj = role.find("why_god_why")
|
344
|
+
obj.set_override_attribute("my_app.webapp.enabled", false)
|
345
|
+
obj.save
|
346
|
+
end
|
347
|
+
|
325
348
|
# Authors and Contributors
|
326
349
|
|
327
350
|
* Jamie Winsor (<jamie@vialstudios.com>)
|
data/lib/ridley.rb
CHANGED
@@ -12,10 +12,56 @@ module Ridley
|
|
12
12
|
validates_presence_of :name
|
13
13
|
|
14
14
|
attribute :description, default: String.new
|
15
|
-
attribute :default_attributes, default:
|
16
|
-
attribute :override_attributes, default:
|
15
|
+
attribute :default_attributes, default: HashWithIndifferentAccess.new
|
16
|
+
attribute :override_attributes, default: HashWithIndifferentAccess.new
|
17
17
|
attribute :run_list, default: Array.new
|
18
18
|
attribute :env_run_lists, default: Hash.new
|
19
|
+
|
20
|
+
# @param [Hash] hash
|
21
|
+
def default_attributes=(hash)
|
22
|
+
super(HashWithIndifferentAccess.new(hash))
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Hash] hash
|
26
|
+
def override_attributes=(hash)
|
27
|
+
super(HashWithIndifferentAccess.new(hash))
|
28
|
+
end
|
29
|
+
|
30
|
+
# Set a role level override attribute given the dotted path representation of the Chef
|
31
|
+
# attribute and value
|
32
|
+
#
|
33
|
+
# @example setting and saving a node level override attribute
|
34
|
+
#
|
35
|
+
# obj = node.role("why_god_why")
|
36
|
+
# obj.set_override_attribute("my_app.billing.enabled", false)
|
37
|
+
# obj.save
|
38
|
+
#
|
39
|
+
# @param [String] key
|
40
|
+
# @param [Object] value
|
41
|
+
#
|
42
|
+
# @return [HashWithIndifferentAccess]
|
43
|
+
def set_override_attribute(key, value)
|
44
|
+
attr_hash = HashWithIndifferentAccess.from_dotted_path(key, value)
|
45
|
+
self.override_attributes = self.override_attributes.merge(attr_hash)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Set a role level default attribute given the dotted path representation of the Chef
|
49
|
+
# attribute and value
|
50
|
+
#
|
51
|
+
# @example setting and saving a node level default attribute
|
52
|
+
#
|
53
|
+
# obj = node.role("why_god_why")
|
54
|
+
# obj.set_default_attribute("my_app.billing.enabled", false)
|
55
|
+
# obj.save
|
56
|
+
#
|
57
|
+
# @param [String] key
|
58
|
+
# @param [Object] value
|
59
|
+
#
|
60
|
+
# @return [HashWithIndifferentAccess]
|
61
|
+
def set_default_attribute(key, value)
|
62
|
+
attr_hash = HashWithIndifferentAccess.from_dotted_path(key, value)
|
63
|
+
self.default_attributes = self.default_attributes.merge(attr_hash)
|
64
|
+
end
|
19
65
|
end
|
20
66
|
|
21
67
|
module DSL
|
@@ -3,14 +3,19 @@ module Ridley
|
|
3
3
|
class << self
|
4
4
|
# Returns an array of possible search indexes to be search on
|
5
5
|
#
|
6
|
-
# @param [Ridley::Connection]
|
6
|
+
# @param [Ridley::Connection] connection
|
7
7
|
#
|
8
|
-
# @
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# Search.indexes(connection) => [ :client, :environment, :node, :role ]
|
11
|
+
#
|
12
|
+
# @return [Array<String, Symbol>]
|
9
13
|
def indexes(connection)
|
10
14
|
connection.get("search").body.collect { |name, _| name }
|
11
15
|
end
|
12
16
|
end
|
13
17
|
|
18
|
+
# @return [Ridley::Connection]
|
14
19
|
attr_reader :connection
|
15
20
|
attr_reader :index
|
16
21
|
attr_reader :query
|
@@ -19,9 +24,19 @@ module Ridley
|
|
19
24
|
attr_accessor :rows
|
20
25
|
attr_accessor :start
|
21
26
|
|
27
|
+
# @param [Ridley::Connection] connection
|
28
|
+
# @param [#to_sym] index
|
29
|
+
# @param [#to_s] query
|
30
|
+
#
|
31
|
+
# @option options [String] :sort
|
32
|
+
# a sort string such as 'name DESC'
|
33
|
+
# @option options [Integer] :rows
|
34
|
+
# how many rows to return
|
35
|
+
# @option options [Integer] :start
|
36
|
+
# the result number to start from
|
22
37
|
def initialize(connection, index, query, options = {})
|
23
38
|
@connection = connection
|
24
|
-
@index = index
|
39
|
+
@index = index.to_sym
|
25
40
|
@query = query
|
26
41
|
|
27
42
|
@sort = options[:sort]
|
@@ -53,7 +68,20 @@ module Ridley
|
|
53
68
|
#
|
54
69
|
# @return [Hash]
|
55
70
|
def run
|
56
|
-
connection.get(query_uri, query_options).body
|
71
|
+
response = connection.get(query_uri, query_options).body
|
72
|
+
|
73
|
+
case index
|
74
|
+
when :node
|
75
|
+
response[:rows].collect { |row| Node.new(connection, row) }
|
76
|
+
when :role
|
77
|
+
response[:rows].collect { |row| Role.new(connection, row) }
|
78
|
+
when :client
|
79
|
+
response[:rows].collect { |row| Client.new(connection, row) }
|
80
|
+
when :environment
|
81
|
+
response[:rows].collect { |row| Environment.new(connection, row) }
|
82
|
+
else
|
83
|
+
response[:rows]
|
84
|
+
end
|
57
85
|
end
|
58
86
|
|
59
87
|
private
|
data/lib/ridley/version.rb
CHANGED
@@ -28,24 +28,6 @@ describe "Search API operations", type: "acceptance" do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe "showing an index" do
|
32
|
-
before(:each) do
|
33
|
-
@result = connection.search(:node)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "returns a hash with a total key" do
|
37
|
-
@result.should have_key(:total)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "returns a hash with a start key" do
|
41
|
-
@result.should have_key(:start)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "returns a hash with a rows key" do
|
45
|
-
@result.should have_key(:rows)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
31
|
describe "searching an index that doesn't exist" do
|
50
32
|
it "it raises a Ridley::Errors::HTTPNotFound error" do
|
51
33
|
lambda {
|
@@ -2,4 +2,92 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Ridley::Role do
|
4
4
|
it_behaves_like "a Ridley Resource", Ridley::Role
|
5
|
+
|
6
|
+
let(:connection) { double("connection") }
|
7
|
+
|
8
|
+
subject { Ridley::Role.new(connection) }
|
9
|
+
|
10
|
+
describe "#override_attributes=" do
|
11
|
+
context "given a Hash" do
|
12
|
+
it "returns a HashWithIndifferentAccess" do
|
13
|
+
subject.override_attributes = {
|
14
|
+
"key" => "value"
|
15
|
+
}
|
16
|
+
|
17
|
+
subject.override_attributes.should be_a(HashWithIndifferentAccess)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#default_attributes=" do
|
23
|
+
context "given a Hash" do
|
24
|
+
it "returns a HashWithIndifferentAccess" do
|
25
|
+
subject.default_attributes = {
|
26
|
+
"key" => "value"
|
27
|
+
}
|
28
|
+
|
29
|
+
subject.default_attributes.should be_a(HashWithIndifferentAccess)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#set_override_attribute" do
|
35
|
+
it "returns a HashWithIndifferentAccess" do
|
36
|
+
subject.set_override_attribute('deep.nested.item', true).should be_a(HashWithIndifferentAccess)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sets an override node attribute at the nested path" do
|
40
|
+
subject.set_override_attribute('deep.nested.item', true)
|
41
|
+
|
42
|
+
subject.override_attributes.should have_key("deep")
|
43
|
+
subject.override_attributes["deep"].should have_key("nested")
|
44
|
+
subject.override_attributes["deep"]["nested"].should have_key("item")
|
45
|
+
subject.override_attributes["deep"]["nested"]["item"].should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when the override attribute is already set" do
|
49
|
+
it "test" do
|
50
|
+
subject.override_attributes = {
|
51
|
+
deep: {
|
52
|
+
nested: {
|
53
|
+
item: false
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
subject.set_override_attribute('deep.nested.item', true)
|
58
|
+
|
59
|
+
subject.override_attributes["deep"]["nested"]["item"].should be_true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#set_default_attribute" do
|
65
|
+
it "returns a HashWithIndifferentAccess" do
|
66
|
+
subject.set_default_attribute('deep.nested.item', true).should be_a(HashWithIndifferentAccess)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "sets an override node attribute at the nested path" do
|
70
|
+
subject.set_default_attribute('deep.nested.item', true)
|
71
|
+
|
72
|
+
subject.default_attributes.should have_key("deep")
|
73
|
+
subject.default_attributes["deep"].should have_key("nested")
|
74
|
+
subject.default_attributes["deep"]["nested"].should have_key("item")
|
75
|
+
subject.default_attributes["deep"]["nested"]["item"].should be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when the override attribute is already set" do
|
79
|
+
it "test" do
|
80
|
+
subject.default_attributes = {
|
81
|
+
deep: {
|
82
|
+
nested: {
|
83
|
+
item: false
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
subject.set_default_attribute('deep.nested.item', true)
|
88
|
+
|
89
|
+
subject.default_attributes["deep"]["nested"]["item"].should be_true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
5
93
|
end
|
@@ -4,7 +4,16 @@ describe Ridley::Search do
|
|
4
4
|
let(:connection) { double('connection') }
|
5
5
|
let(:index) { :role }
|
6
6
|
let(:query) { "*:*" }
|
7
|
-
let(:response)
|
7
|
+
let(:response) do
|
8
|
+
double(
|
9
|
+
"response",
|
10
|
+
body: {
|
11
|
+
rows: Array.new,
|
12
|
+
total: 0,
|
13
|
+
start: 0
|
14
|
+
}
|
15
|
+
)
|
16
|
+
end
|
8
17
|
|
9
18
|
describe "ClassMethods" do
|
10
19
|
subject { Ridley::Search }
|
@@ -61,5 +70,148 @@ describe Ridley::Search do
|
|
61
70
|
subject.run
|
62
71
|
end
|
63
72
|
end
|
73
|
+
|
74
|
+
context "when ':node' is given as index" do
|
75
|
+
let(:index) { :node }
|
76
|
+
let(:response) do
|
77
|
+
double(
|
78
|
+
"response",
|
79
|
+
body: {
|
80
|
+
rows: [
|
81
|
+
{
|
82
|
+
chef_type: "node",
|
83
|
+
json_class: "Chef::Node",
|
84
|
+
name: "ridley-one",
|
85
|
+
chef_environment: "_default",
|
86
|
+
automatic: {},
|
87
|
+
normal: {},
|
88
|
+
default: {},
|
89
|
+
override: {},
|
90
|
+
run_list: [
|
91
|
+
"recipe[one]",
|
92
|
+
"recipe[two]"
|
93
|
+
]
|
94
|
+
}
|
95
|
+
],
|
96
|
+
total: 1,
|
97
|
+
start: 0
|
98
|
+
}
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
subject { Ridley::Search.new(connection, index, query) }
|
103
|
+
|
104
|
+
it "returns an array of Ridley::Node" do
|
105
|
+
connection.should_receive(:get).with("search/#{index}", q: query).and_return(response)
|
106
|
+
result = subject.run
|
107
|
+
|
108
|
+
result.should be_a(Array)
|
109
|
+
result.should each be_a(Ridley::Node)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when ':role' is given as index" do
|
114
|
+
let(:index) { :role }
|
115
|
+
let(:response) do
|
116
|
+
double(
|
117
|
+
"response",
|
118
|
+
body: {
|
119
|
+
rows: [
|
120
|
+
{
|
121
|
+
chef_type: "role",
|
122
|
+
json_class: "Chef::Role",
|
123
|
+
name: "ridley-role-one",
|
124
|
+
description: "",
|
125
|
+
default_attributes: {},
|
126
|
+
override_attributes: {},
|
127
|
+
run_list: [],
|
128
|
+
env_run_lists: {}
|
129
|
+
}
|
130
|
+
],
|
131
|
+
total: 1,
|
132
|
+
start: 0
|
133
|
+
}
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
subject { Ridley::Search.new(connection, index, query) }
|
138
|
+
|
139
|
+
it "returns an array of Ridley::Role" do
|
140
|
+
connection.should_receive(:get).with("search/#{index}", q: query).and_return(response)
|
141
|
+
result = subject.run
|
142
|
+
|
143
|
+
result.should be_a(Array)
|
144
|
+
result.should each be_a(Ridley::Role)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "when ':environment' is given as index" do
|
149
|
+
let(:index) { :environment }
|
150
|
+
let(:response) do
|
151
|
+
double(
|
152
|
+
"response",
|
153
|
+
body: {
|
154
|
+
rows: [
|
155
|
+
{
|
156
|
+
chef_type: "environment",
|
157
|
+
json_class: "Chef::Environment",
|
158
|
+
name: "ridley-env-test",
|
159
|
+
description: "ridley testing environment",
|
160
|
+
default_attributes: {},
|
161
|
+
override_attributes: {},
|
162
|
+
cookbook_versions: {}
|
163
|
+
}
|
164
|
+
],
|
165
|
+
total: 1,
|
166
|
+
start: 0
|
167
|
+
}
|
168
|
+
)
|
169
|
+
end
|
170
|
+
|
171
|
+
subject { Ridley::Search.new(connection, index, query) }
|
172
|
+
|
173
|
+
it "returns an array of Ridley::Environment" do
|
174
|
+
connection.should_receive(:get).with("search/#{index}", q: query).and_return(response)
|
175
|
+
result = subject.run
|
176
|
+
|
177
|
+
result.should be_a(Array)
|
178
|
+
result.should each be_a(Ridley::Environment)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "when ':client' is given as index" do
|
183
|
+
let(:index) { :client }
|
184
|
+
let(:response) do
|
185
|
+
double(
|
186
|
+
"response",
|
187
|
+
body: {
|
188
|
+
rows: [
|
189
|
+
{
|
190
|
+
chef_type: "client",
|
191
|
+
name: nil,
|
192
|
+
admin: false,
|
193
|
+
validator: false,
|
194
|
+
certificate: "-----BEGIN CERTIFICATE-----\nMIIDOjCCAqOgAwIBAgIE47eOmDANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC\nVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNV\nBAoMDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2Ux\nMjAwBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUu\nY29tMCAXDTEyMTAwOTAwMTUxNVoYDzIxMDExMTA0MDAxNTE1WjCBnTEQMA4GA1UE\nBxMHU2VhdHRsZTETMBEGA1UECBMKV2FzaGluZ3RvbjELMAkGA1UEBhMCVVMxHDAa\nBgNVBAsTE0NlcnRpZmljYXRlIFNlcnZpY2UxFjAUBgNVBAoTDU9wc2NvZGUsIElu\nYy4xMTAvBgNVBAMUKFVSSTpodHRwOi8vb3BzY29kZS5jb20vR1VJRFMvY2xpZW50\nX2d1aWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqB9KEGzl7Wcm/\nwz/x8HByZANCn6WQC+R12qQso5I6nLbTNkRP668jXG3j0R5/F5i/KearAB9ePzL/\nQe3iHtwW6u1qLI1hVNFNB+I1fGu1p6fZyIOjnLn3bqsbOkBplHOIqHsp4GVSsHKb\nD32UXZDa9S9ZFXnR4iT6hUGm5895ReZG9TDiHvBpi9NJFDZXz+AQ6JuQY8UgYMMA\nm80KbO8/NJlXbRW+siRuvr+LIsi9Mx4i63pBWAN46my291rQU31PF3IB+btfGtR/\nyDWDgMSB37bTzZeOf1Dg9fpl2vIXyu3PoHER0oYmrMQbrdwAt7qCHZNuNWn51WPb\n1PHxXL1rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAGnJUVAv951fUhGyPOrl+LbQG\nqgchMwIn7oDLE863e66BYTDj7koK3jjhx3EBkrT2vt/xS4yW0ZRV1BNqfnNKWbBq\nMNQiKkYdTr+oq2O3plOg/q/M1eG1B5pxGXqvH0O76DVWQcV/svO+HQEi1n8y5UQd\n+pBJCygpuv78wPCM+c4=\n-----END CERTIFICATE-----\n",
|
195
|
+
public_key: nil,
|
196
|
+
private_key: nil,
|
197
|
+
orgname: "ridley"
|
198
|
+
}
|
199
|
+
],
|
200
|
+
total: 1,
|
201
|
+
start: 0
|
202
|
+
}
|
203
|
+
)
|
204
|
+
end
|
205
|
+
|
206
|
+
subject { Ridley::Search.new(connection, index, query) }
|
207
|
+
|
208
|
+
it "returns an array of Ridley::Client" do
|
209
|
+
connection.should_receive(:get).with("search/#{index}", q: query).and_return(response)
|
210
|
+
result = subject.run
|
211
|
+
|
212
|
+
result.should be_a(Array)
|
213
|
+
result.should each be_a(Ridley::Client)
|
214
|
+
end
|
215
|
+
end
|
64
216
|
end
|
65
217
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ridley
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -434,7 +434,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
434
434
|
version: '0'
|
435
435
|
segments:
|
436
436
|
- 0
|
437
|
-
hash:
|
437
|
+
hash: 1428878148981436287
|
438
438
|
requirements: []
|
439
439
|
rubyforge_project:
|
440
440
|
rubygems_version: 1.8.23
|