deltacloud-core 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -12
- data/config/drivers/{aruba.yaml → arubacloud.yaml} +2 -2
- data/deltacloud-core.gemspec +4 -4
- data/lib/cimi/collections/address_templates.rb +1 -1
- data/lib/cimi/collections/addresses.rb +2 -2
- data/lib/cimi/collections/base.rb +1 -0
- data/lib/cimi/collections/credentials.rb +1 -1
- data/lib/cimi/collections/forwarding_group_templates.rb +1 -1
- data/lib/cimi/collections/forwarding_groups.rb +1 -1
- data/lib/cimi/collections/machine_configurations.rb +1 -1
- data/lib/cimi/collections/machine_images.rb +1 -1
- data/lib/cimi/collections/machine_templates.rb +1 -1
- data/lib/cimi/collections/machines.rb +2 -2
- data/lib/cimi/collections/network_configurations.rb +1 -1
- data/lib/cimi/collections/network_port_configurations.rb +1 -1
- data/lib/cimi/collections/network_port_templates.rb +1 -1
- data/lib/cimi/collections/network_ports.rb +1 -1
- data/lib/cimi/collections/network_templates.rb +1 -1
- data/lib/cimi/collections/networks.rb +1 -1
- data/lib/cimi/collections/volume_configurations.rb +1 -1
- data/lib/cimi/collections/volume_images.rb +1 -1
- data/lib/cimi/collections/volume_templates.rb +1 -1
- data/lib/cimi/collections/volumes.rb +1 -1
- data/lib/cimi/helpers/database_helper.rb +16 -61
- data/lib/cimi/helpers/filter_helper.rb +41 -0
- data/lib/cimi/helpers/select_helper.rb +62 -0
- data/lib/cimi/models.rb +21 -2
- data/lib/cimi/models/address.rb +9 -7
- data/lib/cimi/models/address_template.rb +4 -4
- data/lib/cimi/models/base.rb +62 -197
- data/lib/cimi/models/collection.rb +78 -70
- data/lib/cimi/models/disk.rb +15 -8
- data/lib/cimi/models/machine.rb +27 -29
- data/lib/cimi/models/machine_image.rb +10 -13
- data/lib/cimi/models/machine_template.rb +3 -3
- data/lib/cimi/models/resource.rb +190 -0
- data/lib/cimi/models/schema.rb +9 -0
- data/lib/cimi/models/volume.rb +10 -13
- data/lib/cimi/models/volume_configuration.rb +3 -3
- data/lib/cimi/models/volume_template.rb +2 -2
- data/lib/cimi/server.rb +1 -0
- data/lib/db.rb +15 -0
- data/lib/db/address_template.rb +15 -0
- data/lib/db/entity.rb +55 -0
- data/lib/db/machine_template.rb +15 -0
- data/lib/db/provider.rb +40 -0
- data/lib/db/volume_configuration.rb +15 -0
- data/lib/db/volume_template.rb +15 -0
- data/lib/deltacloud/collections/base.rb +1 -0
- data/lib/deltacloud/collections/instances.rb +2 -1
- data/lib/deltacloud/collections/storage_snapshots.rb +3 -1
- data/lib/deltacloud/core_ext/array.rb +5 -0
- data/lib/deltacloud/drivers/{aruba/aruba_driver.rb → arubacloud/arubacloud_driver.rb} +3 -6
- data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +48 -75
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +18 -3
- data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +25 -0
- data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +1 -1
- data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +34 -14
- data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +2 -0
- data/lib/deltacloud/drivers/mock/mock_driver.rb +3 -3
- data/lib/deltacloud/drivers/openstack/openstack_driver.rb +93 -33
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +2 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +2 -2
- data/lib/deltacloud/helpers/deltacloud_helper.rb +3 -1
- data/lib/deltacloud/helpers/rabbit_helper.rb +1 -2
- data/lib/deltacloud/models/address.rb +1 -0
- data/lib/deltacloud/models/blob.rb +1 -0
- data/lib/deltacloud/models/bucket.rb +1 -0
- data/lib/deltacloud/models/firewall.rb +1 -0
- data/lib/deltacloud/models/hardware_profile.rb +3 -1
- data/lib/deltacloud/models/image.rb +7 -0
- data/lib/deltacloud/models/instance.rb +12 -3
- data/lib/deltacloud/models/key.rb +1 -0
- data/lib/deltacloud/models/load_balancer.rb +1 -0
- data/lib/deltacloud/models/metric.rb +1 -0
- data/lib/deltacloud/models/realm.rb +10 -1
- data/lib/deltacloud/models/storage_snapshot.rb +1 -0
- data/lib/deltacloud/models/storage_volume.rb +2 -1
- data/lib/deltacloud/runner.rb +2 -1
- data/lib/deltacloud/server.rb +1 -0
- data/lib/deltacloud/version.rb +1 -1
- data/lib/deltacloud_rack.rb +4 -0
- data/tests/cimi/collections/machines_test.rb +80 -0
- data/tests/cimi/db/database_helper_test.rb +54 -99
- data/tests/cimi/db/db_helper.rb +2 -0
- data/tests/cimi/db/entity_test.rb +29 -0
- data/tests/cimi/model/collection_spec.rb +2 -2
- data/tests/cimi/model/credential_spec.rb +2 -2
- data/tests/cimi/model/machine_configuration_spec.rb +2 -2
- data/tests/cimi/model/machine_image_spec.rb +2 -2
- data/tests/cimi/model/machine_spec.rb +4 -4
- data/tests/cimi/model/machine_template_spec.rb +2 -2
- data/tests/cimi/model/volume_configuration_spec.rb +2 -2
- data/tests/cimi/model/volume_image_spec.rb +2 -2
- data/tests/cimi/model/volume_spec.rb +2 -2
- data/tests/cimi/model/volume_template_spec.rb +2 -2
- data/tests/cimi/spec_helper.rb +4 -0
- data/tests/deltacloud/collections/instances_collection_test.rb +3 -1
- data/tests/deltacloud/launcher_test.rb +3 -5
- data/tests/drivers/ec2/images_test.rb +7 -0
- data/tests/drivers/gogrid/images_test.rb +7 -0
- data/tests/drivers/openstack/instances_test.rb +8 -8
- data/tests/drivers/openstack/realms_test.rb +13 -13
- data/views/errors/403.xml.haml +2 -1
- data/views/images/show.html.haml +4 -1
- data/views/images/show.xml.haml +1 -0
- data/views/instances/new.html.haml +1 -1
- data/views/instances/show.html.haml +3 -0
- data/views/realms/index.html.haml +2 -0
- data/views/realms/show.html.haml +4 -0
- data/views/realms/show.xml.haml +3 -0
- metadata +19 -14
@@ -53,6 +53,7 @@ module Deltacloud
|
|
53
53
|
memory 613
|
54
54
|
storage 160
|
55
55
|
architecture ['i386','x86_64']
|
56
|
+
root_type :persistent
|
56
57
|
end
|
57
58
|
|
58
59
|
define_hardware_profile('m1.small') do
|
@@ -301,7 +302,7 @@ module Deltacloud
|
|
301
302
|
target = instance(credentials, :id => opts[:id])
|
302
303
|
param = {}
|
303
304
|
param[:credentials] = {
|
304
|
-
:username => 'root', # Default for EC2 Linux instances
|
305
|
+
:username => (opts[:username]) ? opts[:username] : 'root', # Default for EC2 Linux instances
|
305
306
|
}
|
306
307
|
param[:port] = opts[:port] || '22'
|
307
308
|
param[:ip] = opts[:ip] || target.public_addresses.first.address
|
@@ -379,7 +380,11 @@ module Deltacloud
|
|
379
380
|
def create_key(credentials, opts={})
|
380
381
|
ec2 = new_client(credentials)
|
381
382
|
safely do
|
382
|
-
|
383
|
+
if (opts[:public_key] && opts[:public_key].length >0)
|
384
|
+
convert_key(ec2.import_key_pair(opts[:key_name], opts[:public_key]))
|
385
|
+
else
|
386
|
+
convert_key(ec2.create_key_pair(opts[:key_name]))
|
387
|
+
end
|
383
388
|
end
|
384
389
|
end
|
385
390
|
|
@@ -938,10 +943,15 @@ module Deltacloud
|
|
938
943
|
:owner_id => image[:aws_owner],
|
939
944
|
:architecture => image[:aws_architecture],
|
940
945
|
:hardware_profiles => image_profiles(image, profiles),
|
941
|
-
:state => image[:aws_state]
|
946
|
+
:state => image[:aws_state],
|
947
|
+
:root_type => convert_root_type(image[:aws_root_device_type])
|
942
948
|
)
|
943
949
|
end
|
944
950
|
|
951
|
+
def convert_root_type(type)
|
952
|
+
type == 'ebs' ? 'persistent' : 'transient'
|
953
|
+
end
|
954
|
+
|
945
955
|
def convert_instance(instance)
|
946
956
|
can_create_image = 'ebs'.eql?(instance[:root_device_type]) and 'RUNNING'.eql?(convert_state(instance[:aws_state]))
|
947
957
|
inst_profile_opts={}
|
@@ -1146,6 +1156,11 @@ module Deltacloud
|
|
1146
1156
|
end
|
1147
1157
|
|
1148
1158
|
exceptions do
|
1159
|
+
|
1160
|
+
on /root device is not supported for the instance/ do
|
1161
|
+
status 400
|
1162
|
+
end
|
1163
|
+
|
1149
1164
|
on /(AuthFailure|InvalidAccessKeyId)/ do
|
1150
1165
|
status 401
|
1151
1166
|
end
|
@@ -118,6 +118,31 @@ module Deltacloud
|
|
118
118
|
"Loadbalancer not supported in Eucalyptus", "")
|
119
119
|
end
|
120
120
|
|
121
|
+
#override ec2 driver realms - euca API doesn't support vpc/subnet concepts
|
122
|
+
#http://docs.aws.amazon.com/AWSEC2/2009-04-04/DeveloperGuide/
|
123
|
+
def realms(credentials, opts={})
|
124
|
+
ec2 = new_client(credentials)
|
125
|
+
realms = []
|
126
|
+
safely do
|
127
|
+
if opts[:id] and !opts[:id].empty?
|
128
|
+
begin
|
129
|
+
ec2.describe_availability_zones([opts[:id]]).collect do |realm|
|
130
|
+
realms << convert_realm(realm) unless realm.empty?
|
131
|
+
end
|
132
|
+
rescue => e
|
133
|
+
raise e unless e.message =~ /Invalid availability zone/
|
134
|
+
realms = []
|
135
|
+
end
|
136
|
+
else
|
137
|
+
realms = ec2.describe_availability_zones.collect do |realm|
|
138
|
+
convert_realm(realm) unless realm.empty?
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
realms
|
143
|
+
end
|
144
|
+
|
145
|
+
|
121
146
|
# override EC2 implementation; Eucalyptus implements the older definition of EC2 security group;
|
122
147
|
# http://docs.amazonwebservices.com/AWSEC2/2009-07-15/APIReference/index.html?ApiReference-query-AuthorizeSecurityGroupIngress.html
|
123
148
|
# if the rule specifies a source group, port&protocol will be ignored. And source group and cidr range can't be mixed in a request
|
@@ -60,6 +60,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
60
60
|
stopping.to( :stopped ) .automatically # stopping an instance does not automatically destroy it
|
61
61
|
stopped.to(:running) .on( :start ) # obvious
|
62
62
|
stopped.to(:finish) .on( :destroy ) # only destroy removes an instance, and it has to be stopped first
|
63
|
+
error.from( :pending, :running, :stopping) # not including STOP_ERROR and START_ERROR as they are as :running and :stopped
|
63
64
|
end
|
64
65
|
|
65
66
|
######################################################################
|
@@ -108,6 +109,13 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
108
109
|
if xml['diskimages'] # not likely to not be so, but just in case
|
109
110
|
xml['diskimages'][0]['diskimage'].each do |img|
|
110
111
|
|
112
|
+
# 32bit CentOS/RHEL images are refused on hwps > 16GB (i.e. w_high, quad_high)
|
113
|
+
os_arch = img['osName'][0].to_s =~ /.*32.?bit.*/ ? 'i386' : 'x86_64'
|
114
|
+
os_centos_rhel = img['osName'][0] =~ /(CentOS|Red Hat).*/
|
115
|
+
allowed_hwps = hwps.select do |hwp|
|
116
|
+
hwp.memory.default.to_i < 16000 or os_arch == 'x86_64' or not os_centos_rhel
|
117
|
+
end
|
118
|
+
|
111
119
|
images << Image.new(
|
112
120
|
:id => img['diskimageId'][0],
|
113
121
|
:name => img['diskimageName'][0].to_s,
|
@@ -117,8 +125,8 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
117
125
|
# This will determine image architecture using OS name.
|
118
126
|
# Usually the OS name includes '64bit' or '32bit'. If not,
|
119
127
|
# it will fall back to 64 bit.
|
120
|
-
:architecture =>
|
121
|
-
:hardware_profiles =>
|
128
|
+
:architecture => os_arch,
|
129
|
+
:hardware_profiles => allowed_hwps
|
122
130
|
) if opts[:id].nil? or opts[:id] == img['diskimageId'][0]
|
123
131
|
end
|
124
132
|
end
|
@@ -138,7 +146,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
138
146
|
if opts[:name].nil?
|
139
147
|
# default to instance name
|
140
148
|
instance = client.get_vserver_attributes(opts[:id])
|
141
|
-
opts[:name]
|
149
|
+
opts[:name] = instance['vserver'][0]['vserverName']
|
142
150
|
opts[:description] ||= opts[:name]
|
143
151
|
end
|
144
152
|
|
@@ -449,7 +457,9 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
449
457
|
end
|
450
458
|
state = client.get_vdisk_status(opts[:id])['vdiskStatus'][0]
|
451
459
|
actions = []
|
452
|
-
|
460
|
+
#align with EC2, cimi
|
461
|
+
case state
|
462
|
+
when 'NORMAL'
|
453
463
|
if vdisk['attachedTo'].nil?
|
454
464
|
state = 'AVAILABLE'
|
455
465
|
actions = [:attach, :destroy]
|
@@ -457,6 +467,10 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
457
467
|
state = 'IN-USE'
|
458
468
|
actions = [:detach]
|
459
469
|
end
|
470
|
+
when 'DEPLOYING'
|
471
|
+
state = 'CREATING'
|
472
|
+
when 'BACKUP_ING'
|
473
|
+
state = 'CAPTURING'
|
460
474
|
end
|
461
475
|
|
462
476
|
volumes << StorageVolume.new(
|
@@ -490,7 +504,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
490
504
|
:realm_id => client.extract_vsys_id(vdisk['vdiskId'][0]),
|
491
505
|
# aligning with rhevm, which returns 'system' or 'data'
|
492
506
|
:kind => determine_storage_type(vdisk['vdiskId'][0]),
|
493
|
-
:state => vdisk['attachedTo'].nil? ?
|
507
|
+
:state => vdisk['attachedTo'].nil? ? 'AVAILABLE' : 'IN-USE'
|
494
508
|
)
|
495
509
|
end
|
496
510
|
end
|
@@ -502,7 +516,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
502
516
|
|
503
517
|
def create_storage_volume(credentials, opts={})
|
504
518
|
opts ||= {}
|
505
|
-
opts[:name]
|
519
|
+
opts[:name] = Time.now.to_s unless opts[:name] and not opts[:name].empty?
|
506
520
|
opts[:capacity] ||= '1' # DC default
|
507
521
|
#size has to be a multiple of 10: round up.
|
508
522
|
opts[:capacity] = ((opts[:capacity].to_f / 10.0).ceil * 10.0).to_s
|
@@ -528,7 +542,8 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
528
542
|
:capacity => opts[:capacity],
|
529
543
|
:realm_id => client.extract_vsys_id(opts[:realm_id]),
|
530
544
|
:instance_id => nil,
|
531
|
-
|
545
|
+
# aligning with ec2, cimi (instead of fgcp's DEPLOYING)
|
546
|
+
:state => 'CREATING',
|
532
547
|
# aligning with rhevm, which returns 'system' or 'data'
|
533
548
|
:kind => 'data',
|
534
549
|
:actions => []
|
@@ -577,7 +592,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
577
592
|
|
578
593
|
snapshots << StorageSnapshot.new(
|
579
594
|
:id => opts[:id],
|
580
|
-
|
595
|
+
:state => 'AVAILABLE',
|
581
596
|
:storage_volume_id => vdisk_id,
|
582
597
|
:created => backup['backupTime'][0]
|
583
598
|
) if backup_id = backup['backupId'][0]
|
@@ -603,7 +618,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
603
618
|
|
604
619
|
snapshots << StorageSnapshot.new(
|
605
620
|
:id => generate_snapshot_id(vdisk['vdiskId'][0], backup['backupId'][0]),
|
606
|
-
|
621
|
+
:state => 'AVAILABLE',
|
607
622
|
:storage_volume_id => vdisk['vdiskId'][0],
|
608
623
|
:created => backup['backupTime'][0]
|
609
624
|
)
|
@@ -626,7 +641,7 @@ class FgcpDriver < Deltacloud::BaseDriver
|
|
626
641
|
|
627
642
|
StorageSnapshot.new(
|
628
643
|
:id => "PENDING-#{opts[:volume_id]}", # don't know id until backup completed
|
629
|
-
:state => '
|
644
|
+
:state => 'CREATING',
|
630
645
|
:storage_volume_id => opts[:volume_id],
|
631
646
|
:created => Time.now.to_s
|
632
647
|
)
|
@@ -1443,6 +1458,11 @@ eofwopxml
|
|
1443
1458
|
status 404 # Not Found
|
1444
1459
|
end
|
1445
1460
|
|
1461
|
+
# trying to create an image that has never been booted
|
1462
|
+
on /NEVER_BOOTED/ do
|
1463
|
+
status 409 # Conflict
|
1464
|
+
end
|
1465
|
+
|
1446
1466
|
# reached maximum number of attempts while polling for an update
|
1447
1467
|
on /Server did not include public IP address in FW NAT rules/ do
|
1448
1468
|
status 504 # Gateway Timeout
|
@@ -1629,7 +1649,7 @@ eofwopxml
|
|
1629
1649
|
:firewalls => server != 'FW' ? [client.extract_vsys_id(vserver['vserverId'][0]) + '-S-0001'] : nil,
|
1630
1650
|
:owner_id => vserver['creator'][0]
|
1631
1651
|
}
|
1632
|
-
instance.merge!( {'create_image' => false}) if
|
1652
|
+
instance.merge!( {'create_image' => false}) if server != 'vserver' or state_data[:state] != 'STOPPED'
|
1633
1653
|
instance.merge! state_data
|
1634
1654
|
|
1635
1655
|
Instance::new(instance)
|
@@ -1705,9 +1725,9 @@ eofwopxml
|
|
1705
1725
|
'UNEXPECTED_STOP' => 'STOPPED',
|
1706
1726
|
'RESTORING' => 'PENDING',
|
1707
1727
|
'BACKUP_ING' => 'PENDING',
|
1708
|
-
'ERROR' => '
|
1709
|
-
'START_ERROR' => 'STOPPED', #
|
1710
|
-
'STOP_ERROR' => '
|
1728
|
+
'ERROR' => 'ERROR', # allowed actions limited
|
1729
|
+
'START_ERROR' => 'STOPPED', # allowed actions are same as for STOPPED
|
1730
|
+
'STOP_ERROR' => 'RUNNING', # allowed actions are same as for RUNNING
|
1711
1731
|
'REGISTERING' => 'PENDING',
|
1712
1732
|
'CHANGE_TYPE' => 'PENDING'
|
1713
1733
|
}
|
@@ -205,11 +205,11 @@ module Deltacloud::Drivers::Mock
|
|
205
205
|
hwp ||= find_hardware_profile(credentials, 'm1-small', image_id)
|
206
206
|
|
207
207
|
name = opts[:name] || "i-#{Time.now.to_i}"
|
208
|
-
|
208
|
+
initial_state = opts[:initial_state] || "RUNNING"
|
209
209
|
instance = {
|
210
210
|
:id => next_id,
|
211
211
|
:name=>name,
|
212
|
-
:state=>
|
212
|
+
:state=> (initial_state == "STARTED" ? "RUNNING" : initial_state),
|
213
213
|
:keyname => opts[:keyname],
|
214
214
|
:image_id=>image_id,
|
215
215
|
:owner_id=>credentials.user,
|
@@ -218,7 +218,7 @@ module Deltacloud::Drivers::Mock
|
|
218
218
|
:instance_profile => InstanceProfile.new(hwp.name, opts),
|
219
219
|
:realm_id=>realm_id,
|
220
220
|
:create_image=>true,
|
221
|
-
:actions=>instance_actions_for(
|
221
|
+
:actions=>instance_actions_for((initial_state == "STARTED" ? "RUNNING" : initial_state)),
|
222
222
|
:user_data => opts[:user_data] ? Base64::decode64(opts[:user_data]) : nil
|
223
223
|
}
|
224
224
|
@client.store(:instances, instance)
|
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
require 'openstack'
|
18
18
|
require 'tempfile'
|
19
|
-
require 'base64'
|
20
19
|
|
21
20
|
module Deltacloud
|
22
21
|
module Drivers
|
@@ -44,20 +43,11 @@ module Deltacloud
|
|
44
43
|
end
|
45
44
|
|
46
45
|
define_hardware_profile('default')
|
47
|
-
|
48
46
|
def supported_collections(credentials)
|
49
47
|
#get the collections as defined by 'capability' and 'respond_to?' blocks
|
50
48
|
super_collections = super
|
51
|
-
|
52
|
-
|
53
|
-
rescue Deltacloud::Exceptions::NotImplemented #OpenStack::Exception::NotImplemented...
|
54
|
-
super_collections = super_collections - [Sinatra::Rabbit::BucketsCollection]
|
55
|
-
end
|
56
|
-
begin
|
57
|
-
new_client(credentials, "volume")
|
58
|
-
rescue Deltacloud::Exceptions::NotImplemented
|
59
|
-
super_collections = super_collections - [Sinatra::Rabbit::StorageVolumesCollection]
|
60
|
-
end
|
49
|
+
super_collections = super_collections - [Sinatra::Rabbit::BucketsCollection] if regions_for(credentials, "object-store").empty?
|
50
|
+
super_collections = super_collections - [Sinatra::Rabbit::StorageVolumesCollection] if regions_for(credentials, "volume").empty?
|
61
51
|
super_collections
|
62
52
|
end
|
63
53
|
|
@@ -127,21 +117,42 @@ module Deltacloud
|
|
127
117
|
|
128
118
|
def realms(credentials, opts={})
|
129
119
|
os = new_client(credentials)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
120
|
+
realms = []
|
121
|
+
if opts[:id]
|
122
|
+
resource_types = []
|
123
|
+
(os.connection.regions_list[opts[:id]] || []).each do |service|
|
124
|
+
resource_types << service[:service] if ["compute", "volume", "object-store"].include?(service[:service])
|
125
|
+
realms << Realm.new( { :id => opts[:id],
|
126
|
+
:name => opts[:id],
|
127
|
+
:state =>'AVAILABLE',
|
128
|
+
:resource_types => resource_types}) unless resource_types.empty?
|
129
|
+
end
|
130
|
+
else
|
131
|
+
os.connection.regions_list.each_pair do |region, services|
|
132
|
+
resource_types = services.inject([]){|res, cur| res << cur[:service] if ["compute", "volume", "object-store"].include?(cur[:service]); res }
|
133
|
+
next if resource_types.empty? #nothing here deltacloud manages
|
134
|
+
realms << Realm.new( { :id => region,
|
135
|
+
:name => region,
|
136
|
+
:state =>'AVAILABLE',
|
137
|
+
:resource_types => resource_types})
|
138
|
+
end
|
139
139
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
140
|
+
realms
|
141
|
+
# limits = ""
|
142
|
+
# safely do
|
143
|
+
# lim = os.limits
|
144
|
+
# limits << "ABSOLUTE >> Max. Instances: #{lim[:absolute][:maxTotalInstances]} Max. RAM: #{lim[:absolute][:maxTotalRAMSize]} || "
|
145
|
+
# lim[:rate].each do |rate|
|
146
|
+
# if rate[:regex] =~ /servers/
|
147
|
+
# limits << "SERVERS >> Total: #{rate[:limit].first[:value]} Remaining: #{rate[:limit].first[:remaining]} Time Unit: per #{rate[:limit].first[:unit]}"
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
# end
|
151
|
+
# return [] if opts[:id] and opts[:id] != 'default'
|
152
|
+
# [ Realm.new( { :id=>'default',
|
153
|
+
# :name=>'default',
|
154
|
+
# :limit => limits,
|
155
|
+
# :state=>'AVAILABLE' })]
|
145
156
|
end
|
146
157
|
|
147
158
|
def instances(credentials, opts={})
|
@@ -167,7 +178,13 @@ module Deltacloud
|
|
167
178
|
end
|
168
179
|
|
169
180
|
def create_instance(credentials, image_id, opts)
|
170
|
-
|
181
|
+
if opts[:realm_id] && opts[:realm_id].length > 0
|
182
|
+
os = new_client( credentials, "compute", opts[:realm_id])
|
183
|
+
else
|
184
|
+
#choose a random realm:
|
185
|
+
available_realms = regions_for(credentials, "compute")
|
186
|
+
os = new_client(credentials, "compute", available_realms.sample.id)
|
187
|
+
end
|
171
188
|
result = nil
|
172
189
|
#opts[:personality]: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc
|
173
190
|
params = {}
|
@@ -183,15 +200,16 @@ module Deltacloud
|
|
183
200
|
params[:key_name]=opts[:keyname]
|
184
201
|
end
|
185
202
|
if opts[:user_data] && opts[:user_data].length > 0
|
186
|
-
params[:user_data]=
|
203
|
+
params[:user_data]=opts[:user_data]
|
187
204
|
end
|
188
205
|
safely do
|
189
206
|
server = os.create_server(params)
|
190
|
-
result = convert_from_server(server, os.connection.authuser, get_attachments(server.id, os))
|
207
|
+
result = convert_from_server(server, os.connection.authuser, get_attachments(server.id, os), os.connection.region)
|
191
208
|
end
|
192
209
|
result
|
193
210
|
end
|
194
211
|
|
212
|
+
|
195
213
|
def reboot_instance(credentials, instance_id)
|
196
214
|
os = new_client(credentials)
|
197
215
|
safely do
|
@@ -435,26 +453,48 @@ module Deltacloud
|
|
435
453
|
|
436
454
|
def storage_snapshots(credentials, opts={})
|
437
455
|
vs = new_client(credentials, "volume")
|
456
|
+
snapshots = []
|
438
457
|
safely do
|
458
|
+
if opts[:id]
|
459
|
+
snapshots << convert_snapshot(vs.get_snapshot(opts[:id]))
|
460
|
+
else
|
461
|
+
vs.snapshots.each do |snap|
|
462
|
+
snapshots << convert_snapshot(snap)
|
463
|
+
end
|
464
|
+
end
|
439
465
|
end
|
466
|
+
snapshots
|
440
467
|
end
|
441
468
|
|
442
469
|
def create_storage_snapshot(credentials, opts={})
|
443
470
|
vs = new_client(credentials, "volume")
|
444
471
|
safely do
|
472
|
+
name = opts[:name] || "snapshot_#{Time.now.to_i}"
|
473
|
+
description = opts[:description] || "snapshot from volume #{opts[:volume_id]}"
|
474
|
+
params = {:volume_id => opts[:volume_id], :display_name=>name, :display_description=>description}
|
475
|
+
convert_snapshot(vs.create_snapshot(params))
|
445
476
|
end
|
446
477
|
end
|
447
478
|
|
448
479
|
def destroy_storage_snapshot(credentials, opts={})
|
449
480
|
vs = new_client(credentials, "volume")
|
450
481
|
safely do
|
482
|
+
vs.delete_snapshot(opts[:id])
|
451
483
|
end
|
452
484
|
end
|
453
485
|
|
454
486
|
private
|
455
487
|
|
488
|
+
def region_specified?
|
489
|
+
api_provider.split(";").last
|
490
|
+
end
|
491
|
+
|
492
|
+
def regions_for(credentials, service="compute")
|
493
|
+
realms(credentials).select{|region| region.resource_types.include?(service)}
|
494
|
+
end
|
495
|
+
|
456
496
|
#for v2 authentication credentials.name == "username+tenant_name"
|
457
|
-
def new_client(credentials, type
|
497
|
+
def new_client(credentials, type="compute", realm_id=nil)
|
458
498
|
tokens = credentials.user.split("+")
|
459
499
|
if credentials.user.empty?
|
460
500
|
raise AuthenticationFailure.new(Exception.new("Error: you must supply the username"))
|
@@ -464,10 +504,18 @@ private
|
|
464
504
|
else
|
465
505
|
user_name, tenant_name = tokens.first, tokens.last
|
466
506
|
end
|
507
|
+
#check if region specified with provider:
|
508
|
+
provider = api_provider
|
509
|
+
if (realm_id || provider.include?(";"))
|
510
|
+
region = realm_id || provider.split(";").last
|
511
|
+
provider = provider.chomp(";#{region}")
|
512
|
+
end
|
513
|
+
connection_params = {:username => user_name, :api_key => credentials.password, :authtenant => tenant_name, :auth_url => provider, :service_type => type}
|
514
|
+
connection_params.merge!({:region => region}) if region
|
467
515
|
safely do
|
468
516
|
raise ValidationFailure.new(Exception.new("Error: tried to initialise Openstack connection using" +
|
469
517
|
" an unknown service_type: #{type}")) unless ["volume", "compute", "object-store"].include? type
|
470
|
-
OpenStack::Connection.create(
|
518
|
+
OpenStack::Connection.create(connection_params)
|
471
519
|
end
|
472
520
|
end
|
473
521
|
|
@@ -500,7 +548,7 @@ private
|
|
500
548
|
})
|
501
549
|
end
|
502
550
|
|
503
|
-
def convert_from_server(server, owner, attachments=[])
|
551
|
+
def convert_from_server(server, owner, attachments=[], region=nil)
|
504
552
|
op = (server.class == Hash)? :fetch : :send
|
505
553
|
image = server.send(op, :image)
|
506
554
|
flavor = server.send(op, :flavor)
|
@@ -511,7 +559,7 @@ private
|
|
511
559
|
end
|
512
560
|
inst = Instance.new(
|
513
561
|
:id => server.send(op, :id).to_s,
|
514
|
-
:realm_id =>
|
562
|
+
:realm_id => region || "n/a",
|
515
563
|
:owner_id => owner,
|
516
564
|
:description => server.send(op, :name),
|
517
565
|
:name => server.send(op, :name),
|
@@ -524,6 +572,7 @@ private
|
|
524
572
|
:username => 'root',
|
525
573
|
:password => password,
|
526
574
|
:keyname => server.send(op, :key_name),
|
575
|
+
:launch_time => server.send(op, :created),
|
527
576
|
:storage_volumes => attachments.inject([]){|res, cur| res << {cur[:volumeId] => cur[:device]} ;res}
|
528
577
|
)
|
529
578
|
inst.actions = instance_actions_for(inst.state)
|
@@ -607,6 +656,17 @@ private
|
|
607
656
|
})
|
608
657
|
end
|
609
658
|
|
659
|
+
def convert_snapshot(snapshot)
|
660
|
+
StorageSnapshot.new(
|
661
|
+
:id => snapshot.id,
|
662
|
+
:name => snapshot.display_name,
|
663
|
+
:description => snapshot.display_description || snapshot.display_name,
|
664
|
+
:state => snapshot.status,
|
665
|
+
:storage_volume_id => snapshot.volume_id,
|
666
|
+
:created => snapshot.created_at
|
667
|
+
)
|
668
|
+
end
|
669
|
+
|
610
670
|
#IN: path1='server_path1'. content1='contents1', path2='server_path2', content2='contents2' etc
|
611
671
|
#OUT:{local_path=>server_path, local_path1=>server_path2 etc}
|
612
672
|
def extract_personality(opts)
|