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.
Files changed (141) hide show
  1. data/Rakefile +10 -2
  2. data/bin/deltacloudd +10 -10
  3. data/config.ru +2 -1
  4. data/config/drivers/digitalocean.yaml +3 -0
  5. data/deltacloud-core.gemspec +13 -6
  6. data/lib/cimi/collections.rb +1 -1
  7. data/lib/cimi/collections/address_templates.rb +27 -3
  8. data/lib/cimi/collections/addresses.rb +1 -1
  9. data/lib/cimi/collections/base.rb +1 -0
  10. data/lib/cimi/collections/cloud_entry_point.rb +4 -0
  11. data/lib/cimi/collections/credentials.rb +2 -2
  12. data/lib/cimi/collections/machine_images.rb +20 -0
  13. data/lib/cimi/collections/machine_templates.rb +72 -0
  14. data/lib/cimi/collections/machines.rb +50 -41
  15. data/lib/cimi/collections/network_ports.rb +3 -3
  16. data/lib/cimi/collections/networks.rb +4 -4
  17. data/lib/cimi/collections/resource_metadata.rb +1 -1
  18. data/lib/cimi/collections/volume_configurations.rb +25 -0
  19. data/lib/cimi/collections/volume_images.rb +21 -1
  20. data/lib/cimi/collections/volume_templates.rb +69 -0
  21. data/lib/cimi/collections/volumes.rb +5 -10
  22. data/lib/cimi/dependencies.rb +0 -1
  23. data/lib/cimi/helpers.rb +4 -1
  24. data/lib/cimi/helpers/cimi_helper.rb +62 -0
  25. data/lib/cimi/helpers/database_helper.rb +95 -0
  26. data/lib/cimi/models.rb +15 -1
  27. data/lib/cimi/models/address.rb +10 -5
  28. data/lib/cimi/models/address_template.rb +67 -3
  29. data/lib/cimi/models/base.rb +8 -5
  30. data/lib/cimi/models/cloud_entry_point.rb +6 -1
  31. data/lib/cimi/models/collection.rb +9 -4
  32. data/lib/cimi/models/disk.rb +6 -1
  33. data/lib/cimi/models/errors.rb +8 -0
  34. data/lib/cimi/models/machine.rb +68 -42
  35. data/lib/cimi/models/machine_configuration.rb +2 -2
  36. data/lib/cimi/models/machine_image.rb +41 -6
  37. data/lib/cimi/models/machine_template.rb +58 -0
  38. data/lib/cimi/models/machine_volume.rb +51 -3
  39. data/lib/cimi/models/resource_metadata.rb +88 -25
  40. data/lib/cimi/models/schema.rb +19 -5
  41. data/lib/cimi/models/volume.rb +66 -30
  42. data/lib/cimi/models/volume_configuration.rb +53 -21
  43. data/lib/cimi/models/volume_image.rb +24 -9
  44. data/lib/cimi/models/volume_template.rb +61 -0
  45. data/lib/cimi/server.rb +0 -6
  46. data/lib/db.rb +82 -0
  47. data/lib/db/address_template.rb +15 -0
  48. data/lib/db/entity.rb +22 -0
  49. data/lib/db/machine_template.rb +10 -0
  50. data/lib/db/provider.rb +13 -0
  51. data/lib/db/volume_configuration.rb +10 -0
  52. data/lib/db/volume_template.rb +10 -0
  53. data/lib/deltacloud/collections/addresses.rb +1 -1
  54. data/lib/deltacloud/collections/base.rb +12 -1
  55. data/lib/deltacloud/collections/buckets.rb +41 -8
  56. data/lib/deltacloud/collections/drivers.rb +1 -1
  57. data/lib/deltacloud/collections/firewalls.rb +2 -2
  58. data/lib/deltacloud/collections/images.rb +1 -1
  59. data/lib/deltacloud/collections/instances.rb +7 -1
  60. data/lib/deltacloud/collections/keys.rb +1 -1
  61. data/lib/deltacloud/collections/load_balancers.rb +4 -4
  62. data/lib/deltacloud/collections/storage_snapshots.rb +5 -1
  63. data/lib/deltacloud/collections/storage_volumes.rb +7 -3
  64. data/lib/deltacloud/drivers/base_driver.rb +10 -9
  65. data/lib/deltacloud/drivers/cimi_features.rb +42 -0
  66. data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +307 -0
  67. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +40 -14
  68. data/lib/deltacloud/drivers/exceptions.rb +8 -0
  69. data/lib/deltacloud/drivers/features.rb +19 -2
  70. data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +11 -0
  71. data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +83 -11
  72. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +1 -1
  73. data/lib/deltacloud/drivers/mock/mock_client.rb +2 -4
  74. data/lib/deltacloud/drivers/mock/mock_driver.rb +29 -0
  75. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +153 -36
  76. data/lib/deltacloud/drivers/rackspace/anti_cache_monkey_patch.rb +20 -0
  77. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +1 -0
  78. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +30 -12
  79. data/lib/deltacloud/drivers/sbc/sbc_client.rb +0 -1
  80. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +5 -1
  81. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +1 -1
  82. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +19 -9
  83. data/lib/deltacloud/helpers/blob_stream_helper.rb +42 -3
  84. data/lib/deltacloud/helpers/deltacloud_helper.rb +31 -14
  85. data/lib/deltacloud/models/address.rb +9 -0
  86. data/lib/deltacloud/models/base_model.rb +4 -0
  87. data/lib/deltacloud/models/blob.rb +12 -0
  88. data/lib/deltacloud/models/bucket.rb +9 -0
  89. data/lib/deltacloud/models/firewall.rb +13 -1
  90. data/lib/deltacloud/models/firewall_rule.rb +14 -0
  91. data/lib/deltacloud/models/hardware_profile.rb +14 -0
  92. data/lib/deltacloud/models/image.rb +15 -0
  93. data/lib/deltacloud/models/instance.rb +40 -1
  94. data/lib/deltacloud/models/instance_address.rb +9 -0
  95. data/lib/deltacloud/models/key.rb +15 -0
  96. data/lib/deltacloud/models/load_balancer.rb +20 -0
  97. data/lib/deltacloud/models/metric.rb +15 -0
  98. data/lib/deltacloud/models/provider.rb +8 -0
  99. data/lib/deltacloud/models/realm.rb +9 -0
  100. data/lib/deltacloud/models/state_machine.rb +8 -0
  101. data/lib/deltacloud/models/storage_snapshot.rb +11 -0
  102. data/lib/deltacloud/models/storage_volume.rb +24 -0
  103. data/lib/deltacloud/server.rb +1 -3
  104. data/lib/deltacloud/version.rb +2 -1
  105. data/lib/deltacloud_rack.rb +1 -1
  106. data/tests/cimi/db/database_helper_test.rb +190 -0
  107. data/tests/cimi/db/db_helper.rb +30 -0
  108. data/tests/cimi/db/schema_test.rb +94 -0
  109. data/tests/cimi/model/collection_spec.rb +0 -1
  110. data/tests/cimi/model/machine_spec.rb +17 -0
  111. data/tests/cimi/spec_helper.rb +3 -2
  112. data/tests/deltacloud/collections/buckets_collection_test.rb +3 -0
  113. data/tests/deltacloud/collections/drivers_collection_test.rb +10 -0
  114. data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +4 -0
  115. data/tests/deltacloud/collections/images_collection_test.rb +4 -0
  116. data/tests/deltacloud/collections/instances_collection_test.rb +14 -1
  117. data/tests/deltacloud/collections/keys_collection_test.rb +4 -0
  118. data/tests/deltacloud/collections/realms_collection_test.rb +47 -0
  119. data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +47 -0
  120. data/tests/deltacloud/collections/storage_volumes_collection_test.rb +47 -0
  121. data/tests/deltacloud/common.rb +15 -0
  122. data/tests/deltacloud/deltacloud_helper_test.rb +0 -4
  123. data/tests/deltacloud/launcher_test.rb +108 -0
  124. data/tests/drivers/ec2/buckets_test.rb +2 -1
  125. data/tests/drivers/mock/buckets_test.rb +27 -0
  126. data/tests/drivers/mock/instances_test.rb +6 -0
  127. data/tests/drivers/openstack/common.rb +1 -1
  128. data/tests/drivers/openstack/hardware_profiles_test.rb +2 -1
  129. data/tests/drivers/openstack/instances_test.rb +18 -17
  130. data/tests/drivers/rhevm/common.rb +1 -0
  131. data/tests/drivers/rhevm/images_test.rb +1 -1
  132. data/tests/drivers/rhevm/instance_test.rb +7 -7
  133. data/tests/helpers/rack/rack_matrix_params_test.rb +0 -2
  134. data/tests/test_helper.rb +2 -1
  135. data/views/errors/403.xml.haml +6 -0
  136. data/views/errors/409.html.haml +47 -0
  137. data/views/errors/409.xml.haml +11 -0
  138. data/views/errors/502.html.haml +6 -5
  139. data/views/images/show.xml.haml +3 -2
  140. data/views/instances/new.html.haml +1 -1
  141. metadata +77 -30
@@ -19,4 +19,16 @@ class Firewall < BaseModel
19
19
  attr_accessor :description
20
20
  attr_accessor :owner_id
21
21
  attr_accessor :rules
22
- end
22
+
23
+ def to_hash(context)
24
+ r = {
25
+ :id => self.id,
26
+ :name => name,
27
+ :description => description,
28
+ :owner_id => owner_id,
29
+ :rules => []
30
+ }
31
+ r[:rules] = rules.map { |rule| rule.to_hash(context) } if rules and !rules.empty?
32
+ r
33
+ end
34
+ end
@@ -22,4 +22,18 @@ class FirewallRule < BaseModel
22
22
  attr_accessor :direction #ingress egress
23
23
  attr_accessor :rule_action #Accept/Deny - initially added for FGCP
24
24
  attr_accessor :log_rule #log when rule triggered true/false - added for FGCP
25
+
26
+ def to_hash(context)
27
+ {
28
+ :id => self.id,
29
+ :allow_protocol => allow_protocol,
30
+ :port_from => port_from,
31
+ :port_to => port_to,
32
+ :sources => sources,
33
+ :direction => direction,
34
+ :rule_action => rule_action,
35
+ :log_rule => log_rule
36
+ }.delete_if { |k, v| v.nil? }
37
+ end
38
+
25
39
  end
@@ -75,6 +75,7 @@ module Deltacloud
75
75
  return false unless p = property(prop)
76
76
  return true if p.kind == :range and (p.first..p.last).include?(v)
77
77
  return true if p.kind == :enum and p.values.include?(v)
78
+ return true if p.kind == :fixed and p.value == v
78
79
  false
79
80
  end
80
81
 
@@ -84,6 +85,15 @@ module Deltacloud
84
85
  }.compact
85
86
  end
86
87
 
88
+ def to_hash(context)
89
+ r = {
90
+ :id => self.id,
91
+ :name => name,
92
+ }
93
+ r.merge!({:properties => @properties}) if !@properties.empty?
94
+ r
95
+ end
96
+
87
97
  class Property
88
98
  attr_reader :name, :kind, :default
89
99
  # kind == :range
@@ -112,6 +122,10 @@ module Deltacloud
112
122
  @default = opts[:default] if opts[:default]
113
123
  end
114
124
 
125
+ def to_s
126
+ "#{@default}"
127
+ end
128
+
115
129
  def unit
116
130
  HardwareProfile.unit(name)
117
131
  end
@@ -25,4 +25,19 @@ class Image < BaseModel
25
25
  attr_accessor :hardware_profiles
26
26
  attr_accessor :creation_time
27
27
 
28
+ def to_hash(context)
29
+ {
30
+ :id => self.id,
31
+ :name => name,
32
+ :description => description,
33
+ :owner => owner_id,
34
+ :architecture => architecture,
35
+ :state => state,
36
+ :creation_time => creation_time,
37
+ :hardware_profiles => hardware_profiles.map { |p|
38
+ { :id => p.id, :href => context.hardware_profile_url(p.id), :rel => :hardware_profile }
39
+ }
40
+ }
41
+ end
42
+
28
43
  end
@@ -38,6 +38,45 @@ class Instance < BaseModel
38
38
  attr_accessor :firewalls
39
39
  attr_accessor :storage_volumes
40
40
 
41
+ def to_hash(context)
42
+ r = {
43
+ :id => self.id,
44
+ :name => name,
45
+ :state => state,
46
+ :owner => owner_id,
47
+ :image => { :href => context.image_url(image_id), :id => image_id, :rel => :image },
48
+ :realm => { :href => context.realm_url(realm_id), :id => realm_id, :rel => :realm },
49
+ :actions => actions.compact.map { |a|
50
+ {
51
+ :href => context.send("#{a}_instance_url", self.id),
52
+ :rel => "#{a}",
53
+ :method => context.instance_action_method(a)
54
+ }
55
+ },
56
+ :instance_profile => {
57
+ :id => instance_profile.id,
58
+ :href => context.hardware_profile_url(instance_profile.id),
59
+ :rel => :hardware_profile,
60
+ :properties => instance_profile.overrides
61
+ },
62
+ :public_addresses => public_addresses.map { |addr| addr.to_hash(context) },
63
+ :private_addresses => private_addresses.map { |addr| addr.to_hash(context) }
64
+ }
65
+ r.merge!(:launch_time => launch_time)
66
+ r.merge!(:create_image => create_image) if create_image
67
+ r.merge!(:firewalls => firewalls.map { |f| { :id => f, :href => context.firewall_url(f), :rel => :firewall }}) if firewalls
68
+ if storage_volumes
69
+ r.merge!(:storage_volumes => storage_volumes.map { |v| { :id => v.keys.first, :href => context.storage_volume_url(v.keys.first), :rel => :storage_volume }})
70
+ end
71
+ if context.driver.class.has_feature?(:instances, :authentication_key)
72
+ r.merge!(:authentication => { :keyname => keyname }) if keyname
73
+ end
74
+ if context.driver.class.has_feature?(:instances, :authentication_password)
75
+ r.merge!(:authentication => { :user => username, :password => password }) if username
76
+ end
77
+ r
78
+ end
79
+
41
80
  def storage_volumes
42
81
  @storage_volumes || []
43
82
  end
@@ -51,7 +90,7 @@ class Instance < BaseModel
51
90
  end
52
91
 
53
92
  def hardware_profile=(profile)
54
- instance_profile = profile
93
+ @instance_profile = profile
55
94
  end
56
95
 
57
96
  def initialize(init=nil)
@@ -37,6 +37,15 @@ class InstanceAddress
37
37
  address
38
38
  end
39
39
 
40
+ def to_hash(context)
41
+ r = {
42
+ :address => address,
43
+ :type => address_type
44
+ }
45
+ r.merge!(:port => port) if !port.nil?
46
+ r
47
+ end
48
+
40
49
  def is_mac?
41
50
  address_type == :mac
42
51
  end
@@ -51,4 +51,19 @@ class Key < BaseModel
51
51
  "-----BEGIN RSA PRIVATE KEY-----\n"+pem_material+"-----END RSA PRIVATE KEY-----"
52
52
  end
53
53
 
54
+ def to_hash(context)
55
+ r = {
56
+ :id => self.id,
57
+ :credential_type => credential_type,
58
+ :username => username,
59
+ :password => password,
60
+ :state => state
61
+ }
62
+ r[:pem_rsa_key] = pem_rsa_key if pem_rsa_key
63
+ r[:fingerprint] = fingerprint if fingerprint
64
+ r[:username] = username if username
65
+ r[:password] = password if password
66
+ r
67
+ end
68
+
54
69
  end
@@ -27,10 +27,30 @@ class LoadBalancer < BaseModel
27
27
  @listeners << Listener.new(opts)
28
28
  end
29
29
 
30
+ def to_hash(context)
31
+ {
32
+ :id => self.id,
33
+ :realms => realms,
34
+ :listeners => listeners.map { |l| l.to_hash(context) },
35
+ :instances => instances.map { |i| i.to_hash(context) },
36
+ :public_addresses => public_addresses,
37
+ :created_at => created_at
38
+ }
39
+ end
40
+
30
41
  class Listener < BaseModel
31
42
  attr_accessor :protocol
32
43
  attr_accessor :load_balancer_port
33
44
  attr_accessor :instance_port
45
+
46
+ def to_hash(context)
47
+ {
48
+ :id => self.id,
49
+ :protocol => protocol,
50
+ :load_balancer_port => load_balancer_port,
51
+ :instance_port => instance_port
52
+ }
53
+ end
34
54
  end
35
55
 
36
56
  end
@@ -29,12 +29,27 @@ class Metric < BaseModel
29
29
  self
30
30
  end
31
31
 
32
+ def to_hash(context)
33
+ {
34
+ :id => self.id,
35
+ :entity => entity,
36
+ :properties => properties.map { |p| p.to_hash(context) }
37
+ }
38
+ end
39
+
32
40
  class Property
33
41
  attr_accessor :name, :values
34
42
 
35
43
  def initialize(name, values=nil)
36
44
  @name, @values = name, values
37
45
  end
46
+
47
+ def to_hash(context)
48
+ {
49
+ :name => name,
50
+ :values => values
51
+ }
52
+ end
38
53
  end
39
54
 
40
55
  end
@@ -24,4 +24,12 @@ class Provider < BaseModel
24
24
  super(opts)
25
25
  end
26
26
 
27
+ def to_hash(context)
28
+ {
29
+ :id => self.id,
30
+ :name => name,
31
+ :url => url
32
+ }
33
+ end
34
+
27
35
  end
@@ -21,4 +21,13 @@ class Realm < BaseModel
21
21
  attr_accessor :limit
22
22
  attr_accessor :state
23
23
 
24
+ def to_hash(context)
25
+ {
26
+ :id => self.id,
27
+ :name => name,
28
+ :state => state,
29
+ :limit => limit
30
+ }
31
+ end
32
+
24
33
  end
@@ -81,6 +81,14 @@ module Deltacloud
81
81
  transition
82
82
  end
83
83
 
84
+ def from(*states)
85
+ states.each do |s|
86
+ initial = @machine.state(s)
87
+ trans = initial.to self.name
88
+ trans.automatically
89
+ end
90
+ end
91
+
84
92
  end
85
93
 
86
94
  class Transition
@@ -21,9 +21,20 @@ class StorageSnapshot < BaseModel
21
21
  attr_accessor :state
22
22
  attr_accessor :storage_volume_id
23
23
  attr_accessor :created
24
+ attr_accessor :name
25
+ attr_accessor :description
24
26
 
25
27
  def is_completed?
26
28
  state == 'completed'
27
29
  end
28
30
 
31
+ def to_hash(context)
32
+ {
33
+ :id => self.id,
34
+ :state => state,
35
+ :storage_volume => { :id => storage_volume_id, :href => context.storage_volume_url(storage_volume_id), :rel => :storage_volume },
36
+ :created => created
37
+ }
38
+ end
39
+
29
40
  end
@@ -26,5 +26,29 @@ class StorageVolume < BaseModel
26
26
  attr_accessor :actions
27
27
  attr_accessor :name
28
28
  attr_accessor :kind
29
+ attr_accessor :description # openstack volumes have a display_description attr
30
+
31
+ def to_hash(context)
32
+ r = {
33
+ :id => self.id,
34
+ :name => name,
35
+ :description => description,
36
+ :state => state,
37
+ :created => created,
38
+ :realm => { :id => realm_id, :href => context.realm_url(realm_id), :rel => :realm },
39
+ :device => device,
40
+ :kind => kind,
41
+ :capacity => capacity,
42
+ }
43
+ r[:actions] = (actions || []).map { |a|
44
+ { :href => context.send("#{a}_storage_volume", self.id), :rel => a }
45
+ }
46
+ if instance_id
47
+ r[:instance] = { :id => instance_id, :href => context.instance_url(instance_id), :rel => :instance }
48
+ else
49
+ r[:instance] = {}
50
+ end
51
+ r
52
+ end
29
53
 
30
54
  end
@@ -14,8 +14,6 @@
14
14
  # under the License.
15
15
 
16
16
  require 'rubygems'
17
- require 'crack'
18
- require 'json'
19
17
  require 'yaml'
20
18
  require 'haml'
21
19
  require 'sinatra/base'
@@ -52,7 +50,7 @@ module Deltacloud
52
50
  @collections = driver.supported_collections(credentials)
53
51
  respond_to do |format|
54
52
  format.xml { haml :"api/show" }
55
- format.json { xml_to_json :"api/show" }
53
+ format.json { collections_to_json(@collections) }
56
54
  format.html { haml :"api/show" }
57
55
  end
58
56
  end
@@ -15,5 +15,6 @@
15
15
  # under the License.
16
16
 
17
17
  module Deltacloud
18
- API_VERSION = '1.0.5' unless defined?(API_VERSION)
18
+ API_VERSION = '1.1.0'
19
+ CIMI_API_VERSION = '1.0.1'
19
20
  end
@@ -14,6 +14,7 @@
14
14
  # under the License.
15
15
 
16
16
  require 'require_relative' if RUBY_VERSION < '1.9'
17
+ require 'json/pure'
17
18
 
18
19
  require_relative './deltacloud/core_ext'
19
20
  require_relative './sinatra/rack_logger'
@@ -71,7 +72,6 @@ module Deltacloud
71
72
  respond_to do |format|
72
73
  format.xml { haml :'index', :layout => false }
73
74
  format.html { haml :'index', :layout => false }
74
- format.json { xml_to_json "index" }
75
75
  end
76
76
  end
77
77
  end
@@ -0,0 +1,190 @@
1
+ require 'rubygems'
2
+ require 'require_relative' if RUBY_VERSION < '1.9'
3
+ require 'minitest/autorun'
4
+
5
+ require_relative 'db_helper.rb'
6
+ require_relative '../spec_helper.rb'
7
+ require_relative './../collections/common.rb'
8
+
9
+ class DatabaseHelper
10
+ include Deltacloud::Helpers::Database
11
+ end
12
+
13
+ describe Deltacloud::Helpers::Database do
14
+ include Deltacloud::DatabaseTestHelper
15
+
16
+ before do
17
+ ENV['RACK_ENV'] = 'development'
18
+ @db = DatabaseHelper.new
19
+ end
20
+
21
+ it 'report if application is running under test environment' do
22
+ ENV['RACK_ENV'] = 'test'
23
+ @db.test_environment?.must_equal true
24
+ ENV['RACK_ENV'] = 'development'
25
+ @db.test_environment?.must_equal false
26
+ end
27
+
28
+ it 'report if given entity is provided by database' do
29
+ @db.provides?('machine_template').must_equal true
30
+ @db.provides?('machine').must_equal false
31
+ end
32
+
33
+ it 'reports the current provider' do
34
+ @db.current_provider.must_equal 'default'
35
+ end
36
+
37
+ it 'create provider when it does not exists' do
38
+ @db.current_db.must_be_kind_of Deltacloud::Database::Provider
39
+ @db.current_db.driver.must_equal 'mock'
40
+ @db.current_db.url.must_equal @db.current_provider
41
+ @db.current_db.must_respond_to :entities
42
+ @db.current_db.must_respond_to :machine_templates
43
+ @db.current_db.must_respond_to :address_templates
44
+ @db.current_db.must_respond_to :volume_configurations
45
+ @db.current_db.must_respond_to :volume_templates
46
+ end
47
+
48
+ it 'extract attributes both from JSON and XMLSimple' do
49
+ xml_simple_test = { 'property' => [ { 'key' => 'template', 'content' => "value"} ] }
50
+ json_test = { 'properties' => { 'template' => 'value' } }
51
+
52
+ @db.extract_attribute_value('property', xml_simple_test).must_equal('template' => 'value')
53
+ @db.extract_attribute_value('properties', json_test).must_equal('template' => 'value')
54
+ end
55
+
56
+ it 'must return entity for given model' do
57
+ provider = Deltacloud::Database::Provider
58
+ entity = Deltacloud::Database::Entity
59
+ @db.current_db.wont_be_nil
60
+
61
+ new_entity = @db.current_db.add_entity(
62
+ :name => 'testMachine1',
63
+ :description => 'testMachine1 description',
64
+ :ent_properties => JSON::dump(:key => 'value'),
65
+ :be_kind => 'instance',
66
+ :be_id => 'inst1'
67
+ )
68
+
69
+ check_entity_base_attrs new_entity, entity, @db.current_db
70
+
71
+ result = @db.get_entity(Instance.new(:id => 'inst1'))
72
+ result.must_equal new_entity
73
+
74
+ new_entity.destroy.wont_equal false
75
+ end
76
+
77
+ it 'must load attributes for entity for given model' do
78
+ provider = Deltacloud::Database::Provider
79
+ entity = Deltacloud::Database::Entity
80
+ @db.current_db.wont_be_nil
81
+
82
+ new_entity = @db.current_db.add_entity(
83
+ :name => 'testMachine1',
84
+ :description => 'testMachine1 description',
85
+ :ent_properties => JSON::dump(:key => 'value'),
86
+ :be_kind => 'instance',
87
+ :be_id => 'inst1'
88
+ )
89
+
90
+ check_entity_base_attrs new_entity, entity, @db.current_db
91
+
92
+ result = @db.load_attributes_for(Instance.new(:id => 'inst1'))
93
+ result.must_be_kind_of Hash
94
+ result[:name].must_equal new_entity.name
95
+ result[:description].must_equal new_entity.description
96
+ result[:property].must_equal JSON::parse(new_entity.ent_properties)
97
+
98
+ new_entity.destroy.wont_equal false
99
+ end
100
+
101
+ it 'must delete attributes for entity for given model' do
102
+ provider = Deltacloud::Database::Provider
103
+ entity = Deltacloud::Database::Entity
104
+ @db.current_db.wont_be_nil
105
+
106
+ new_entity = @db.current_db.add_entity(
107
+ :name => 'testMachine1',
108
+ :description => 'testMachine1 description',
109
+ :ent_properties => JSON::dump(:key => 'value'),
110
+ :be_kind => 'instance',
111
+ :be_id => 'inst1'
112
+ )
113
+
114
+ check_entity_base_attrs new_entity, entity, @db.current_db
115
+
116
+ result = @db.delete_attributes_for(Instance.new(:id => 'inst1'))
117
+ result.wont_equal false
118
+ result.exists?.must_equal false
119
+ end
120
+
121
+ it 'must store JSON attributes for entity for given model' do
122
+ provider = Deltacloud::Database::Provider
123
+ entity = Deltacloud::Database::Entity
124
+ @db.current_db.wont_be_nil
125
+
126
+ mock_instance = Instance.new(:id => 'inst1')
127
+ mock_json = '
128
+ {
129
+ "resourceURI": "http://schemas.dmtf.org/cimi/1/MachineCreate",
130
+ "name": "myDatabaseMachine",
131
+ "description": "This is a demo machine",
132
+ "properties": {
133
+ "foo": "bar",
134
+ "life": "is life"
135
+ },
136
+ "machineTemplate": {
137
+ "machineConfig": { "href": "http://localhost:3001/cimi/machine_configurations/m1-small" },
138
+ "machineImage": { "href": "http://localhost:3001/cimi/machine_images/img1" }
139
+ }
140
+ }
141
+ '
142
+ result = @db.store_attributes_for(mock_instance, JSON::parse(mock_json))
143
+ result.must_be_kind_of entity
144
+ check_entity_base_attrs result, entity, @db.current_db
145
+ load_result = @db.load_attributes_for(mock_instance)
146
+ load_result.must_be_kind_of Hash
147
+ load_result.wont_be_empty
148
+ load_result[:name].must_equal 'myDatabaseMachine'
149
+ load_result[:description].must_equal 'This is a demo machine'
150
+ load_result[:property].must_be_kind_of Hash
151
+ load_result[:property].wont_be_empty
152
+ load_result[:property]['foo'].must_equal 'bar'
153
+ load_result[:property]['life'].must_equal 'is life'
154
+ result.destroy.wont_equal false
155
+ end
156
+
157
+ it 'must store XML attributes for entity for given model' do
158
+ provider = Deltacloud::Database::Provider
159
+ entity = Deltacloud::Database::Entity
160
+ @db.current_db.wont_be_nil
161
+
162
+ mock_instance = Instance.new(:id => 'inst1')
163
+ mock_xml = '
164
+ <MachineCreate>
165
+ <name>myMachineXML123</name>
166
+ <description>Description of my new Machine</description>
167
+ <machineTemplate>
168
+ <machineConfig href="http://localhost:3001/cimi/machine_configurations/m1-small"/>
169
+ <machineImage href="http://localhost:3001/cimi/machine_images/img1"/>
170
+ </machineTemplate>
171
+ <property key="test">value</property>
172
+ <property key="foo">bar</property>
173
+ </MachineCreate>
174
+ '
175
+ result = @db.store_attributes_for(mock_instance, XmlSimple.xml_in(mock_xml))
176
+ result.must_be_kind_of entity
177
+ check_entity_base_attrs result, entity, @db.current_db
178
+ load_result = @db.load_attributes_for(mock_instance)
179
+ load_result.must_be_kind_of Hash
180
+ load_result.wont_be_empty
181
+ load_result[:name].must_equal 'myMachineXML123'
182
+ load_result[:description].must_equal 'Description of my new Machine'
183
+ load_result[:property].must_be_kind_of Hash
184
+ load_result[:property].wont_be_empty
185
+ load_result[:property]['test'].must_equal 'value'
186
+ result.destroy.wont_equal false
187
+ end
188
+
189
+
190
+ end