deltacloud-core 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +10 -2
- data/bin/deltacloudd +10 -10
- data/config.ru +2 -1
- data/config/drivers/digitalocean.yaml +3 -0
- data/deltacloud-core.gemspec +13 -6
- data/lib/cimi/collections.rb +1 -1
- data/lib/cimi/collections/address_templates.rb +27 -3
- data/lib/cimi/collections/addresses.rb +1 -1
- data/lib/cimi/collections/base.rb +1 -0
- data/lib/cimi/collections/cloud_entry_point.rb +4 -0
- data/lib/cimi/collections/credentials.rb +2 -2
- data/lib/cimi/collections/machine_images.rb +20 -0
- data/lib/cimi/collections/machine_templates.rb +72 -0
- data/lib/cimi/collections/machines.rb +50 -41
- data/lib/cimi/collections/network_ports.rb +3 -3
- data/lib/cimi/collections/networks.rb +4 -4
- data/lib/cimi/collections/resource_metadata.rb +1 -1
- data/lib/cimi/collections/volume_configurations.rb +25 -0
- data/lib/cimi/collections/volume_images.rb +21 -1
- data/lib/cimi/collections/volume_templates.rb +69 -0
- data/lib/cimi/collections/volumes.rb +5 -10
- data/lib/cimi/dependencies.rb +0 -1
- data/lib/cimi/helpers.rb +4 -1
- data/lib/cimi/helpers/cimi_helper.rb +62 -0
- data/lib/cimi/helpers/database_helper.rb +95 -0
- data/lib/cimi/models.rb +15 -1
- data/lib/cimi/models/address.rb +10 -5
- data/lib/cimi/models/address_template.rb +67 -3
- data/lib/cimi/models/base.rb +8 -5
- data/lib/cimi/models/cloud_entry_point.rb +6 -1
- data/lib/cimi/models/collection.rb +9 -4
- data/lib/cimi/models/disk.rb +6 -1
- data/lib/cimi/models/errors.rb +8 -0
- data/lib/cimi/models/machine.rb +68 -42
- data/lib/cimi/models/machine_configuration.rb +2 -2
- data/lib/cimi/models/machine_image.rb +41 -6
- data/lib/cimi/models/machine_template.rb +58 -0
- data/lib/cimi/models/machine_volume.rb +51 -3
- data/lib/cimi/models/resource_metadata.rb +88 -25
- data/lib/cimi/models/schema.rb +19 -5
- data/lib/cimi/models/volume.rb +66 -30
- data/lib/cimi/models/volume_configuration.rb +53 -21
- data/lib/cimi/models/volume_image.rb +24 -9
- data/lib/cimi/models/volume_template.rb +61 -0
- data/lib/cimi/server.rb +0 -6
- data/lib/db.rb +82 -0
- data/lib/db/address_template.rb +15 -0
- data/lib/db/entity.rb +22 -0
- data/lib/db/machine_template.rb +10 -0
- data/lib/db/provider.rb +13 -0
- data/lib/db/volume_configuration.rb +10 -0
- data/lib/db/volume_template.rb +10 -0
- data/lib/deltacloud/collections/addresses.rb +1 -1
- data/lib/deltacloud/collections/base.rb +12 -1
- data/lib/deltacloud/collections/buckets.rb +41 -8
- data/lib/deltacloud/collections/drivers.rb +1 -1
- data/lib/deltacloud/collections/firewalls.rb +2 -2
- data/lib/deltacloud/collections/images.rb +1 -1
- data/lib/deltacloud/collections/instances.rb +7 -1
- data/lib/deltacloud/collections/keys.rb +1 -1
- data/lib/deltacloud/collections/load_balancers.rb +4 -4
- data/lib/deltacloud/collections/storage_snapshots.rb +5 -1
- data/lib/deltacloud/collections/storage_volumes.rb +7 -3
- data/lib/deltacloud/drivers/base_driver.rb +10 -9
- data/lib/deltacloud/drivers/cimi_features.rb +42 -0
- data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +307 -0
- data/lib/deltacloud/drivers/ec2/ec2_driver.rb +40 -14
- data/lib/deltacloud/drivers/exceptions.rb +8 -0
- data/lib/deltacloud/drivers/features.rb +19 -2
- data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +11 -0
- data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +83 -11
- data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +1 -1
- data/lib/deltacloud/drivers/mock/mock_client.rb +2 -4
- data/lib/deltacloud/drivers/mock/mock_driver.rb +29 -0
- data/lib/deltacloud/drivers/openstack/openstack_driver.rb +153 -36
- data/lib/deltacloud/drivers/rackspace/anti_cache_monkey_patch.rb +20 -0
- data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +1 -0
- data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +30 -12
- data/lib/deltacloud/drivers/sbc/sbc_client.rb +0 -1
- data/lib/deltacloud/drivers/sbc/sbc_driver.rb +5 -1
- data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +1 -1
- data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +19 -9
- data/lib/deltacloud/helpers/blob_stream_helper.rb +42 -3
- data/lib/deltacloud/helpers/deltacloud_helper.rb +31 -14
- data/lib/deltacloud/models/address.rb +9 -0
- data/lib/deltacloud/models/base_model.rb +4 -0
- data/lib/deltacloud/models/blob.rb +12 -0
- data/lib/deltacloud/models/bucket.rb +9 -0
- data/lib/deltacloud/models/firewall.rb +13 -1
- data/lib/deltacloud/models/firewall_rule.rb +14 -0
- data/lib/deltacloud/models/hardware_profile.rb +14 -0
- data/lib/deltacloud/models/image.rb +15 -0
- data/lib/deltacloud/models/instance.rb +40 -1
- data/lib/deltacloud/models/instance_address.rb +9 -0
- data/lib/deltacloud/models/key.rb +15 -0
- data/lib/deltacloud/models/load_balancer.rb +20 -0
- data/lib/deltacloud/models/metric.rb +15 -0
- data/lib/deltacloud/models/provider.rb +8 -0
- data/lib/deltacloud/models/realm.rb +9 -0
- data/lib/deltacloud/models/state_machine.rb +8 -0
- data/lib/deltacloud/models/storage_snapshot.rb +11 -0
- data/lib/deltacloud/models/storage_volume.rb +24 -0
- data/lib/deltacloud/server.rb +1 -3
- data/lib/deltacloud/version.rb +2 -1
- data/lib/deltacloud_rack.rb +1 -1
- data/tests/cimi/db/database_helper_test.rb +190 -0
- data/tests/cimi/db/db_helper.rb +30 -0
- data/tests/cimi/db/schema_test.rb +94 -0
- data/tests/cimi/model/collection_spec.rb +0 -1
- data/tests/cimi/model/machine_spec.rb +17 -0
- data/tests/cimi/spec_helper.rb +3 -2
- data/tests/deltacloud/collections/buckets_collection_test.rb +3 -0
- data/tests/deltacloud/collections/drivers_collection_test.rb +10 -0
- data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +4 -0
- data/tests/deltacloud/collections/images_collection_test.rb +4 -0
- data/tests/deltacloud/collections/instances_collection_test.rb +14 -1
- data/tests/deltacloud/collections/keys_collection_test.rb +4 -0
- data/tests/deltacloud/collections/realms_collection_test.rb +47 -0
- data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +47 -0
- data/tests/deltacloud/collections/storage_volumes_collection_test.rb +47 -0
- data/tests/deltacloud/common.rb +15 -0
- data/tests/deltacloud/deltacloud_helper_test.rb +0 -4
- data/tests/deltacloud/launcher_test.rb +108 -0
- data/tests/drivers/ec2/buckets_test.rb +2 -1
- data/tests/drivers/mock/buckets_test.rb +27 -0
- data/tests/drivers/mock/instances_test.rb +6 -0
- data/tests/drivers/openstack/common.rb +1 -1
- data/tests/drivers/openstack/hardware_profiles_test.rb +2 -1
- data/tests/drivers/openstack/instances_test.rb +18 -17
- data/tests/drivers/rhevm/common.rb +1 -0
- data/tests/drivers/rhevm/images_test.rb +1 -1
- data/tests/drivers/rhevm/instance_test.rb +7 -7
- data/tests/helpers/rack/rack_matrix_params_test.rb +0 -2
- data/tests/test_helper.rb +2 -1
- data/views/errors/403.xml.haml +6 -0
- data/views/errors/409.html.haml +47 -0
- data/views/errors/409.xml.haml +11 -0
- data/views/errors/502.html.haml +6 -5
- data/views/images/show.xml.haml +3 -2
- data/views/instances/new.html.haml +1 -1
- metadata +77 -30
data/lib/cimi/models/address.rb
CHANGED
@@ -51,7 +51,7 @@ class CIMI::Model::Address < CIMI::Model::Base
|
|
51
51
|
|
52
52
|
def self.create(request_body, context, type)
|
53
53
|
input = (type == :xml)? XmlSimple.xml_in(request_body, {"ForceArray"=>false, "NormaliseSpace"=>2}) : JSON.parse(request_body)
|
54
|
-
if input["addressTemplate"]["href"] #by reference
|
54
|
+
if input['addressTemplate'] and input["addressTemplate"]["href"] #by reference
|
55
55
|
address_template = CIMI::Model::AddressTemplate.find(context.href_id(input["addressTemplate"]["href"], :address_templates), context)
|
56
56
|
else
|
57
57
|
case type
|
@@ -64,27 +64,32 @@ class CIMI::Model::Address < CIMI::Model::Base
|
|
64
64
|
end
|
65
65
|
params = {:name=>input["name"], :description=>input["description"], :address_template=>address_template, :env=>context }
|
66
66
|
raise CIMI::Model::BadRequest.new("Bad request - missing required parameters. Client sent: #{request_body} which produced #{params.inspect}") if params.has_value?(nil)
|
67
|
-
context.driver.create_address(context.credentials, params)
|
67
|
+
address = context.driver.create_address(context.credentials, params)
|
68
|
+
store_attributes_for(address, input)
|
69
|
+
from_address(address, context)
|
68
70
|
end
|
69
71
|
|
70
72
|
def self.delete!(id, context)
|
71
73
|
context.driver.delete_address(context.credentials, id)
|
74
|
+
delete_attributes_for(::Address.new(:id => id))
|
72
75
|
end
|
73
76
|
|
74
77
|
private
|
75
78
|
|
76
79
|
def self.from_address(address, context)
|
80
|
+
stored_attributes = load_attributes_for(address)
|
77
81
|
self.new(
|
78
|
-
:name => address.id,
|
82
|
+
:name => stored_attributes[:name] || address.id,
|
79
83
|
:id => context.address_url(address.id),
|
80
|
-
:description => "Address #{address.id}",
|
84
|
+
:description => stored_attributes[:description] || "Address #{address.id}",
|
81
85
|
:ip => address.id,
|
82
86
|
:allocation => "dynamic", #or "static"
|
83
|
-
:default_gateway => "
|
87
|
+
:default_gateway => "unknown", #wtf
|
84
88
|
:dns => "unknown", #wtf
|
85
89
|
:protocol => protocol_from_address(address.id),
|
86
90
|
:mask => "unknown",
|
87
91
|
:resource => (address.instance_id) ? {:href=> context.machine_url(address.instance_id)} : nil,
|
92
|
+
:property => stored_attributes[:property],
|
88
93
|
:network => nil #unknown
|
89
94
|
#optional:
|
90
95
|
#:hostname =>
|
@@ -39,16 +39,80 @@ class CIMI::Model::AddressTemplate < CIMI::Model::Base
|
|
39
39
|
|
40
40
|
def self.find(id, context)
|
41
41
|
if id==:all
|
42
|
-
context.driver.
|
42
|
+
if context.driver.respond_to? :address_templates
|
43
|
+
context.driver.address_templates(context.credentials, {:env=>context})
|
44
|
+
else
|
45
|
+
current_db.address_teplates.map { |t| from_db(t, context) }
|
46
|
+
end
|
43
47
|
else
|
44
|
-
context.driver.
|
48
|
+
if context.driver.respond_to? :address_template
|
49
|
+
context.driver.address_template(context.credentials, id, :env=>context)
|
50
|
+
else
|
51
|
+
template = current_db.address_templates_dataset.first(:id => id)
|
52
|
+
raise CIMI::Model::NotFound unless template
|
53
|
+
from_db(template, context)
|
54
|
+
end
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
48
|
-
def self.
|
58
|
+
def self.create_from_json(body, context)
|
59
|
+
json = JSON.parse(body)
|
60
|
+
new_template = current_db.add_address_template(
|
61
|
+
:name => json['name'],
|
62
|
+
:description => json['description'],
|
63
|
+
:hostname => json['hostname'],
|
64
|
+
:ip => json['ip'],
|
65
|
+
:allocation => json['allocation'],
|
66
|
+
:default_gateway => json['default_gateway'],
|
67
|
+
:dns => json['dns'],
|
68
|
+
:protocol => json['protocol'],
|
69
|
+
:mask => json['mask'],
|
70
|
+
:ent_properties => json['properties'].to_json
|
71
|
+
)
|
72
|
+
from_db(new_template, context)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.create_from_xml(body, context)
|
76
|
+
xml = XmlSimple.xml_in(body)
|
77
|
+
xml['property'] ||= []
|
78
|
+
new_template = current_db.add_address_template(
|
79
|
+
:name => xml['name'].first,
|
80
|
+
:description => xml['description'].first,
|
81
|
+
:ip => xml['ip'].first,
|
82
|
+
:hostname => xml['hostname'].first,
|
83
|
+
:allocation => xml['allocation'].first,
|
84
|
+
:default_gateway => xml['default_gateway'].first,
|
85
|
+
:dns => xml['dns'].first,
|
86
|
+
:protocol => xml['protocol'].nil? ? nil : xml['protocol'].first,
|
87
|
+
:mask => xml['mask'].first,
|
88
|
+
:ent_properties => JSON::dump(xml['property'].inject({}) { |r, p| r[p['key']]=p['content']; r })
|
89
|
+
)
|
90
|
+
from_db(new_template, context)
|
49
91
|
end
|
50
92
|
|
51
93
|
def self.delete!(id, context)
|
94
|
+
current_db.address_templates.first(:id => id).destroy
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def self.from_db(model, context)
|
100
|
+
self.new(
|
101
|
+
:id => context.address_template_url(model.id),
|
102
|
+
:name => model.name,
|
103
|
+
:description => model.description,
|
104
|
+
:ip => model.ip,
|
105
|
+
:hostname => model.hostname,
|
106
|
+
:allocation => model.allocation,
|
107
|
+
:default_gateway => model.default_gateway,
|
108
|
+
:dns => model.dns,
|
109
|
+
:protocol => model.protocol,
|
110
|
+
:mask => model.mask,
|
111
|
+
:property => JSON::parse(model.ent_properties),
|
112
|
+
:operations => [
|
113
|
+
{ :href => context.destroy_address_template_url(model.id), :rel => 'http://schemas.dmtf.org/cimi/1/action/delete' }
|
114
|
+
]
|
115
|
+
)
|
52
116
|
end
|
53
117
|
|
54
118
|
end
|
data/lib/cimi/models/base.rb
CHANGED
@@ -14,7 +14,6 @@
|
|
14
14
|
# under the License.
|
15
15
|
|
16
16
|
require 'xmlsimple'
|
17
|
-
require 'json'
|
18
17
|
|
19
18
|
# The base class for any CIMI object that we either read from a request or
|
20
19
|
# write as a response. This class handles serializing/deserializing XML and
|
@@ -73,7 +72,7 @@ require 'json'
|
|
73
72
|
module CIMI::Model
|
74
73
|
|
75
74
|
def self.register_as_root_entity!(klass, opts = {})
|
76
|
-
@root_entities ||= []
|
75
|
+
@root_entities ||= [CIMI::Model::CloudEntryPoint]
|
77
76
|
@root_entities << klass
|
78
77
|
name = klass.name.split("::").last.pluralize
|
79
78
|
unless CIMI::Model::CloudEntryPoint.href_defined?(name)
|
@@ -109,7 +108,6 @@ class CIMI::Model::Resource
|
|
109
108
|
clone_base_schema unless base_schema_cloned?
|
110
109
|
member_name = model.name.split("::").last
|
111
110
|
if ::Struct.const_defined?("CIMI_#{member_name}")
|
112
|
-
puts "Removing struct"
|
113
111
|
::Struct.send(:remove_const, "CIMI_#{member_name}")
|
114
112
|
end
|
115
113
|
member_symbol = member_name.underscore.pluralize.to_sym
|
@@ -182,7 +180,7 @@ class CIMI::Model::Resource
|
|
182
180
|
#
|
183
181
|
def initialize(values = {})
|
184
182
|
names = self.class.schema.attribute_names
|
185
|
-
@attribute_values = names.inject(
|
183
|
+
@attribute_values = names.inject(OrderedHash.new) do |hash, name|
|
186
184
|
hash[name] = self.class.schema.convert(name, values[name])
|
187
185
|
hash
|
188
186
|
end
|
@@ -270,7 +268,10 @@ class CIMI::Model::Resource
|
|
270
268
|
end
|
271
269
|
end
|
272
270
|
|
271
|
+
require_relative '../helpers/database_helper'
|
272
|
+
|
273
273
|
class CIMI::Model::Base < CIMI::Model::Resource
|
274
|
+
extend Deltacloud::Helpers::Database
|
274
275
|
#
|
275
276
|
# Common attributes for all resources
|
276
277
|
#
|
@@ -280,9 +281,11 @@ class CIMI::Model::Base < CIMI::Model::Resource
|
|
280
281
|
|
281
282
|
def filter_attributes(attr_list)
|
282
283
|
attrs = attr_list.inject({}) do |result, attr|
|
283
|
-
|
284
|
+
attr = attr.to_s.underscore
|
285
|
+
result[attr.to_sym] = self.send(attr) if self.respond_to?(attr)
|
284
286
|
result
|
285
287
|
end
|
286
288
|
self.class.new(attrs)
|
287
289
|
end
|
290
|
+
|
288
291
|
end
|
@@ -15,6 +15,9 @@
|
|
15
15
|
|
16
16
|
class CIMI::Model::CloudEntryPoint < CIMI::Model::Base
|
17
17
|
|
18
|
+
resource_attr :driver, :required => true
|
19
|
+
resource_attr :provider, :required => true
|
20
|
+
|
18
21
|
# All possible CIMI collections, in the order in which they should appear
|
19
22
|
# in the CEP
|
20
23
|
COLLECTIONS = [ "resourceMetadata", "systems", "systemTemplates",
|
@@ -38,8 +41,10 @@ class CIMI::Model::CloudEntryPoint < CIMI::Model::Base
|
|
38
41
|
self.new(entities(context).merge({
|
39
42
|
:name => context.driver.name,
|
40
43
|
:description => "Cloud Entry Point for the Deltacloud #{context.driver.name} driver",
|
44
|
+
:driver => context.driver.name,
|
45
|
+
:provider => context.current_provider,
|
41
46
|
:id => context.cloudEntryPoint_url,
|
42
|
-
:base_uri => context.base_uri,
|
47
|
+
:base_uri => context.base_uri + "/",
|
43
48
|
:created => Time.now.xmlschema
|
44
49
|
}))
|
45
50
|
end
|
@@ -116,14 +116,19 @@ module CIMI::Model
|
|
116
116
|
def list(context)
|
117
117
|
entries = find(:all, context)
|
118
118
|
desc = "#{self.name.split("::").last} Collection for the #{context.driver.name.capitalize} driver"
|
119
|
+
acts_as_root_entity unless collection_class
|
119
120
|
id = context.send("#{collection_class.entry_name}_url")
|
120
121
|
ops = []
|
121
|
-
|
122
|
-
|
123
|
-
|
122
|
+
cimi_entity = collection_class.entry_name.to_s.singularize
|
123
|
+
cimi_create = "create_#{cimi_entity}_url"
|
124
|
+
dcloud_create = context.deltacloud_create_method_for(cimi_entity)
|
125
|
+
if(context.respond_to?(cimi_create) &&
|
126
|
+
context.driver.respond_to?(dcloud_create)) ||
|
127
|
+
provides?(cimi_entity)
|
128
|
+
url = context.send(cimi_create)
|
124
129
|
ops << { :rel => "add", :href => url }
|
125
130
|
end
|
126
|
-
collection_class.new(:id => id,
|
131
|
+
collection_class.new(:id => id,
|
127
132
|
:count => entries.size,
|
128
133
|
:entries => entries,
|
129
134
|
:operations => ops,
|
data/lib/cimi/models/disk.rb
CHANGED
@@ -57,7 +57,12 @@ class CIMI::Model::Disk < CIMI::Model::Base
|
|
57
57
|
def self.collection_for_instance(instance_id, context)
|
58
58
|
instance = context.driver.instance(context.credentials, :id => instance_id)
|
59
59
|
disks = find(instance, nil, context)
|
60
|
-
CIMI::Model
|
60
|
+
unless CIMI::Model.const_defined?('DiskCollection')
|
61
|
+
collection_class = CIMI::Model::Collection.generate(self)
|
62
|
+
else
|
63
|
+
collection_class = CIMI::Model::DiskCollection
|
64
|
+
end
|
65
|
+
collection_class.new(
|
61
66
|
:id => context.url("/machines/#{instance_id}/disks"),
|
62
67
|
:name => 'default',
|
63
68
|
:count => disks.size,
|
data/lib/cimi/models/errors.rb
CHANGED
data/lib/cimi/models/machine.rb
CHANGED
@@ -17,6 +17,11 @@ class CIMI::Model::Machine < CIMI::Model::Base
|
|
17
17
|
|
18
18
|
acts_as_root_entity
|
19
19
|
|
20
|
+
resource_attr :realm, :required => false,
|
21
|
+
:constraints => lambda { |c| c.driver.realms(c.credentials).map { |r| r.id } }
|
22
|
+
|
23
|
+
resource_attr :machine_image, :required => false, :type => :href
|
24
|
+
|
20
25
|
text :state
|
21
26
|
text :cpu
|
22
27
|
|
@@ -48,38 +53,60 @@ class CIMI::Model::Machine < CIMI::Model::Base
|
|
48
53
|
def self.create_from_json(body, context)
|
49
54
|
json = JSON.parse(body)
|
50
55
|
machine_template = json['machineTemplate']
|
51
|
-
|
52
|
-
|
56
|
+
if !machine_template['href'].nil?
|
57
|
+
template = current_db.machine_templates.first(:id => machine_template['href'].split('/').last)
|
58
|
+
raise 'Could not find the MachineTemplate' if template.nil?
|
59
|
+
hardware_profile_id = template.machine_config.split('/').last
|
60
|
+
image_id = template.machine_image.split('/').last
|
61
|
+
else
|
62
|
+
hardware_profile_id = machine_template['machineConfig']["href"].split('/').last
|
63
|
+
image_id = machine_template['machineImage']["href"].split('/').last
|
64
|
+
if machine_template.has_key? 'credential'
|
65
|
+
additional_params[:keyname] = machine_template['credential']["href"].split('/').last
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
53
69
|
additional_params = {}
|
54
70
|
additional_params[:name] = json['name'] if json['name']
|
55
|
-
if machine_template.has_key? 'credential'
|
56
|
-
additional_params[:keyname] = machine_template['credential']["href"].split('/').last
|
57
|
-
end
|
58
71
|
instance = context.driver.create_instance(context.credentials, image_id, {
|
59
72
|
:hwp_id => hardware_profile_id
|
60
73
|
}.merge(additional_params))
|
74
|
+
|
75
|
+
# Store attributes that are not supported by the backend cloud to local
|
76
|
+
# database:
|
77
|
+
store_attributes_for(instance, json)
|
61
78
|
from_instance(instance, context)
|
62
79
|
end
|
63
80
|
|
64
81
|
def self.create_from_xml(body, context)
|
65
82
|
xml = XmlSimple.xml_in(body)
|
66
|
-
|
67
|
-
|
68
|
-
|
83
|
+
if xml['machineTemplate'][0]['href']
|
84
|
+
template = current_db.machine_templates_dataset.first(:id => xml['machineTemplate'][0]['href'].split('/').last)
|
85
|
+
hardware_profile_id = template.machine_config.split('/').last
|
86
|
+
image_id = template.machine_image.split('/').last
|
87
|
+
else
|
88
|
+
machine_template = xml['machineTemplate'][0]
|
89
|
+
hardware_profile_id = machine_template['machineConfig'].first["href"].split('/').last
|
90
|
+
image_id = machine_template['machineImage'].first["href"].split('/').last
|
91
|
+
if machine_template.has_key? 'credential'
|
92
|
+
additional_params[:keyname] = machine_template['credential'][0]["href"].split('/').last
|
93
|
+
end
|
94
|
+
end
|
69
95
|
additional_params = {}
|
70
96
|
additional_params[:name] = xml['name'][0] if xml['name']
|
71
|
-
if machine_template.has_key? 'credential'
|
72
|
-
additional_params[:keyname] = machine_template['credential'][0]["href"].split('/').last
|
73
|
-
end
|
74
97
|
instance = context.driver.create_instance(context.credentials, image_id, {
|
75
98
|
:hwp_id => hardware_profile_id
|
76
99
|
}.merge(additional_params))
|
77
|
-
|
100
|
+
|
101
|
+
# Store attributes that are not supported by the backend cloud to local
|
102
|
+
# database:
|
103
|
+
entity = store_attributes_for(instance, xml)
|
104
|
+
from_instance(instance, context, entity.to_hash)
|
78
105
|
end
|
79
106
|
|
80
107
|
def perform(action, context, &block)
|
81
108
|
begin
|
82
|
-
if context.driver.send(:"#{action.name}_instance", context.credentials, self.
|
109
|
+
if context.driver.send(:"#{action.name}_instance", context.credentials, self.id.split("/").last)
|
83
110
|
block.callback :success
|
84
111
|
else
|
85
112
|
raise "Operation failed to execute on given Machine"
|
@@ -90,42 +117,38 @@ class CIMI::Model::Machine < CIMI::Model::Base
|
|
90
117
|
end
|
91
118
|
|
92
119
|
def self.delete!(id, context)
|
120
|
+
delete_attributes_for Instance.new(:id => id)
|
93
121
|
context.driver.destroy_instance(context.credentials, id)
|
94
122
|
end
|
95
123
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
:constraints=>"Determined by the cloud provider", :type=>"xs:string"}
|
102
|
-
end
|
103
|
-
metadata
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.attach_volumes(volumes, context)
|
107
|
-
volumes.each do |vol|
|
108
|
-
context.driver.attach_storage_volume(context.credentials,
|
109
|
-
{:id=>vol[:volume].name, :instance_id=>context.params[:id], :device=>vol[:attachment_point]})
|
110
|
-
end
|
111
|
-
self.find(context.params[:id], context)
|
124
|
+
#returns the newly attach machine_volume
|
125
|
+
def self.attach_volume(volume, location, context)
|
126
|
+
context.driver.attach_storage_volume(context.credentials,
|
127
|
+
{:id=>volume, :instance_id=>context.params[:id], :device=>location})
|
128
|
+
CIMI::Model::MachineVolume.find(context.params[:id], context, volume)
|
112
129
|
end
|
113
130
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
131
|
+
#returns the machine_volume_collection for the given machine
|
132
|
+
def self.detach_volume(volume, location, context)
|
133
|
+
context.driver.detach_storage_volume(context.credentials,
|
134
|
+
{:id=>volume, :instance_id=>context.params[:id], :device=>location})
|
135
|
+
CIMI::Model::MachineVolume.collection_for_instance(context.params[:id], context)
|
119
136
|
end
|
120
137
|
|
121
138
|
private
|
122
|
-
def self.from_instance(instance, context)
|
139
|
+
def self.from_instance(instance, context, stored_attributes=nil)
|
123
140
|
cpu = memory = (instance.instance_profile.id == "opaque")? "n/a" : nil
|
124
141
|
machine_conf = CIMI::Model::MachineConfiguration.find(instance.instance_profile.name, context)
|
142
|
+
stored_attributes ||= load_attributes_for(instance)
|
143
|
+
if stored_attributes[:property]
|
144
|
+
stored_attributes[:property].merge!(convert_instance_properties(instance, context))
|
145
|
+
else
|
146
|
+
stored_attributes[:property] = convert_instance_properties(instance, context)
|
147
|
+
end
|
125
148
|
machine_spec = {
|
126
149
|
:name => instance.name,
|
127
|
-
:
|
128
|
-
:
|
150
|
+
:created => instance.launch_time.nil? ? Time.now.xmlschema : Time.parse(instance.launch_time.to_s).xmlschema,
|
151
|
+
:description => "No description set for Machine #{instance.name}",
|
129
152
|
:id => context.machine_url(instance.id),
|
130
153
|
:state => convert_instance_state(instance.state),
|
131
154
|
:cpu => cpu || convert_instance_cpu(instance.instance_profile, context),
|
@@ -133,14 +156,16 @@ class CIMI::Model::Machine < CIMI::Model::Base
|
|
133
156
|
:disks => { :href => context.machine_url(instance.id)+"/disks"},
|
134
157
|
:volumes => { :href=>context.machine_url(instance.id)+"/volumes"},
|
135
158
|
:operations => convert_instance_actions(instance, context),
|
136
|
-
:property =>
|
137
|
-
}
|
159
|
+
:property => stored_attributes
|
160
|
+
}.merge(stored_attributes)
|
138
161
|
if context.expand? :disks
|
139
162
|
machine_spec[:disks] = CIMI::Model::Disk.find(instance, machine_conf, context, :all)
|
140
163
|
end
|
141
164
|
if context.expand? :volumes
|
142
165
|
machine_spec[:volumes] = CIMI::Model::MachineVolume.find(instance.id, context, :all)
|
143
166
|
end
|
167
|
+
machine_spec[:realm] = instance.realm_id if instance.realm_id
|
168
|
+
machine_spec[:machine_image] = { :href => context.machine_image_url(instance.image_id) } if instance.image_id
|
144
169
|
machine = self.new(machine_spec)
|
145
170
|
machine
|
146
171
|
end
|
@@ -195,9 +220,10 @@ class CIMI::Model::Machine < CIMI::Model::Base
|
|
195
220
|
|
196
221
|
def self.convert_instance_actions(instance, context)
|
197
222
|
actions = instance.actions.collect do |action|
|
198
|
-
action = :
|
199
|
-
|
200
|
-
|
223
|
+
action = :restart if action == :reboot
|
224
|
+
name = action
|
225
|
+
name = :delete if action == :destroy # In CIMI destroy operation become delete
|
226
|
+
{ :href => context.send(:"#{action}_machine_url", instance.id), :rel => "http://schemas.dmtf.org/cimi/1/action/#{name}" }
|
201
227
|
end
|
202
228
|
actions << { :href => context.send(:"machine_images_url"), :rel => "http://schemas.dmtf.org/cimi/1/action/capture" } if instance.can_create_image?
|
203
229
|
actions
|
@@ -52,11 +52,11 @@ class CIMI::Model::MachineConfiguration < CIMI::Model::Base
|
|
52
52
|
:name => profile.name,
|
53
53
|
:description => "Machine Configuration with #{memory} KiB "+
|
54
54
|
"of memory and #{cpu} CPU",
|
55
|
-
:cpu => ( cpu if cpu ) ,
|
55
|
+
:cpu => ( cpu.to_i.to_s if cpu ) ,
|
56
56
|
:created => Time.now.xmlschema, # FIXME: DC hardware_profile has no mention about created_at
|
57
57
|
:memory => (memory if memory),
|
58
58
|
:disks => ( [ { :capacity => storage, :format => (profile.storage.respond_to?(:format) ? profile.storage.format : "unknown") } ] if storage ), #no format attr for hwp - may be added if providers support...,
|
59
|
-
:id => context.machine_configuration_url(profile.
|
59
|
+
:id => context.machine_configuration_url(profile.id)
|
60
60
|
}
|
61
61
|
self.new(machine_hash)
|
62
62
|
end
|