cloudstack-cli 0.1.7 → 0.2.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.
- checksums.yaml +7 -0
- data/Gemfile.lock +1 -3
- data/cloudstack-cli.gemspec +0 -1
- data/lib/cloudstack-cli/base.rb +3 -0
- data/lib/cloudstack-cli/cli.rb +5 -0
- data/lib/cloudstack-cli/commands/server.rb +8 -7
- data/lib/cloudstack-cli/helper.rb +6 -2
- data/lib/cloudstack-cli/version.rb +1 -1
- data/lib/cloudstack-client/client.rb +7 -980
- data/lib/cloudstack-client/commands/account.rb +22 -0
- data/lib/cloudstack-client/commands/capacity.rb +19 -0
- data/lib/cloudstack-client/commands/command_template +8 -0
- data/lib/cloudstack-client/commands/disk_offering.rb +49 -0
- data/lib/cloudstack-client/commands/domain.rb +22 -0
- data/lib/cloudstack-client/commands/ip_address.rb +77 -0
- data/lib/cloudstack-client/commands/iso.rb +60 -0
- data/lib/cloudstack-client/commands/load_balancer_rule.rb +61 -0
- data/lib/cloudstack-client/commands/network.rb +101 -0
- data/lib/cloudstack-client/commands/port_forwarding_rule.rb +50 -0
- data/lib/cloudstack-client/commands/project.rb +32 -0
- data/lib/cloudstack-client/commands/router.rb +74 -0
- data/lib/cloudstack-client/commands/server.rb +291 -0
- data/lib/cloudstack-client/commands/service_offering.rb +98 -0
- data/lib/cloudstack-client/commands/template.rb +60 -0
- data/lib/cloudstack-client/commands/volumes.rb +20 -0
- data/lib/cloudstack-client/commands/zone.rb +57 -0
- data/lib/cloudstack-client/helper.rb +2 -2
- data/lib/cloudstack-client/version.rb +3 -0
- data/lib/cloudstack_cli.rb +0 -8
- data/lib/cloudstack_client.rb +2 -2
- metadata +26 -34
- data/config/cloudstack.example.yml +0 -3
- data/lib/cloudstack-client/ssh_command.rb +0 -15
@@ -1,21 +1,3 @@
|
|
1
|
-
# cloudstack-client by Nik Wolfgramm (<nik.wolfgramm@gmail.com.ch>) based on
|
2
|
-
# knife-cloudstack by Ryan Holmes (<rholmes@edmunds.com>), KC Braunschweig (<kcbraunschweig@gmail.com>)
|
3
|
-
#
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
-
# you may not use this file except in compliance with the License.
|
8
|
-
# You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
-
# See the License for the specific language governing permissions and
|
16
|
-
# limitations under the License.
|
17
|
-
#
|
18
|
-
|
19
1
|
require 'base64'
|
20
2
|
require 'openssl'
|
21
3
|
require 'uri'
|
@@ -31,6 +13,13 @@ module CloudstackClient
|
|
31
13
|
@@async_poll_interval = 2.0
|
32
14
|
@@async_timeout = 300
|
33
15
|
|
16
|
+
# include all commands
|
17
|
+
Dir.glob(File.dirname(__FILE__) + "/commands/*.rb").each do |file|
|
18
|
+
require file
|
19
|
+
module_name = File.basename(file, '.rb').split('_').map{|f| f.capitalize}.join
|
20
|
+
include Object.const_get("CloudstackClient::" + module_name)
|
21
|
+
end
|
22
|
+
|
34
23
|
def initialize(api_url, api_key, secret_key)
|
35
24
|
@api_url = api_url
|
36
25
|
@api_key = api_key
|
@@ -38,968 +27,6 @@ module CloudstackClient
|
|
38
27
|
@use_ssl = api_url.start_with? "https"
|
39
28
|
end
|
40
29
|
|
41
|
-
##
|
42
|
-
# Finds the server with the specified name.
|
43
|
-
|
44
|
-
def get_server(name, project_id=nil)
|
45
|
-
params = {
|
46
|
-
'command' => 'listVirtualMachines',
|
47
|
-
'name' => name
|
48
|
-
}
|
49
|
-
params['projectid'] = project_id if project_id
|
50
|
-
json = send_request(params)
|
51
|
-
machines = json['virtualmachine']
|
52
|
-
|
53
|
-
if !machines || machines.empty? then
|
54
|
-
return nil
|
55
|
-
end
|
56
|
-
|
57
|
-
machines.select {|m| m['name'] == name }.first
|
58
|
-
end
|
59
|
-
|
60
|
-
def get_server_state(id)
|
61
|
-
params = {
|
62
|
-
'command' => 'listVirtualMachines',
|
63
|
-
'id' => id
|
64
|
-
}
|
65
|
-
json = send_request(params)
|
66
|
-
machine_state = json['virtualmachine'][0]['state']
|
67
|
-
|
68
|
-
if !machine_state || machine_state.empty? then
|
69
|
-
return nil
|
70
|
-
end
|
71
|
-
|
72
|
-
machine_state
|
73
|
-
end
|
74
|
-
|
75
|
-
def wait_for_server_state(id, state)
|
76
|
-
while get_server_state(id) != state
|
77
|
-
print '..'
|
78
|
-
sleep 5
|
79
|
-
end
|
80
|
-
state
|
81
|
-
end
|
82
|
-
|
83
|
-
##
|
84
|
-
# Finds the public ip for a server
|
85
|
-
|
86
|
-
def get_server_public_ip(server, cached_rules=nil)
|
87
|
-
return nil unless server
|
88
|
-
|
89
|
-
# find the public ip
|
90
|
-
nic = get_server_default_nic(server) || {}
|
91
|
-
if nic['type'] == 'Virtual' then
|
92
|
-
ssh_rule = get_ssh_port_forwarding_rule(server, cached_rules)
|
93
|
-
ssh_rule ? ssh_rule['ipaddress'] : nil
|
94
|
-
else
|
95
|
-
nic['ipaddress']
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
##
|
100
|
-
# Returns the fully qualified domain name for a server.
|
101
|
-
|
102
|
-
def get_server_fqdn(server)
|
103
|
-
return nil unless server
|
104
|
-
|
105
|
-
nic = get_server_default_nic(server) || {}
|
106
|
-
networks = list_networks(project_id: server['projectid']) || {}
|
107
|
-
|
108
|
-
id = nic['networkid']
|
109
|
-
network = networks.select { |net|
|
110
|
-
net['id'] == id
|
111
|
-
}.first
|
112
|
-
return nil unless network
|
113
|
-
|
114
|
-
"#{server['name']}.#{network['networkdomain']}"
|
115
|
-
end
|
116
|
-
|
117
|
-
def get_server_default_nic(server)
|
118
|
-
server['nic'].each do |nic|
|
119
|
-
return nic if nic['isdefault']
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
##
|
124
|
-
# Lists all the servers in your account.
|
125
|
-
|
126
|
-
def list_servers(options = {})
|
127
|
-
params = {
|
128
|
-
'command' => 'listVirtualMachines',
|
129
|
-
'listAll' => true
|
130
|
-
}
|
131
|
-
params['projectid'] = options[:project_id] if options[:project_id]
|
132
|
-
if options[:account]
|
133
|
-
if account = list_accounts({name: options[:account]}).first
|
134
|
-
params['domainid'] = account["domainid"]
|
135
|
-
params['account'] = options[:account]
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
json = send_request(params)
|
140
|
-
json['virtualmachine'] || []
|
141
|
-
end
|
142
|
-
|
143
|
-
##
|
144
|
-
# Deploys a new server using the specified parameters.
|
145
|
-
|
146
|
-
def create_server(host_name, service_name, template_name, zone_name=nil,
|
147
|
-
network_names=[], project_name=nil, disk_offering=nil, hypervisor=nil)
|
148
|
-
if host_name then
|
149
|
-
if get_server(host_name) then
|
150
|
-
puts "Error: Server '#{host_name}' already exists."
|
151
|
-
exit 1
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
service = get_service_offering(service_name)
|
156
|
-
if !service then
|
157
|
-
puts "Error: Service offering '#{service_name}' is invalid"
|
158
|
-
exit 1
|
159
|
-
end
|
160
|
-
|
161
|
-
template = get_template(template_name)
|
162
|
-
if !template then
|
163
|
-
template = get_iso(template_name)
|
164
|
-
if !template then
|
165
|
-
puts "Error: Template '#{template_name}' is invalid"
|
166
|
-
exit 1
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
zone = zone_name ? get_zone(zone_name) : get_default_zone
|
171
|
-
if !zone then
|
172
|
-
msg = zone_name ? "Zone '#{zone_name}' is invalid" : "No default zone found"
|
173
|
-
puts "Error: #{msg}"
|
174
|
-
exit 1
|
175
|
-
end
|
176
|
-
|
177
|
-
if project_name
|
178
|
-
project = get_project(project_name)
|
179
|
-
if !project then
|
180
|
-
msg = "Project '#{project_name}' is invalid"
|
181
|
-
puts "Error: #{msg}"
|
182
|
-
exit 1
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
networks = []
|
187
|
-
network_names.each do |name|
|
188
|
-
network = project_name ? get_network(name, project['id']) : get_network(name)
|
189
|
-
if !network then
|
190
|
-
puts "Error: Network '#{name}' not found"
|
191
|
-
exit 1
|
192
|
-
end
|
193
|
-
networks << network
|
194
|
-
end
|
195
|
-
if networks.empty? then
|
196
|
-
networks << get_default_network
|
197
|
-
end
|
198
|
-
if networks.empty? then
|
199
|
-
puts "No default network found"
|
200
|
-
exit 1
|
201
|
-
end
|
202
|
-
network_ids = networks.map { |network|
|
203
|
-
network['id']
|
204
|
-
}
|
205
|
-
|
206
|
-
if disk_offering
|
207
|
-
disk_offering = get_disk_offering(disk_offering)
|
208
|
-
unless disk_offering
|
209
|
-
msg = zone_name ? "Zone '#{zone_name}' is invalid" : "No default zone found"
|
210
|
-
puts "Error: #{msg}"
|
211
|
-
exit 1
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
params = {
|
217
|
-
'command' => 'deployVirtualMachine',
|
218
|
-
'serviceOfferingId' => service['id'],
|
219
|
-
'templateId' => template['id'],
|
220
|
-
'zoneId' => zone['id'],
|
221
|
-
'networkids' => network_ids.join(',')
|
222
|
-
}
|
223
|
-
params['name'] = host_name if host_name
|
224
|
-
params['projectid'] = project['id'] if project_name
|
225
|
-
params['diskofferingid'] = disk_offering['id'] if disk_offering
|
226
|
-
params['hypervisor'] = hypervisor || 'vmware' if disk_offering
|
227
|
-
|
228
|
-
json = send_async_request(params)
|
229
|
-
json['virtualmachine']
|
230
|
-
end
|
231
|
-
|
232
|
-
##
|
233
|
-
# Stops the server with the specified name.
|
234
|
-
#
|
235
|
-
|
236
|
-
def stop_server(name, forced=nil)
|
237
|
-
server = get_server(name)
|
238
|
-
if !server || !server['id'] then
|
239
|
-
puts "Error: Virtual machine '#{name}' does not exist"
|
240
|
-
exit 1
|
241
|
-
end
|
242
|
-
|
243
|
-
params = {
|
244
|
-
'command' => 'stopVirtualMachine',
|
245
|
-
'id' => server['id']
|
246
|
-
}
|
247
|
-
params['forced'] = true if forced
|
248
|
-
|
249
|
-
json = send_async_request(params)
|
250
|
-
json['virtualmachine']
|
251
|
-
end
|
252
|
-
|
253
|
-
##
|
254
|
-
# Start the server with the specified name.
|
255
|
-
#
|
256
|
-
|
257
|
-
def start_server(name)
|
258
|
-
server = get_server(name)
|
259
|
-
if !server || !server['id'] then
|
260
|
-
puts "Error: Virtual machine '#{name}' does not exist"
|
261
|
-
exit 1
|
262
|
-
end
|
263
|
-
|
264
|
-
params = {
|
265
|
-
'command' => 'startVirtualMachine',
|
266
|
-
'id' => server['id']
|
267
|
-
}
|
268
|
-
|
269
|
-
json = send_async_request(params)
|
270
|
-
json['virtualmachine']
|
271
|
-
end
|
272
|
-
|
273
|
-
##
|
274
|
-
# Reboot the server with the specified name.
|
275
|
-
#
|
276
|
-
|
277
|
-
def reboot_server(name)
|
278
|
-
server = get_server(name)
|
279
|
-
if !server || !server['id'] then
|
280
|
-
puts "Error: Virtual machine '#{name}' does not exist"
|
281
|
-
exit 1
|
282
|
-
end
|
283
|
-
|
284
|
-
params = {
|
285
|
-
'command' => 'rebootVirtualMachine',
|
286
|
-
'id' => server['id']
|
287
|
-
}
|
288
|
-
|
289
|
-
json = send_async_request(params)
|
290
|
-
json['virtualmachine']
|
291
|
-
end
|
292
|
-
|
293
|
-
##
|
294
|
-
# Destroy the server with the specified name.
|
295
|
-
#
|
296
|
-
|
297
|
-
def destroy_server(id)
|
298
|
-
params = {
|
299
|
-
'command' => 'destroyVirtualMachine',
|
300
|
-
'id' => id
|
301
|
-
}
|
302
|
-
|
303
|
-
json = send_async_request(params)
|
304
|
-
json['virtualmachine']
|
305
|
-
end
|
306
|
-
|
307
|
-
##
|
308
|
-
# Finds the service offering with the specified name.
|
309
|
-
|
310
|
-
def get_service_offering(name)
|
311
|
-
|
312
|
-
# TODO: use name parameter
|
313
|
-
# listServiceOfferings in CloudStack 2.2 doesn't seem to work
|
314
|
-
# when the name parameter is specified. When this is fixed,
|
315
|
-
# the name parameter should be added to the request.
|
316
|
-
params = {
|
317
|
-
'command' => 'listServiceOfferings'
|
318
|
-
}
|
319
|
-
json = send_request(params)
|
320
|
-
|
321
|
-
services = json['serviceoffering']
|
322
|
-
return nil unless services
|
323
|
-
|
324
|
-
services.each { |s|
|
325
|
-
if s['name'] == name then
|
326
|
-
return s
|
327
|
-
end
|
328
|
-
}
|
329
|
-
nil
|
330
|
-
end
|
331
|
-
|
332
|
-
##
|
333
|
-
# Lists all available service offerings.
|
334
|
-
|
335
|
-
def list_service_offerings(domain = nil)
|
336
|
-
params = {
|
337
|
-
'command' => 'listServiceOfferings'
|
338
|
-
}
|
339
|
-
|
340
|
-
if domain
|
341
|
-
params['domainid'] = list_domains(domain).first["id"]
|
342
|
-
end
|
343
|
-
|
344
|
-
json = send_request(params)
|
345
|
-
json['serviceoffering'] || []
|
346
|
-
end
|
347
|
-
|
348
|
-
##
|
349
|
-
# Create a service offering.
|
350
|
-
|
351
|
-
def create_offering(args)
|
352
|
-
params = {
|
353
|
-
'command' => 'createServiceOffering',
|
354
|
-
'name' => args[:name],
|
355
|
-
'cpunumber' => args[:cpunumber],
|
356
|
-
'cpuspeed' => args[:cpuspeed],
|
357
|
-
'displaytext' => args[:displaytext],
|
358
|
-
'memory' => args[:memory]
|
359
|
-
}
|
360
|
-
|
361
|
-
if args['domain']
|
362
|
-
params['domainid'] = list_domains(args['domain']).first["id"]
|
363
|
-
end
|
364
|
-
|
365
|
-
params['tags'] = args[:tags] if args[:tags]
|
366
|
-
params['offerha'] = 'true' if args[:ha]
|
367
|
-
|
368
|
-
json = send_request(params)
|
369
|
-
json['serviceoffering'].first
|
370
|
-
end
|
371
|
-
|
372
|
-
##
|
373
|
-
# Delete a service offering.
|
374
|
-
|
375
|
-
def delete_offering(id)
|
376
|
-
params = {
|
377
|
-
'command' => 'deleteServiceOffering',
|
378
|
-
'id' => id
|
379
|
-
}
|
380
|
-
|
381
|
-
json = send_request(params)
|
382
|
-
json['success']
|
383
|
-
end
|
384
|
-
|
385
|
-
def update_offering(args)
|
386
|
-
params = {
|
387
|
-
'command' => 'updateServiceOffering',
|
388
|
-
'id' => args['id']
|
389
|
-
}
|
390
|
-
params['name'] = args['name'] if args['name']
|
391
|
-
params['displaytext'] = args['displaytext'] if args['displaytext']
|
392
|
-
params['sortkey'] = args['sortkey'] if args['sortkey']
|
393
|
-
|
394
|
-
json = send_request(params)
|
395
|
-
json['serviceoffering']
|
396
|
-
end
|
397
|
-
|
398
|
-
##
|
399
|
-
# Lists all available disk offerings.
|
400
|
-
|
401
|
-
def list_disk_offerings(domain = nil)
|
402
|
-
params = {
|
403
|
-
'command' => 'listDiskOfferings'
|
404
|
-
}
|
405
|
-
|
406
|
-
if domain
|
407
|
-
params['domainid'] = list_domains(domain).first["id"]
|
408
|
-
end
|
409
|
-
|
410
|
-
json = send_request(params)
|
411
|
-
json['diskoffering'] || []
|
412
|
-
end
|
413
|
-
|
414
|
-
##
|
415
|
-
# Get disk offering by name.
|
416
|
-
|
417
|
-
def get_disk_offering(name)
|
418
|
-
|
419
|
-
# TODO: use name parameter
|
420
|
-
# listServiceOfferings in CloudStack 2.2 doesn't seem to work
|
421
|
-
# when the name parameter is specified. When this is fixed,
|
422
|
-
# the name parameter should be added to the request.
|
423
|
-
params = {
|
424
|
-
'command' => 'listDiskOfferings'
|
425
|
-
}
|
426
|
-
json = send_request(params)
|
427
|
-
|
428
|
-
services = json['diskoffering']
|
429
|
-
return nil unless services
|
430
|
-
|
431
|
-
services.each { |s|
|
432
|
-
if s['name'] == name then
|
433
|
-
return s
|
434
|
-
end
|
435
|
-
}
|
436
|
-
nil
|
437
|
-
end
|
438
|
-
|
439
|
-
##
|
440
|
-
# Finds the template with the specified name.
|
441
|
-
|
442
|
-
def get_template(name)
|
443
|
-
|
444
|
-
# TODO: use name parameter
|
445
|
-
# listTemplates in CloudStack 2.2 doesn't seem to work
|
446
|
-
# when the name parameter is specified. When this is fixed,
|
447
|
-
# the name parameter should be added to the request.
|
448
|
-
params = {
|
449
|
-
'command' => 'listTemplates',
|
450
|
-
'templateFilter' => 'executable'
|
451
|
-
}
|
452
|
-
json = send_request(params)
|
453
|
-
|
454
|
-
templates = json['template']
|
455
|
-
if !templates then
|
456
|
-
return nil
|
457
|
-
end
|
458
|
-
|
459
|
-
templates.each { |t|
|
460
|
-
if t['name'] == name then
|
461
|
-
return t
|
462
|
-
end
|
463
|
-
}
|
464
|
-
|
465
|
-
nil
|
466
|
-
end
|
467
|
-
|
468
|
-
##
|
469
|
-
# Lists all templates that match the specified filter.
|
470
|
-
#
|
471
|
-
# Allowable filter values are:
|
472
|
-
#
|
473
|
-
# * featured - templates that are featured and are public
|
474
|
-
# * self - templates that have been registered/created by the owner
|
475
|
-
# * self-executable - templates that have been registered/created by the owner that can be used to deploy a new VM
|
476
|
-
# * executable - all templates that can be used to deploy a new VM
|
477
|
-
# * community - templates that are public
|
478
|
-
|
479
|
-
def list_templates(args = {})
|
480
|
-
filter = args[:filter] || 'featured'
|
481
|
-
params = {
|
482
|
-
'command' => 'listTemplates',
|
483
|
-
'templateFilter' => filter
|
484
|
-
}
|
485
|
-
params['projectid'] = args[:project_id] if args[:project_id]
|
486
|
-
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
487
|
-
|
488
|
-
json = send_request(params)
|
489
|
-
json['template'] || []
|
490
|
-
end
|
491
|
-
|
492
|
-
##
|
493
|
-
# Lists all isos that match the specified filter.
|
494
|
-
#
|
495
|
-
# Allowable filter values are:
|
496
|
-
#
|
497
|
-
# * featured - isos that are featured and are public
|
498
|
-
# * self - isos that have been registered/created by the owner
|
499
|
-
# * self-executable - isos that have been registered/created by the owner that can be used to deploy a new VM
|
500
|
-
# * executable - all isos that can be used to deploy a new VM
|
501
|
-
# * community - isos that are public
|
502
|
-
|
503
|
-
def list_isos(args = {})
|
504
|
-
filter = args[:filter] || 'featured'
|
505
|
-
params = {
|
506
|
-
'command' => 'listIsos',
|
507
|
-
'templateFilter' => filter
|
508
|
-
}
|
509
|
-
params['projectid'] = args[:project_id] if args[:project_id]
|
510
|
-
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
511
|
-
|
512
|
-
json = send_request(params)
|
513
|
-
json['iso'] || []
|
514
|
-
end
|
515
|
-
|
516
|
-
##
|
517
|
-
# Finds the template with the specified name.
|
518
|
-
|
519
|
-
def get_iso(name)
|
520
|
-
|
521
|
-
# TODO: use name parameter
|
522
|
-
# listIsos in CloudStack 2.2 doesn't seem to work
|
523
|
-
# when the name parameter is specified. When this is fixed,
|
524
|
-
# the name parameter should be added to the request.
|
525
|
-
params = {
|
526
|
-
'command' => 'listIsos',
|
527
|
-
'templateFilter' => 'executable'
|
528
|
-
}
|
529
|
-
json = send_request(params)
|
530
|
-
|
531
|
-
isos = json['iso']
|
532
|
-
if !isos then
|
533
|
-
return nil
|
534
|
-
end
|
535
|
-
|
536
|
-
isos.each { |t|
|
537
|
-
if t['name'] == name then
|
538
|
-
return t
|
539
|
-
end
|
540
|
-
}
|
541
|
-
|
542
|
-
nil
|
543
|
-
end
|
544
|
-
|
545
|
-
##
|
546
|
-
# Finds the network with the specified name.
|
547
|
-
|
548
|
-
def get_network(name, project_id = nil)
|
549
|
-
params = {
|
550
|
-
'command' => 'listNetworks',
|
551
|
-
'listall' => true
|
552
|
-
}
|
553
|
-
params['projectid'] = project_id if project_id
|
554
|
-
json = send_request(params)
|
555
|
-
|
556
|
-
networks = json['network']
|
557
|
-
return nil unless networks
|
558
|
-
|
559
|
-
networks.each { |n|
|
560
|
-
if n['name'] == name then
|
561
|
-
return n
|
562
|
-
end
|
563
|
-
}
|
564
|
-
nil
|
565
|
-
end
|
566
|
-
|
567
|
-
##
|
568
|
-
# Finds the default network.
|
569
|
-
|
570
|
-
def get_default_network(zone = nil)
|
571
|
-
params = {
|
572
|
-
'command' => 'listNetworks',
|
573
|
-
'isDefault' => true
|
574
|
-
}
|
575
|
-
if zone
|
576
|
-
params['zoneid'] = get_zone(zone)['id']
|
577
|
-
end
|
578
|
-
json = send_request(params)
|
579
|
-
|
580
|
-
networks = json['network']
|
581
|
-
return nil if !networks || networks.empty?
|
582
|
-
return networks.first if networks.length == 1
|
583
|
-
|
584
|
-
networks.each { |n|
|
585
|
-
if n['type'] == 'Direct' then
|
586
|
-
return n
|
587
|
-
end
|
588
|
-
}
|
589
|
-
nil
|
590
|
-
end
|
591
|
-
|
592
|
-
##
|
593
|
-
# Lists all available networks.
|
594
|
-
|
595
|
-
def list_networks(args = {})
|
596
|
-
params = {
|
597
|
-
'command' => 'listNetworks',
|
598
|
-
'listall' => true,
|
599
|
-
}
|
600
|
-
params['projectid'] = args[:project_id] if args[:project_id]
|
601
|
-
params['zoneid'] = args[:zone_id] if args[:zone_id]
|
602
|
-
params['isDefault'] = true if args[:isdefault]
|
603
|
-
if args[:account]
|
604
|
-
domain = list_accounts(name: args[:account])
|
605
|
-
if domain.size > 0
|
606
|
-
params['account'] = args[:account]
|
607
|
-
params['domainid'] = domain.first["domainid"]
|
608
|
-
else
|
609
|
-
puts "Account #{args[:account]} not found."
|
610
|
-
end
|
611
|
-
end
|
612
|
-
json = send_request(params)
|
613
|
-
json['network'] || []
|
614
|
-
end
|
615
|
-
|
616
|
-
##
|
617
|
-
# Delete network.
|
618
|
-
|
619
|
-
def delete_network(id)
|
620
|
-
params = {
|
621
|
-
'command' => 'deleteNetwork',
|
622
|
-
'id' => id,
|
623
|
-
}
|
624
|
-
p json = send_async_request(params)
|
625
|
-
json['network']
|
626
|
-
end
|
627
|
-
|
628
|
-
##
|
629
|
-
# Lists all physical networks.
|
630
|
-
|
631
|
-
def list_physical_networks
|
632
|
-
params = {
|
633
|
-
'command' => 'listPhysicalNetworks',
|
634
|
-
}
|
635
|
-
json = send_request(params)
|
636
|
-
json['physicalnetwork'] || []
|
637
|
-
end
|
638
|
-
|
639
|
-
##
|
640
|
-
# Lists all volumes.
|
641
|
-
|
642
|
-
def list_volumes(project_id = nil)
|
643
|
-
params = {
|
644
|
-
'command' => 'listVolumes',
|
645
|
-
'listall' => true,
|
646
|
-
}
|
647
|
-
params['projectid'] = project_id if project_id
|
648
|
-
json = send_request(params)
|
649
|
-
json['network'] || []
|
650
|
-
end
|
651
|
-
|
652
|
-
##
|
653
|
-
# Finds the zone with the specified name.
|
654
|
-
|
655
|
-
def get_zone(name)
|
656
|
-
params = {
|
657
|
-
'command' => 'listZones',
|
658
|
-
'available' => 'true'
|
659
|
-
}
|
660
|
-
json = send_request(params)
|
661
|
-
|
662
|
-
networks = json['zone']
|
663
|
-
return nil unless networks
|
664
|
-
|
665
|
-
networks.each { |z|
|
666
|
-
if z['name'] == name then
|
667
|
-
return z
|
668
|
-
end
|
669
|
-
}
|
670
|
-
|
671
|
-
nil
|
672
|
-
end
|
673
|
-
|
674
|
-
##
|
675
|
-
# Finds the default zone for your account.
|
676
|
-
|
677
|
-
def get_default_zone
|
678
|
-
params = {
|
679
|
-
'command' => 'listZones',
|
680
|
-
'available' => 'true'
|
681
|
-
}
|
682
|
-
json = send_request(params)
|
683
|
-
|
684
|
-
zones = json['zone']
|
685
|
-
return nil unless zones
|
686
|
-
|
687
|
-
zones.first
|
688
|
-
end
|
689
|
-
|
690
|
-
##
|
691
|
-
# Lists all available zones.
|
692
|
-
|
693
|
-
def list_zones
|
694
|
-
params = {
|
695
|
-
'command' => 'listZones',
|
696
|
-
'available' => 'true'
|
697
|
-
}
|
698
|
-
json = send_request(params)
|
699
|
-
json['zone'] || []
|
700
|
-
end
|
701
|
-
|
702
|
-
##
|
703
|
-
# Lists the public ip addresses.
|
704
|
-
|
705
|
-
def list_public_ip_addresses(args = {})
|
706
|
-
params = {
|
707
|
-
'command' => 'listPublicIpAddresses',
|
708
|
-
'isrecursive' => true
|
709
|
-
}
|
710
|
-
if args[:project]
|
711
|
-
project = get_project(args[:project])
|
712
|
-
params['projectid'] = project['id']
|
713
|
-
end
|
714
|
-
if args[:account]
|
715
|
-
account = list_accounts({name: args[:account]}).first
|
716
|
-
unless account
|
717
|
-
puts "Error: Account #{args[:account]} not found."
|
718
|
-
exit 1
|
719
|
-
end
|
720
|
-
params['domainid'] = account["domainid"]
|
721
|
-
params['account'] = args[:account]
|
722
|
-
end
|
723
|
-
params['listall'] = args[:listall] if args[:listall]
|
724
|
-
|
725
|
-
json = send_request(params)
|
726
|
-
json['publicipaddress'] || []
|
727
|
-
end
|
728
|
-
|
729
|
-
##
|
730
|
-
# Finds the public ip address for a given ip address string.
|
731
|
-
|
732
|
-
def get_public_ip_address(ip_address)
|
733
|
-
params = {
|
734
|
-
'command' => 'listPublicIpAddresses',
|
735
|
-
'ipaddress' => ip_address
|
736
|
-
}
|
737
|
-
json = send_request(params)
|
738
|
-
ip_address = json['publicipaddress']
|
739
|
-
|
740
|
-
return nil unless ip_address
|
741
|
-
ip_address.first
|
742
|
-
end
|
743
|
-
|
744
|
-
|
745
|
-
##
|
746
|
-
# Acquires and associates a public IP to an account.
|
747
|
-
|
748
|
-
def associate_ip_address(network_id)
|
749
|
-
params = {
|
750
|
-
'command' => 'associateIpAddress',
|
751
|
-
'networkid' => network_id
|
752
|
-
}
|
753
|
-
|
754
|
-
json = send_async_request(params)
|
755
|
-
json['ipaddress']
|
756
|
-
end
|
757
|
-
|
758
|
-
##
|
759
|
-
# Disassociates an ip address from the account.
|
760
|
-
#
|
761
|
-
# Returns true if successful, false otherwise.
|
762
|
-
|
763
|
-
def disassociate_ip_address(id)
|
764
|
-
params = {
|
765
|
-
'command' => 'disassociateIpAddress',
|
766
|
-
'id' => id
|
767
|
-
}
|
768
|
-
json = send_async_request(params)
|
769
|
-
json['success']
|
770
|
-
end
|
771
|
-
|
772
|
-
##
|
773
|
-
# Lists all port forwarding rules.
|
774
|
-
|
775
|
-
def list_port_forwarding_rules(ip_address_id=nil, project_id)
|
776
|
-
params = {
|
777
|
-
'command' => 'listPortForwardingRules',
|
778
|
-
'listall' => true,
|
779
|
-
'isrecursive' => true
|
780
|
-
}
|
781
|
-
params['ipAddressId'] = ip_address_id if ip_address_id
|
782
|
-
params['projectid'] = project_id if project_id
|
783
|
-
json = send_request(params)
|
784
|
-
json['portforwardingrule'] || []
|
785
|
-
end
|
786
|
-
|
787
|
-
##
|
788
|
-
# Gets the SSH port forwarding rule for the specified server.
|
789
|
-
|
790
|
-
def get_ssh_port_forwarding_rule(server, cached_rules=nil)
|
791
|
-
rules = cached_rules || list_port_forwarding_rules || []
|
792
|
-
rules.find_all { |r|
|
793
|
-
r['virtualmachineid'] == server['id'] &&
|
794
|
-
r['privateport'] == '22'&&
|
795
|
-
r['publicport'] == '22'
|
796
|
-
}.first
|
797
|
-
end
|
798
|
-
|
799
|
-
##
|
800
|
-
# Creates a port forwarding rule.
|
801
|
-
|
802
|
-
def create_port_forwarding_rule(ip_address_id, private_port, protocol, public_port, virtual_machine_id)
|
803
|
-
params = {
|
804
|
-
'command' => 'createPortForwardingRule',
|
805
|
-
'ipAddressId' => ip_address_id,
|
806
|
-
'privatePort' => private_port,
|
807
|
-
'protocol' => protocol,
|
808
|
-
'publicPort' => public_port,
|
809
|
-
'virtualMachineId' => virtual_machine_id
|
810
|
-
}
|
811
|
-
json = send_async_request(params)
|
812
|
-
json['portforwardingrule']
|
813
|
-
end
|
814
|
-
|
815
|
-
##
|
816
|
-
# Get project by name.
|
817
|
-
|
818
|
-
def get_project(name)
|
819
|
-
params = {
|
820
|
-
'command' => 'listProjects',
|
821
|
-
'name' => name,
|
822
|
-
'listall' => true,
|
823
|
-
}
|
824
|
-
json = send_request(params)
|
825
|
-
json['project'] ? json['project'].first : nil
|
826
|
-
end
|
827
|
-
|
828
|
-
##
|
829
|
-
# Lists projects.
|
830
|
-
|
831
|
-
def list_projects
|
832
|
-
params = {
|
833
|
-
'command' => 'listProjects',
|
834
|
-
'listall' => true,
|
835
|
-
}
|
836
|
-
json = send_request(params)
|
837
|
-
json['project'] || []
|
838
|
-
end
|
839
|
-
|
840
|
-
##
|
841
|
-
# List loadbalancer rules
|
842
|
-
|
843
|
-
def list_load_balancer_rules(options = {})
|
844
|
-
params = {
|
845
|
-
'command' => 'listLoadBalancerRules',
|
846
|
-
}
|
847
|
-
params['name'] = options[:name] if options[:name]
|
848
|
-
|
849
|
-
if options[:project_name]
|
850
|
-
project = get_project(options[:project_name])
|
851
|
-
params['projectid'] = project['id']
|
852
|
-
end
|
853
|
-
|
854
|
-
json = send_request(params)
|
855
|
-
json['loadbalancerrule'] || []
|
856
|
-
end
|
857
|
-
|
858
|
-
##
|
859
|
-
# Creates a load balancing rule.
|
860
|
-
|
861
|
-
def create_load_balancer_rule(name, publicip, private_port, public_port, options = {})
|
862
|
-
params = {
|
863
|
-
'command' => 'createLoadBalancerRule',
|
864
|
-
'name' => name,
|
865
|
-
'privateport' => private_port,
|
866
|
-
'publicport' => public_port,
|
867
|
-
'publicipid' => get_public_ip_address(publicip)['id']
|
868
|
-
}
|
869
|
-
params['algorithm'] = options[:algorithm] || 'roundrobin'
|
870
|
-
params['openfirewall'] = options[:openfirewall] || true
|
871
|
-
|
872
|
-
json = send_async_request(params)
|
873
|
-
json['LoadBalancerRule']
|
874
|
-
end
|
875
|
-
|
876
|
-
##
|
877
|
-
# Assigns virtual machine or a list of virtual machines to a load balancer rule.
|
878
|
-
|
879
|
-
def assign_to_load_balancer_rule(name, vm_names)
|
880
|
-
id = list_load_balancer_rules(name).first['id']
|
881
|
-
|
882
|
-
vm_ids = vm_names.map do |vm|
|
883
|
-
get_server(vm)['id']
|
884
|
-
end
|
885
|
-
|
886
|
-
params = {
|
887
|
-
'command' => 'assignToLoadBalancerRule',
|
888
|
-
'id' => id,
|
889
|
-
'virtualmachineids' => vm_ids.join(',')
|
890
|
-
}
|
891
|
-
json = send_async_request(params)
|
892
|
-
end
|
893
|
-
|
894
|
-
##
|
895
|
-
# Lists all virtual routers.
|
896
|
-
|
897
|
-
def list_routers(args = {:account => nil, :zone => nil, :projectid => nil, :status => nil, :name => nil})
|
898
|
-
params = {
|
899
|
-
'command' => 'listRouters',
|
900
|
-
'listall' => 'true',
|
901
|
-
'isrecursive' => 'true'
|
902
|
-
}
|
903
|
-
if args[:zone]
|
904
|
-
zone = get_zone(args[:zone])
|
905
|
-
unless zone
|
906
|
-
puts "Error: Zone #{args[:zone]} not found"
|
907
|
-
exit 1
|
908
|
-
end
|
909
|
-
params['zoneid'] = zone['id']
|
910
|
-
end
|
911
|
-
params['projectid'] = args[:projectid] if args[:projectid]
|
912
|
-
params['state'] = args[:status] if args[:status]
|
913
|
-
params['name'] = args[:name] if args[:name]
|
914
|
-
if args[:account]
|
915
|
-
account = list_accounts({name: args[:account]}).first
|
916
|
-
unless account
|
917
|
-
puts "Error: Account #{args[:account]} not found."
|
918
|
-
exit 1
|
919
|
-
end
|
920
|
-
params['domainid'] = account["domainid"]
|
921
|
-
params['account'] = args[:account]
|
922
|
-
end
|
923
|
-
|
924
|
-
json = send_request(params)
|
925
|
-
json['router'] || []
|
926
|
-
end
|
927
|
-
|
928
|
-
##
|
929
|
-
# Destroy virtual router.
|
930
|
-
|
931
|
-
def destroy_router(id, async = false)
|
932
|
-
params = {
|
933
|
-
'command' => 'destroyRouter',
|
934
|
-
'id' => id
|
935
|
-
}
|
936
|
-
async ? send_async_request(params) : send_request(params)
|
937
|
-
end
|
938
|
-
|
939
|
-
##
|
940
|
-
# Start virtual router.
|
941
|
-
|
942
|
-
def start_router(id, async = false)
|
943
|
-
params = {
|
944
|
-
'command' => 'startRouter',
|
945
|
-
'id' => id
|
946
|
-
}
|
947
|
-
async ? send_async_request(params) : send_request(params)
|
948
|
-
end
|
949
|
-
|
950
|
-
##
|
951
|
-
# Stop virtual router.
|
952
|
-
|
953
|
-
def stop_router(id, async = false)
|
954
|
-
params = {
|
955
|
-
'command' => 'stopRouter',
|
956
|
-
'id' => id
|
957
|
-
}
|
958
|
-
async ? send_async_request(params) : send_request(params)
|
959
|
-
end
|
960
|
-
|
961
|
-
##
|
962
|
-
# Lists accounts.
|
963
|
-
|
964
|
-
def list_accounts(args = { :name => nil })
|
965
|
-
params = {
|
966
|
-
'command' => 'listAccounts',
|
967
|
-
'listall' => 'true',
|
968
|
-
'isrecursive' => 'true'
|
969
|
-
}
|
970
|
-
params['name'] = args[:name] if args[:name]
|
971
|
-
|
972
|
-
json = send_request(params)
|
973
|
-
json['account'] || []
|
974
|
-
end
|
975
|
-
|
976
|
-
##
|
977
|
-
# List domains.
|
978
|
-
|
979
|
-
def list_domains(name = nil)
|
980
|
-
params = {
|
981
|
-
'command' => 'listDomains',
|
982
|
-
'listall' => 'true',
|
983
|
-
'isrecursive' => 'true'
|
984
|
-
}
|
985
|
-
params['name'] = name if name
|
986
|
-
|
987
|
-
json = send_request(params)
|
988
|
-
json['domain'] || []
|
989
|
-
end
|
990
|
-
|
991
|
-
##
|
992
|
-
# List capacity.
|
993
|
-
|
994
|
-
def list_capacity(args = {})
|
995
|
-
params = {
|
996
|
-
'command' => 'listCapacity',
|
997
|
-
}
|
998
|
-
|
999
|
-
json = send_request(params)
|
1000
|
-
json['capacity'] || []
|
1001
|
-
end
|
1002
|
-
|
1003
30
|
##
|
1004
31
|
# Sends a synchronous request to the CloudStack API and returns the response as a Hash.
|
1005
32
|
#
|