rscalr 0.0.1 → 0.0.4
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/.gitignore +5 -0
- data/README.md +49 -2
- data/lib/rscalr/api/scalr.rb +182 -2
- data/lib/rscalr/version.rb +1 -1
- data/rscalr.gemspec +1 -1
- data/test/test_sig.rb +21 -0
- data/test_integration/test_client_farms.rb +41 -0
- metadata +7 -3
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,51 @@
|
|
1
|
-
|
1
|
+
Rscalr
|
2
2
|
======
|
3
3
|
|
4
|
-
Ruby Scalr API implementation
|
4
|
+
Ruby Scalr API implementation.
|
5
|
+
|
6
|
+
Desciption
|
7
|
+
----------
|
8
|
+
|
9
|
+
Rscalr allows your Ops team to build on top of the Scalr API using Ruby. This is particularly beneficial due to the popularity of Chef, a cloud management software suite also written in Ruby.
|
10
|
+
|
11
|
+
Rscalr provides both a low-level client implementation, as well as a more user-friendly domain object layer. Here are some brief examples of how to interact with each API mode.
|
12
|
+
|
13
|
+
Installation
|
14
|
+
------------
|
15
|
+
|
16
|
+
Rscalr is available on RubyGems so installing it is simply:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
gem install rscalr
|
20
|
+
```
|
21
|
+
|
22
|
+
Client Usage
|
23
|
+
------------
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'rscalr'
|
27
|
+
scalr = Scalr.new { :key_id => 'your-key-id', :key_secret => 'your-key-secret' }
|
28
|
+
# list all farms
|
29
|
+
api_response = scalr.farms_list
|
30
|
+
# Response objects exted REXML::Document, so you can work with them easily
|
31
|
+
api_repsonse.write($stdout, 1)
|
32
|
+
```
|
33
|
+
|
34
|
+
Domain Model Usage
|
35
|
+
------------------
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require 'rscalr'
|
39
|
+
scalr = Scalr.new { :key_id => 'your-key-id', :key_secret => 'your-key-secret' }
|
40
|
+
dashboard = Dashboard.new scalr
|
41
|
+
farm = dashboard.get_farm 'my-farm-name'
|
42
|
+
script = dashboard.get_script 'my-script-name'
|
43
|
+
# execute the script on all instances in the farm (see Script.rb for all options)
|
44
|
+
script.execute farm.id
|
45
|
+
```
|
46
|
+
|
47
|
+
|
48
|
+
Caveats
|
49
|
+
-------
|
50
|
+
|
51
|
+
This client library is a work in progress and is not yet complete. Feel free to submit pull requests and/or suggestions. I am not an experienced Rubyist, so if you see anything in the source that makes you cringe, by all means let me know!
|
data/lib/rscalr/api/scalr.rb
CHANGED
@@ -22,10 +22,14 @@ class Scalr
|
|
22
22
|
[[hexdigest].pack("H*")].pack("m0")
|
23
23
|
end
|
24
24
|
|
25
|
+
def generate_timestamp(time)
|
26
|
+
time.strftime("%Y-%m-%dT%H:%M:%SZ")
|
27
|
+
end
|
28
|
+
|
25
29
|
def execute_api_call(action, action_params=nil)
|
26
30
|
|
27
31
|
begin
|
28
|
-
params = { :Action => action, :TimeStamp => Time.now
|
32
|
+
params = { :Action => action, :TimeStamp => generate_timestamp(Time.now) }
|
29
33
|
params.merge!(action_params) unless action_params.nil?
|
30
34
|
|
31
35
|
params[:Signature] = generate_sig(action, params[:TimeStamp])
|
@@ -58,7 +62,7 @@ class Scalr
|
|
58
62
|
result = ScalrResponse.new "<?xml version='1.0?>"
|
59
63
|
result.add_element("Error")
|
60
64
|
ele = REXML::Element.new "TransactionID"
|
61
|
-
ele.text = generate_sig(message, Time.now
|
65
|
+
ele.text = generate_sig(message, generate_timestamp(Time.now))
|
62
66
|
result.root.elements << ele
|
63
67
|
ele = REXML::Element.new "Message"
|
64
68
|
ele.text = message
|
@@ -74,10 +78,149 @@ class Scalr
|
|
74
78
|
|
75
79
|
#=================== API Section ===================================
|
76
80
|
|
81
|
+
def apache_vhost_create(domain_name, farm_id, farm_role_id, document_root_dir, enable_ssl, ssl_private_key=nil, ssl_certificate=nil)
|
82
|
+
params = {
|
83
|
+
:DomainName => domain_name,
|
84
|
+
:FarmID => farm_id,
|
85
|
+
:FarmRoleID => farm_role_id,
|
86
|
+
:DocumentRootDir => document_root_dir,
|
87
|
+
:EnableSSL => enable_ssl
|
88
|
+
}
|
89
|
+
params[:SSLPrivateKey] = ssl_private_key unless ssl_private_key.nil?
|
90
|
+
params[:SSLCertificate] = ssl_certificate unless ssl_certificate.nil?
|
91
|
+
|
92
|
+
execute_api_call('ApacheVhostCreate', params)
|
93
|
+
end
|
94
|
+
|
95
|
+
def apache_vhosts_list
|
96
|
+
execute_api_call('ApacheVhostsList')
|
97
|
+
end
|
98
|
+
|
99
|
+
def bundle_task_get_status(bundle_task_id)
|
100
|
+
params = { :BundleTaskID => bundle_task_id }
|
101
|
+
|
102
|
+
execute_api_call('BundleTaskGetStatus', params)
|
103
|
+
end
|
104
|
+
|
105
|
+
def dm_application_deploy(application_id, farm_role_id, remote_path)
|
106
|
+
params = { :ApplicationID => application_id, :FarmRoleID => farm_role_id, :RemotePath => remote_path }
|
107
|
+
|
108
|
+
execute_api_call('DmApplicationDeploy', params)
|
109
|
+
end
|
110
|
+
|
111
|
+
def dm_applications_list
|
112
|
+
execute_api_call('DmApplicationsList')
|
113
|
+
end
|
114
|
+
|
115
|
+
def dm_sources_list
|
116
|
+
execute_api_call('DmSourcesList')
|
117
|
+
end
|
118
|
+
|
119
|
+
def dns_zone_create(domain_name, farm_id=nil, farm_role_id=nil)
|
120
|
+
params = { :DomainName => domain_name }
|
121
|
+
params[:FarmID] = farm_id unless farm_id.nil?
|
122
|
+
params[:FarmRoleID] = farm_role_id unless farm_role_id.nil?
|
123
|
+
|
124
|
+
execute_api_call('DNSZoneCreate', params)
|
125
|
+
end
|
126
|
+
|
127
|
+
def dns_zone_record_add(zone_name, type, ttl, name, value, priority=nil, weight=nil, port=nil)
|
128
|
+
params = {
|
129
|
+
:ZoneName => zone_name,
|
130
|
+
:Type => type,
|
131
|
+
:TTL => ttl,
|
132
|
+
:Name => name,
|
133
|
+
:Value => value
|
134
|
+
}
|
135
|
+
params[:Priority] = priority unless priority.nil?
|
136
|
+
params[:Weight] = weight unless weight.nil?
|
137
|
+
params[:Port] = port unless port.nil?
|
138
|
+
|
139
|
+
execute_api_call('DNSZoneRecordAdd', params)
|
140
|
+
end
|
141
|
+
|
142
|
+
def dns_zone_record_remove(zone_name, record_id)
|
143
|
+
params = { :ZoneName => zone_name, :RecordID => record_id }
|
144
|
+
|
145
|
+
execute_api_call('DNSZoneRecordRemove', params)
|
146
|
+
end
|
147
|
+
|
148
|
+
def dns_zone_records_list(zone_name)
|
149
|
+
params = { :ZoneName => zone_name }
|
150
|
+
|
151
|
+
execute_api_call('DNSZoneRecordsList', params)
|
152
|
+
end
|
153
|
+
|
154
|
+
def dns_zones_list
|
155
|
+
execute_api_call('DNSZonesList')
|
156
|
+
end
|
157
|
+
|
158
|
+
def environments_list
|
159
|
+
execute_api_call('EnvironmentsList')
|
160
|
+
end
|
161
|
+
|
162
|
+
def events_list(farm_id, start=nil, limit=nil)
|
163
|
+
params = { :FarmID => farm_id }
|
164
|
+
params[:StartFrom] = start unless start.nil?
|
165
|
+
params[:RecordsLimit] = limit unless limit.nil?
|
166
|
+
|
167
|
+
execute_api_call('EventsList', params)
|
168
|
+
end
|
169
|
+
|
170
|
+
def farm_clone(farm_id)
|
171
|
+
params = { :FarmID => farm_id }
|
172
|
+
|
173
|
+
execute_api_call('FarmClone', params)
|
174
|
+
end
|
175
|
+
|
176
|
+
def farm_get_stats(farm_id, date)
|
177
|
+
params = { :FarmID => farm_id }
|
178
|
+
params[:Date] = date.strftime("%m-%Y") unless date.nil?
|
179
|
+
|
180
|
+
execute_api_call('FarmGetStats', params)
|
181
|
+
end
|
182
|
+
|
183
|
+
def farm_launch(farm_id)
|
184
|
+
params = { :FarmID => farm_id }
|
185
|
+
|
186
|
+
execute_api_call('FarmLaunch', params)
|
187
|
+
end
|
188
|
+
|
77
189
|
def farms_list
|
190
|
+
|
78
191
|
execute_api_call('FarmsList')
|
79
192
|
end
|
80
193
|
|
194
|
+
def farm_terminate(farm_id, keep_ebs, keep_eip, keep_dns_zone)
|
195
|
+
params = {
|
196
|
+
:FarmID => farm_id,
|
197
|
+
:KeepEBS => (keep_ebs ? 1 : 0),
|
198
|
+
:KeepEIP => (keep_eip ? 1 : 0),
|
199
|
+
:KeepDNSZone => (keep_dns_zone ? 1 : 0)
|
200
|
+
}
|
201
|
+
|
202
|
+
execute_api_call('FarmTerminate', params)
|
203
|
+
end
|
204
|
+
|
205
|
+
def logs_list(farm_id, server_id=nil, start=nil, limit=nil)
|
206
|
+
params = { :FarmID => farm_id }
|
207
|
+
params[:ServerID] = server_id unless server_id.nil?
|
208
|
+
params[:StartFrom] = start unless start.nil?
|
209
|
+
params[:RecordsLimit] = limit unless limit.nil?
|
210
|
+
|
211
|
+
execute_api_call('LogsList', params)
|
212
|
+
end
|
213
|
+
|
214
|
+
def roles_list(platform=nil, name=nil, prefix=nil, image_id=nil)
|
215
|
+
params = {}
|
216
|
+
params[:Platform] = platform unless platform.nil?
|
217
|
+
params[:Name] = name unless name.nil?
|
218
|
+
params[:Prefix] = prefix unless prefix.nil?
|
219
|
+
params[:ImageID] = image_id unless image_id.nil?
|
220
|
+
|
221
|
+
execute_api_call('RolesList', params)
|
222
|
+
end
|
223
|
+
|
81
224
|
def scripts_list
|
82
225
|
execute_api_call('ScriptsList')
|
83
226
|
end
|
@@ -107,6 +250,32 @@ class Scalr
|
|
107
250
|
execute_api_call('ScriptGetDetails', { :ScriptID => script_id })
|
108
251
|
end
|
109
252
|
|
253
|
+
def server_image_create(server_id, role_name)
|
254
|
+
params = { :ServerID => server_id, :RoleName => role_name }
|
255
|
+
|
256
|
+
execute_api_call('ServerImageCreate', params)
|
257
|
+
end
|
258
|
+
|
259
|
+
def server_launch(farm_role_id, increase_max_instances=nil)
|
260
|
+
params = { :FarmRoleID => farm_role_id }
|
261
|
+
params[:IncreaseMaxInstances] = (increase_max_instances ? 1 : 0) unless increase_max_instances.nil?
|
262
|
+
|
263
|
+
execute_api_call('ServerLaunch', params)
|
264
|
+
end
|
265
|
+
|
266
|
+
def server_reboot(server_id)
|
267
|
+
params = { :ServerID => server_id }
|
268
|
+
|
269
|
+
execute_api_call('ServerReboot', params)
|
270
|
+
end
|
271
|
+
|
272
|
+
def server_terminate(server_id, decrease_min_instances=nil)
|
273
|
+
params = { :ServerID => server_id }
|
274
|
+
params[:DecreaseMinInstancesSetting] = (decrease_min_instances ? 1 : 0) unless decrease_min_instances.nil?
|
275
|
+
|
276
|
+
execute_api_call('ServerTerminate', params)
|
277
|
+
end
|
278
|
+
|
110
279
|
def farm_role_parameters_list(farm_role_id)
|
111
280
|
execute_api_call('FarmRoleParametersList', { :FarmRoleID => farm_role_id })
|
112
281
|
end
|
@@ -123,6 +292,17 @@ class Scalr
|
|
123
292
|
|
124
293
|
execute_api_call('ScriptingLogsList', params)
|
125
294
|
end
|
295
|
+
|
296
|
+
def statistics_get_graph_url(object_type, object_id, watcher_name, graph_type)
|
297
|
+
params = {
|
298
|
+
:ObjectType => object_type,
|
299
|
+
:ObjectID => object_id,
|
300
|
+
:WatcherName => watcher_name,
|
301
|
+
:GraphType => graph_type
|
302
|
+
}
|
303
|
+
|
304
|
+
execute_api_call('StatisticsGetGraphURL', params)
|
305
|
+
end
|
126
306
|
end
|
127
307
|
|
128
308
|
class ScalrResponse < REXML::Document
|
data/lib/rscalr/version.rb
CHANGED
data/rscalr.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.summary = %q{Ruby implementation of the Scalr API}
|
11
11
|
s.description = %q{Rscalr is a Ruby implementation of the Scalr API, written to interface cleanly with Chef and other internal release management tasks.}
|
12
12
|
s.files = `git ls-files`.split("\n")
|
13
|
-
s.test_files = `git ls-files -- {test,
|
13
|
+
s.test_files = `git ls-files -- {test,test_integration}/*`.split("\n")
|
14
14
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
end
|
data/test/test_sig.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rscalr'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestSig < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_generate_timestamp
|
7
|
+
scalr = Scalr.new({ :key_id => '123', :key_secret => '123abc' })
|
8
|
+
time = Time.new(2013, "feb", 3, 22, 36, 01)
|
9
|
+
timestamp = scalr.generate_timestamp time
|
10
|
+
assert_equal '2013-02-03T22:36:01Z', timestamp
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_generate_sig
|
14
|
+
scalr = Scalr.new({ :key_id => '123', :key_secret => '123abc' })
|
15
|
+
time = Time.new(2013, "feb", 3, 22, 36, 01)
|
16
|
+
timestamp = scalr.generate_timestamp time
|
17
|
+
action = 'FarmsList'
|
18
|
+
assert_equal 'XBwijDqKLfCuatAG33SreuL1ftA10L5DZqdTf7mmuII=', scalr.generate_sig(action, timestamp)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rscalr'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
class TestClientFarms < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@scalr = Scalr.new({ :key_id => ENV['SCALR_TEST_API_KEY'], :key_secret => ENV['SCALR_TEST_API_SECRET'] })
|
8
|
+
@farm_test1_name = 'test1'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_list_launch_details_terminate
|
12
|
+
farm_test1_id = nil
|
13
|
+
|
14
|
+
# List
|
15
|
+
api_result = @scalr.farms_list
|
16
|
+
assert(api_result.success?, "FarmsList failed with message #{api_result.error_message}")
|
17
|
+
api_result.root.each_element('FarmSet/Item') do |ele|
|
18
|
+
if ele.elements['Name'].text == @farm_test1_name
|
19
|
+
farm_test1_id = ele.elements['ID'].text.to_i
|
20
|
+
assert ele.elements['Status'].text == '0', "Test Farm 1 is not currently down! Please stop it manually and rerun tests."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
assert_not_nil farm_test1_id, "Test Farm 1 not found!"
|
25
|
+
|
26
|
+
# Launch
|
27
|
+
api_result = @scalr.farm_launch farm_test1_id
|
28
|
+
assert api_result.success?, "FarmLaunch failed with message #{api_result.error_message}"
|
29
|
+
|
30
|
+
# GetDetails
|
31
|
+
api_result = @scalr.farm_get_details farm_test1_id
|
32
|
+
assert api_result.success?, "FarmGetDetails failed with message #{api_result.error_message}"
|
33
|
+
|
34
|
+
sleep(5)
|
35
|
+
|
36
|
+
# Terminate
|
37
|
+
api_result = @scalr.farm_terminate farm_test1_id, false, false, false
|
38
|
+
assert api_result.success?, "FarmTerminate failed with message #{api_result.error_message}"
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rscalr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -31,6 +31,8 @@ files:
|
|
31
31
|
- lib/rscalr/model/server.rb
|
32
32
|
- lib/rscalr/version.rb
|
33
33
|
- rscalr.gemspec
|
34
|
+
- test/test_sig.rb
|
35
|
+
- test_integration/test_client_farms.rb
|
34
36
|
homepage:
|
35
37
|
licenses: []
|
36
38
|
post_install_message:
|
@@ -51,8 +53,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
53
|
version: '0'
|
52
54
|
requirements: []
|
53
55
|
rubyforge_project:
|
54
|
-
rubygems_version: 1.8.
|
56
|
+
rubygems_version: 1.8.25
|
55
57
|
signing_key:
|
56
58
|
specification_version: 3
|
57
59
|
summary: Ruby implementation of the Scalr API
|
58
|
-
test_files:
|
60
|
+
test_files:
|
61
|
+
- test/test_sig.rb
|
62
|
+
- test_integration/test_client_farms.rb
|