deltacloud-core 1.1.0 → 1.1.1
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/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)
|