ridley 0.0.6 → 0.1.0
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.
- 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
|