deltacloud-core 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. data/Rakefile +40 -28
  2. data/bin/deltacloud-db-upgrade +24 -0
  3. data/bin/deltacloudd +20 -9
  4. data/config.ru +12 -53
  5. data/db/migrations/1_add_realm_to_machine_template.rb +23 -0
  6. data/deltacloud-core.gemspec +11 -5
  7. data/lib/cimi/collections.rb +4 -31
  8. data/lib/cimi/collections/address_templates.rb +2 -5
  9. data/lib/cimi/collections/addresses.rb +2 -5
  10. data/lib/cimi/collections/base.rb +18 -6
  11. data/lib/cimi/collections/credentials.rb +2 -5
  12. data/lib/cimi/collections/machine_images.rb +2 -1
  13. data/lib/cimi/collections/machine_templates.rb +2 -5
  14. data/lib/cimi/collections/machines.rb +6 -9
  15. data/lib/cimi/collections/network_ports.rb +3 -3
  16. data/lib/cimi/collections/networks.rb +5 -8
  17. data/lib/cimi/collections/system_templates.rb +72 -0
  18. data/lib/cimi/collections/systems.rb +194 -0
  19. data/lib/cimi/collections/volume_configurations.rb +1 -1
  20. data/lib/cimi/collections/volume_images.rb +2 -1
  21. data/lib/cimi/collections/volume_templates.rb +3 -2
  22. data/lib/cimi/collections/volumes.rb +2 -2
  23. data/lib/cimi/dependencies.rb +0 -2
  24. data/lib/cimi/helpers/cimi_helper.rb +12 -57
  25. data/lib/cimi/helpers/database_helper.rb +0 -4
  26. data/lib/cimi/models.rb +25 -14
  27. data/lib/cimi/models/address.rb +4 -31
  28. data/lib/cimi/models/address_create.rb +51 -0
  29. data/lib/cimi/models/address_template.rb +8 -52
  30. data/lib/cimi/models/address_template_create.rb +44 -0
  31. data/lib/cimi/models/base.rb +44 -6
  32. data/lib/cimi/models/cloud_entry_point.rb +1 -1
  33. data/lib/cimi/models/credential.rb +1 -1
  34. data/lib/cimi/models/credential_create.rb +46 -0
  35. data/lib/cimi/models/credential_template.rb +24 -0
  36. data/lib/cimi/models/machine.rb +1 -71
  37. data/lib/cimi/models/machine_configuration.rb +3 -3
  38. data/lib/cimi/models/machine_create.rb +49 -0
  39. data/lib/cimi/models/machine_image.rb +2 -25
  40. data/lib/cimi/models/machine_image_create.rb +41 -0
  41. data/lib/cimi/models/machine_template.rb +14 -34
  42. data/lib/cimi/models/machine_template_create.rb +33 -0
  43. data/lib/cimi/models/network.rb +0 -38
  44. data/lib/cimi/models/network_create.rb +43 -0
  45. data/lib/cimi/models/network_port.rb +17 -17
  46. data/lib/cimi/models/network_template.rb +2 -3
  47. data/lib/cimi/models/resource.rb +22 -3
  48. data/lib/cimi/models/schema.rb +94 -8
  49. data/lib/cimi/models/system.rb +67 -0
  50. data/lib/cimi/models/system_template.rb +63 -0
  51. data/lib/cimi/models/volume.rb +2 -42
  52. data/lib/cimi/models/volume_configuration.rb +4 -4
  53. data/lib/cimi/models/volume_create.rb +58 -0
  54. data/lib/cimi/models/volume_image.rb +8 -17
  55. data/lib/cimi/models/volume_image_create.rb +47 -0
  56. data/lib/cimi/models/volume_template.rb +6 -19
  57. data/lib/cimi/models/volume_template_create.rb +33 -0
  58. data/lib/db.rb +14 -22
  59. data/lib/db/volume_template.rb +1 -1
  60. data/lib/deltacloud/api.rb +6 -5
  61. data/lib/deltacloud/collections.rb +4 -27
  62. data/lib/deltacloud/collections/base.rb +4 -0
  63. data/lib/deltacloud/collections/images.rb +1 -1
  64. data/lib/deltacloud/collections/instances.rb +2 -2
  65. data/lib/deltacloud/core_ext/array.rb +1 -0
  66. data/lib/deltacloud/core_ext/integer.rb +13 -9
  67. data/lib/deltacloud/core_ext/string.rb +45 -28
  68. data/lib/deltacloud/drivers/arubacloud/arubacloud_driver.rb +0 -9
  69. data/lib/deltacloud/drivers/base_driver.rb +45 -16
  70. data/lib/deltacloud/drivers/digitalocean/digitalocean_driver.rb +78 -8
  71. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +13 -9
  72. data/lib/deltacloud/drivers/fgcp/fgcp_client.rb +44 -0
  73. data/lib/deltacloud/drivers/fgcp/fgcp_driver.rb +164 -90
  74. data/lib/deltacloud/drivers/fgcp/fgcp_driver_cimi_methods.rb +74 -0
  75. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +3 -3
  76. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +3 -3
  77. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +3 -3
  78. data/lib/deltacloud/drivers/mock/mock_client.rb +17 -1
  79. data/lib/deltacloud/drivers/mock/mock_driver.rb +161 -204
  80. data/lib/deltacloud/drivers/mock/mock_driver_cimi_methods.rb +80 -0
  81. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +6 -1
  82. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +61 -68
  83. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +0 -9
  84. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +11 -6
  85. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +0 -8
  86. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +11 -4
  87. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +0 -12
  88. data/lib/deltacloud/helpers/collection_helper.rb +106 -0
  89. data/lib/deltacloud/helpers/deltacloud_helper.rb +12 -8
  90. data/lib/deltacloud/models/address.rb +19 -17
  91. data/lib/deltacloud/models/base_model.rb +29 -26
  92. data/lib/deltacloud/models/blob.rb +22 -20
  93. data/lib/deltacloud/models/bucket.rb +21 -16
  94. data/lib/deltacloud/models/firewall.rb +18 -16
  95. data/lib/deltacloud/models/firewall_rule.rb +22 -20
  96. data/lib/deltacloud/models/image.rb +29 -28
  97. data/lib/deltacloud/models/instance.rb +92 -94
  98. data/lib/deltacloud/models/instance_address.rb +42 -40
  99. data/lib/deltacloud/models/instance_profile.rb +28 -26
  100. data/lib/deltacloud/models/key.rb +47 -45
  101. data/lib/deltacloud/models/load_balancer.rb +32 -31
  102. data/lib/deltacloud/models/metric.rb +76 -29
  103. data/lib/deltacloud/models/provider.rb +15 -13
  104. data/lib/deltacloud/models/realm.rb +15 -21
  105. data/lib/deltacloud/models/storage_snapshot.rb +23 -19
  106. data/lib/deltacloud/models/storage_volume.rb +35 -34
  107. data/lib/deltacloud/version.rb +1 -1
  108. data/lib/deltacloud_rack.rb +22 -0
  109. data/lib/initialize.rb +28 -0
  110. data/lib/initializers/database_initialize.rb +76 -0
  111. data/lib/initializers/frontend_initialize.rb +42 -0
  112. data/lib/initializers/mock_initialize.rb +33 -0
  113. data/lib/sinatra/rack_logger.rb +35 -24
  114. data/tests/cimi/collections/cloud_entry_point_test.rb +1 -7
  115. data/tests/cimi/collections/machine_images_test.rb +2 -2
  116. data/tests/cimi/collections/machine_templates_test.rb +75 -0
  117. data/tests/cimi/collections/machines_test.rb +2 -2
  118. data/tests/cimi/collections/system_templates_test.rb +41 -0
  119. data/tests/cimi/collections/systems_test.rb +50 -0
  120. data/tests/cimi/db/database_helper_test.rb +17 -25
  121. data/tests/cimi/db/db_helper.rb +1 -12
  122. data/tests/cimi/db/entity_test.rb +7 -8
  123. data/tests/cimi/model/machine_create_spec.rb +44 -0
  124. data/tests/cimi/model/machine_template_spec.rb +29 -0
  125. data/tests/cimi/model/resource_spec.rb +40 -0
  126. data/tests/cimi/model/schema_spec.rb +37 -0
  127. data/tests/cimi/spec_helper.rb +3 -0
  128. data/tests/deltacloud/collections/buckets_collection_test.rb +1 -1
  129. data/tests/deltacloud/collections/drivers_collection_test.rb +2 -2
  130. data/tests/deltacloud/collections/hardware_profiles_collection_test.rb +2 -2
  131. data/tests/deltacloud/collections/images_collection_test.rb +2 -2
  132. data/tests/deltacloud/collections/instance_states_collection_test.rb +1 -1
  133. data/tests/deltacloud/collections/instances_collection_test.rb +6 -3
  134. data/tests/deltacloud/collections/keys_collection_test.rb +2 -2
  135. data/tests/deltacloud/collections/realms_collection_test.rb +2 -2
  136. data/tests/deltacloud/collections/storage_snapshots_collection_test.rb +2 -2
  137. data/tests/deltacloud/collections/storage_volumes_collection_test.rb +2 -2
  138. data/tests/deltacloud/collections_test.rb +5 -5
  139. data/tests/deltacloud/common.rb +2 -13
  140. data/tests/deltacloud/launcher_test.rb +3 -3
  141. data/tests/deltacloud/rack_test.rb +2 -2
  142. data/tests/deltacloud/server_test.rb +1 -1
  143. data/tests/drivers/base/base_driver_test.rb +5 -5
  144. data/tests/drivers/base/common.rb +2 -12
  145. data/tests/drivers/ec2/buckets_test.rb +1 -1
  146. data/tests/drivers/ec2/images_test.rb +2 -2
  147. data/tests/drivers/ec2/instance_test.rb +6 -6
  148. data/tests/drivers/ec2/keys_test.rb +3 -3
  149. data/tests/drivers/ec2/realms_test.rb +2 -2
  150. data/tests/drivers/ec2/storage_snapshots_test.rb +1 -1
  151. data/tests/drivers/fgcp/common.rb +32 -0
  152. data/tests/drivers/fgcp/firewall_test.rb +70 -0
  153. data/tests/drivers/fgcp/hardware_profiles_test.rb +61 -0
  154. data/tests/drivers/fgcp/images_test.rb +46 -0
  155. data/tests/drivers/fgcp/provider_test.rb +27 -0
  156. data/tests/drivers/fgcp/realms_test.rb +53 -0
  157. data/tests/drivers/fgcp/storage_volumes_test.rb +58 -0
  158. data/tests/drivers/gogrid/images_test.rb +2 -2
  159. data/tests/drivers/gogrid/instances_test.rb +2 -2
  160. data/tests/drivers/gogrid/realms_test.rb +2 -2
  161. data/tests/drivers/mock/images_test.rb +4 -4
  162. data/tests/drivers/mock/instances_test.rb +9 -9
  163. data/tests/drivers/mock/keys_test.rb +3 -3
  164. data/tests/drivers/mock/realms_test.rb +2 -2
  165. data/tests/drivers/mock/storage_snapshots_test.rb +2 -2
  166. data/tests/drivers/mock/storage_volumes_test.rb +4 -4
  167. data/tests/drivers/models/instance_test.rb +2 -2
  168. data/tests/drivers/openstack/images_test.rb +2 -2
  169. data/tests/drivers/openstack/instances_test.rb +2 -3
  170. data/tests/drivers/openstack/keys_test.rb +1 -1
  171. data/tests/drivers/openstack/realms_test.rb +2 -11
  172. data/tests/drivers/rhevm/common.rb +33 -12
  173. data/tests/drivers/rhevm/images_test.rb +20 -12
  174. data/tests/drivers/rhevm/instance_test.rb +62 -46
  175. data/tests/drivers/rhevm/provider_test.rb +12 -6
  176. data/tests/drivers/rhevm/realms_test.rb +15 -9
  177. data/tests/ec2/query_parser_test.rb +1 -1
  178. data/tests/test_helper.rb +68 -12
  179. data/views/addresses/show.html.haml +1 -1
  180. data/views/buckets/show.html.haml +1 -1
  181. data/views/errors/{500.html.haml → common.html.haml} +0 -0
  182. data/views/errors/common.xml.haml +17 -0
  183. data/views/firewalls/index.xml.haml +2 -2
  184. data/views/firewalls/new.html.haml +2 -2
  185. data/views/images/show.html.haml +1 -1
  186. data/views/instances/run_command.html.haml +1 -1
  187. data/views/instances/show.html.haml +3 -3
  188. data/views/keys/index.html.haml +1 -0
  189. data/views/keys/show.html.haml +8 -4
  190. data/views/keys/show.xml.haml +3 -2
  191. data/views/load_balancers/new.html.haml +1 -1
  192. data/views/load_balancers/show.html.haml +2 -2
  193. data/views/metrics/show.html.haml +1 -1
  194. data/views/realms/index.html.haml +0 -2
  195. data/views/realms/show.html.haml +0 -4
  196. data/views/realms/show.xml.haml +0 -3
  197. data/views/storage_snapshots/index.html.haml +1 -1
  198. data/views/storage_snapshots/new.html.haml +1 -1
  199. data/views/storage_volumes/new.html.haml +2 -2
  200. data/views/storage_volumes/show.html.haml +3 -3
  201. metadata +90 -41
  202. data/views/errors/400.html.haml +0 -41
  203. data/views/errors/400.xml.haml +0 -3
  204. data/views/errors/401.html.haml +0 -26
  205. data/views/errors/401.xml.haml +0 -3
  206. data/views/errors/403.html.haml +0 -42
  207. data/views/errors/403.xml.haml +0 -9
  208. data/views/errors/404.html.haml +0 -28
  209. data/views/errors/404.xml.haml +0 -3
  210. data/views/errors/405.html.haml +0 -29
  211. data/views/errors/405.xml.haml +0 -5
  212. data/views/errors/409.html.haml +0 -47
  213. data/views/errors/409.xml.haml +0 -11
  214. data/views/errors/500.xml.haml +0 -13
  215. data/views/errors/501.html.haml +0 -44
  216. data/views/errors/501.xml.haml +0 -1
  217. data/views/errors/502.html.haml +0 -44
  218. data/views/errors/502.xml.haml +0 -1
  219. data/views/errors/504.html.haml +0 -43
  220. data/views/errors/504.xml.haml +0 -1
@@ -16,6 +16,10 @@
16
16
  module Deltacloud::Collections
17
17
  class Base < Sinatra::Base
18
18
 
19
+ Sinatra::Rabbit.configure do
20
+ enable :use_namespace
21
+ end
22
+
19
23
  include Sinatra::Rabbit
20
24
  include Sinatra::Rabbit::Features
21
25
 
@@ -23,7 +23,7 @@ module Deltacloud::Collections
23
23
 
24
24
  new_route_for :images do
25
25
  halt 404 unless params[:instance_id]
26
- @instance = Instance.new( :id => params[:instance_id] )
26
+ @instance = Deltacloud::Instance.new( :id => params[:instance_id] )
27
27
  end
28
28
 
29
29
  collection :images do
@@ -22,10 +22,10 @@ module Deltacloud::Collections
22
22
  check_features :for => lambda { |c, f| driver.class.has_feature?(c, f) }
23
23
 
24
24
  new_route_for(:instances) do
25
- @instance = Instance.new( { :id=>params[:id], :image_id=>params[:image_id] } )
25
+ @instance = Deltacloud::Instance.new( { :id=>params[:id], :image_id=>params[:image_id] } )
26
26
  @image = driver.image(credentials, :id => params[:image_id])
27
27
  @hardware_profiles = driver.hardware_profiles(credentials, :architecture => @image.architecture )
28
- @realms = [Realm.new(:id => params[:realm_id])] if params[:realm_id]
28
+ @realms = [Deltacloud::Realm.new(:id => params[:realm_id])] if params[:realm_id]
29
29
  @realms ||= driver.realms(credentials)
30
30
  @firewalls = driver.firewalls(credentials) if driver.class.has_feature? :instances, :firewalls
31
31
  @keys = driver.keys(credentials) if driver.class.has_feature? :instances, :authentication_key
@@ -14,6 +14,7 @@
14
14
  # under the License.
15
15
 
16
16
  class Array
17
+
17
18
  def expand_opts!(more_opts)
18
19
  self << {} unless last.is_a?(Hash)
19
20
  last.update(more_opts)
@@ -15,17 +15,21 @@
15
15
  # under the License.
16
16
 
17
17
  class Integer
18
+
18
19
  # Turn integers into strings +1st+, +2nd+, +3rd+ etc.
19
- def ordinalize
20
- if (11..13).include?(self % 100)
21
- "#{self}th"
22
- else
23
- case self % 10
24
- when 1; "#{self}st"
25
- when 2; "#{self}nd"
26
- when 3; "#{self}rd"
27
- else "#{self}th"
20
+ unless method_defined? 'ordinalize'
21
+ def ordinalize
22
+ if (11..13).include?(self % 100)
23
+ "#{self}th"
24
+ else
25
+ case self % 10
26
+ when 1; "#{self}st"
27
+ when 2; "#{self}nd"
28
+ when 3; "#{self}rd"
29
+ else "#{self}th"
30
+ end
28
31
  end
29
32
  end
30
33
  end
34
+
31
35
  end
@@ -15,10 +15,13 @@
15
15
  # under the License.
16
16
 
17
17
  class String
18
+
18
19
  # Rails defines this for a number of other classes, including Object
19
20
  # see activesupport/lib/active_support/core_ext/object/blank.rb
20
- def blank?
21
+ unless method_defined? 'blank?'
22
+ def blank?
21
23
  self !~ /\S/
24
+ end
22
25
  end
23
26
 
24
27
  # Title case.
@@ -28,49 +31,63 @@ class String
28
31
  #
29
32
  # CREDIT: Eliazar Parra
30
33
  # Copied from facets
31
- def titlecase
32
- gsub(/\b\w/){ $`[-1,1] == "'" ? $& : $&.upcase }
34
+ unless method_defined? 'titlecase'
35
+ def titlecase
36
+ gsub(/\b\w/){ $`[-1,1] == "'" ? $& : $&.upcase }
37
+ end
33
38
  end
34
39
 
35
- def pluralize
36
- return self + 'es' if self =~ /ess$/
37
- return self[0, self.length-1] + "ies" if self =~ /ty$/
38
- return self if self =~ /data$/
39
- self + "s"
40
+ unless method_defined? 'pluralize'
41
+ def pluralize
42
+ return self + 'es' if self =~ /ess$/
43
+ return self[0, self.length-1] + "ies" if self =~ /ty$/
44
+ return self if self =~ /data$/
45
+ self + "s"
46
+ end
40
47
  end
41
48
 
42
- def singularize
43
- return self.gsub(/ies$/, 'y') if self =~ /ies$/
44
- return self.gsub(/es$/, '') if self =~ /sses$/
45
- self.gsub(/s$/, '')
49
+ unless method_defined? 'singularize'
50
+ def singularize
51
+ return self.gsub(/ies$/, 'y') if self =~ /ies$/
52
+ return self.gsub(/es$/, '') if self =~ /sses$/
53
+ self.gsub(/s$/, '')
54
+ end
46
55
  end
47
56
 
48
- def underscore
49
- return self.downcase if self =~ /VSPs$/i
50
- gsub(/::/, '/').
51
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
52
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
53
- tr("-", "_").
54
- downcase
57
+ unless method_defined? 'underscore'
58
+ def underscore
59
+ return self.downcase if self =~ /VSPs$/i
60
+ gsub(/::/, '/').
61
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
62
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
63
+ tr("-", "_").
64
+ downcase
65
+ end
55
66
  end
56
67
 
57
- def camelize(lowercase_first_letter=nil)
58
- s = split('_').map { |w| w.capitalize }.join
59
- lowercase_first_letter ? s.uncapitalize : s
68
+ unless method_defined? 'camelize'
69
+ def camelize(lowercase_first_letter=nil)
70
+ s = split('_').map { |w| w.capitalize }.join
71
+ lowercase_first_letter ? s.uncapitalize : s
72
+ end
60
73
  end
61
74
 
62
- def uncapitalize
63
- self[0, 1].downcase + self[1..-1]
75
+ unless method_defined? 'uncapitalize'
76
+ def uncapitalize
77
+ self[0, 1].downcase + self[1..-1]
78
+ end
64
79
  end
65
80
 
66
81
  def upcase_first
67
82
  self[0, 1].upcase + self[1..-1]
68
83
  end
69
84
 
70
- def truncate(length = 10)
71
- return self if self.length <= length
72
- end_string = "...#{self[(self.length-(length/2))..self.length]}"
73
- "#{self[0..(length/2)]}#{end_string}"
85
+ unless method_defined? 'truncate'
86
+ def truncate(length = 10)
87
+ return self if self.length <= length
88
+ end_string = "...#{self[(self.length-(length/2))..self.length]}"
89
+ "#{self[0..(length/2)]}#{end_string}"
90
+ end
74
91
  end
75
92
 
76
93
  def remove_matrix_params
@@ -61,15 +61,6 @@ class ArubacloudDriver < Deltacloud::BaseDriver
61
61
  architecture ['x86_64', 'i386']
62
62
  end
63
63
 
64
- def valid_credentials?(credentials)
65
- begin
66
- new_client(credentials)
67
- rescue
68
- return false
69
- end
70
- true
71
- end
72
-
73
64
  def realms(credentials, opts=nil)
74
65
  client = new_client(credentials)
75
66
  safely do
@@ -25,6 +25,7 @@ module Deltacloud
25
25
  class BaseDriver
26
26
 
27
27
  include Exceptions
28
+ include Deltacloud
28
29
 
29
30
  STATE_MACHINE_OPTS = {
30
31
  :all_states => [:start, :pending, :running, :stopping, :stopped, :finish, :error],
@@ -39,13 +40,15 @@ module Deltacloud
39
40
  @features ||= {}
40
41
  end
41
42
 
42
- def self.feature(collection, feature_name)
43
- return if has_feature?(collection, feature_name)
44
- constraints[collection] ||= {}
45
- constraints[collection][feature_name] ||= {}
46
- constraints[collection][feature_name].merge!(yield) if block_given?
47
- features[collection] ||= []
48
- features[collection] << feature_name
43
+ def self.feature(collection, *feature_list)
44
+ feature_list.each do |feature_name|
45
+ next if has_feature?(collection, feature_name)
46
+ constraints[collection] ||= {}
47
+ constraints[collection][feature_name] ||= {}
48
+ constraints[collection][feature_name].merge!(yield) if block_given?
49
+ features[collection] ||= []
50
+ features[collection] << feature_name
51
+ end
49
52
  end
50
53
 
51
54
  def self.constraints(opts={})
@@ -144,7 +147,7 @@ module Deltacloud
144
147
  end
145
148
 
146
149
  def has_capability?(method)
147
- method = (RUBY_VERSION =~ /^1\.9/) ? method : method.to_s
150
+ method = (RUBY_VERSION < '1.9') ? method.to_s : method
148
151
  # Prevent has_capability fail when driver is inherited from another
149
152
  # driver, like Eucalyptus
150
153
  superclass_methods = self.class.superclass.name == 'Deltacloud::BaseDriver' ?
@@ -154,7 +157,7 @@ module Deltacloud
154
157
 
155
158
  def supported_collections(credentials)
156
159
  collection_arr = []
157
- Deltacloud::Collections.deltacloud_modules.each do |m|
160
+ Deltacloud::Collections.modules(:deltacloud).each do |m|
158
161
  m.collections.each do |c|
159
162
  # Get the required capability for the :index operation (like 'realms' or 'instance_state_machine')
160
163
  index_operation_capability = c.operation(:index).required_capability
@@ -260,15 +263,29 @@ module Deltacloud
260
263
  MEMBER_SHOW_METHODS = [ :realm, :image, :instance, :storage_volume, :bucket, :blob,
261
264
  :key, :firewall ] unless defined?(MEMBER_SHOW_METHODS)
262
265
 
263
- def filter_on(collection, attribute, opts)
266
+ def filter_on(collection, opts, *attributes)
267
+ opts, attributes = attributes.pop, [opts] if !opts.nil? and !(opts.is_a?(Hash))
268
+ # FIXME: ^^ This is just to keep backward compatibility until
269
+ # drivers will be fixed to use the new syntax.
270
+ #
271
+ # filter_on instances, :opts, [ :id, :state, :realm_id]
272
+ #
273
+ # instead of old:
274
+ #
275
+ # filter_on instances, :id, opts
276
+ # filter_on instances, :state, opts
277
+ # filter_on instances, :realm_id, opts
278
+
264
279
  return collection if opts.nil?
265
- return collection if opts[attribute].nil?
266
- filter = opts[attribute]
267
- if ( filter.is_a?( Array ) )
268
- return collection.select{|e| filter.include?( e.send(attribute) ) }
269
- else
270
- return collection.select{|e| filter == e.send(attribute) }
280
+ attributes.each do |attribute|
281
+ next unless filter = opts[attribute]
282
+ if ( filter.is_a?( Array ) )
283
+ collection.select! { |e| filter.include?( e.send(attribute) ) }
284
+ else
285
+ collection.select! { |e| filter == e.send(attribute) }
286
+ end
271
287
  end
288
+ collection
272
289
  end
273
290
 
274
291
  def catched_exceptions_list
@@ -284,6 +301,18 @@ module Deltacloud
284
301
  def configured_providers
285
302
  []
286
303
  end
304
+
305
+ def valid_credentials?(credentials)
306
+ begin
307
+ new_client(credentials)
308
+ rescue Deltacloud::Exceptions::AuthenticationFailure
309
+ return false
310
+ rescue => e
311
+ safely { raise e }
312
+ end
313
+ true
314
+ end
315
+
287
316
  end
288
317
 
289
318
  end
@@ -20,7 +20,7 @@ module Deltacloud
20
20
  module Digitalocean
21
21
  class DigitaloceanDriver < Deltacloud::BaseDriver
22
22
 
23
- feature :instances, :user_name
23
+ feature :instances, :user_name, :authentication_key
24
24
  feature :images, :owner_id
25
25
 
26
26
  define_instance_states do
@@ -30,6 +30,7 @@ module Deltacloud
30
30
  running.to( :stopping ) .on( :stop )
31
31
  running.to( :finish ) .on( :destroy )
32
32
  stopped.to( :running ) .on( :start )
33
+ stopped.to( :finish) .on( :destroy )
33
34
  stopping.to( :stopped ) .automatically
34
35
  stopped.to( :finish ) .automatically
35
36
  error.from(:running, :pending, :stopping)
@@ -45,7 +46,7 @@ module Deltacloud
45
46
  size = do_client.get("sizes/#{opts[:id]}")["size"]
46
47
  results << hardware_profile_from(size)
47
48
  else
48
- sizes = do_client.get("sizes")["sizes"].each do |s|
49
+ do_client.get("sizes")["sizes"].each do |s|
49
50
  size = do_client.get("sizes/#{s['id']}")["size"]
50
51
  results << hardware_profile_from(size)
51
52
  end
@@ -67,14 +68,15 @@ module Deltacloud
67
68
 
68
69
  def realms(credentials, opts={})
69
70
  safely do
70
- new_client(credentials).get('regions')['regions'].map do |r|
71
+ realms = new_client(credentials).get('regions')['regions'].map do |r|
71
72
  Realm.new(
72
- :id => r['id'],
73
+ :id => r['id'].to_s,
73
74
  :name => r['name'],
74
75
  :state => 'AVAILABLE',
75
76
  :limit => :unlimited
76
77
  )
77
78
  end
79
+ filter_on(realms, opts, :id)
78
80
  end
79
81
  end
80
82
 
@@ -133,9 +135,16 @@ module Deltacloud
133
135
  safely do
134
136
  client = new_client(credentials)
135
137
  args = { :image_id => image_id }
136
- args.merge!(:region_id => opts[:realm_id]) if opts[:realm_id]
137
- args.merge!(:size_id => opts[:hwp_id]) if opts[:hwp_id]
138
- args.merge!(:name => opts[:name] || "inst#{Time.now.to_i}")
138
+ # Defaults to first realm if realm_id not set
139
+ opts[:realm_id] ||= '1'
140
+ args.merge!(:region_id => opts[:realm_id])
141
+ # Defaults to first size if hwp_id not set
142
+ opts[:hwp_id] ||= '66'
143
+ args.merge!(:size_id => opts[:hwp_id])
144
+ # Default to 'inst-timestamp if name is not set'
145
+ opts[:name] ||= "inst-#{Time.now.to_i}"
146
+ args.merge!(:name => opts[:name])
147
+ args.merge!(:ssh_key_ids => opts[:keyname]) if opts[:keyname]
139
148
  convert_instance(
140
149
  credentials.user,
141
150
  client.get("droplets/new", args)['droplet']
@@ -167,8 +176,48 @@ module Deltacloud
167
176
  end
168
177
  end
169
178
 
179
+ def keys(credentials, opts={})
180
+ client = new_client(credentials)
181
+ safely do
182
+ client.get('ssh_keys')['ssh_keys'].map do |k|
183
+ convert_key(k)
184
+ end
185
+ end
186
+ end
187
+
188
+ def key(credentials, opts={})
189
+ client = new_client(credentials)
190
+ safely do
191
+ convert_key(client.get("ssh_keys/#{opts[:id]}")["ssh_key"])
192
+ end
193
+ end
194
+
195
+ def destroy_key(credentials, opts={})
196
+ client = new_client(credentials)
197
+ original_key = key(credentials, opts)
198
+ safely do
199
+ client.get("ssh_keys/#{opts[:id]}/destroy")
200
+ original_key.state = 'deleted'
201
+ original_key
202
+ end
203
+ end
204
+
205
+ def create_key(credentials, opts={})
206
+ client = new_client(credentials)
207
+ convert_key(
208
+ client.get(
209
+ "ssh_keys/new",
210
+ :name => opts[:key_name],
211
+ :ssh_pub_key => opts[:public_key])['ssh_key']
212
+ )
213
+ end
214
+
170
215
  exceptions do
171
216
 
217
+ on (/ERROR Unable to verify credentials.*/) do
218
+ status 401
219
+ end
220
+
172
221
  on(/InternalServerError/) do
173
222
  status 502
174
223
  end
@@ -183,6 +232,17 @@ module Deltacloud
183
232
 
184
233
  end
185
234
 
235
+ def valid_credentials?(credentials)
236
+ begin
237
+ hardware_profile_ids(credentials)
238
+ rescue Deltacloud::Exceptions::AuthenticationFailure
239
+ return false
240
+ rescue => e
241
+ safely { raise e }
242
+ end
243
+ true
244
+ end
245
+
186
246
  private
187
247
 
188
248
  class Client
@@ -204,7 +264,7 @@ module Deltacloud
204
264
  json_result = JSON::parse(result)
205
265
  if json_result['status'] != 'OK'
206
266
  p result
207
- error_message = json_result['error_message'] || json_result['status']
267
+ error_message = json_result['error_message'] || "#{json_result['status']} #{json_result['description']}"
208
268
  raise error_message
209
269
  end
210
270
  json_result
@@ -221,6 +281,16 @@ module Deltacloud
221
281
  return 'i386' if name.include? 'x32'
222
282
  end
223
283
 
284
+ def convert_key(k)
285
+ Key.new(
286
+ :id => k['id'],
287
+ :name => k['name'],
288
+ :credential_type => :key,
289
+ :pem_rsa_key => k['ssh_pub_key'],
290
+ :state => 'available'
291
+ )
292
+ end
293
+
224
294
  def convert_state(status)
225
295
  case status
226
296
  when 'active' then 'RUNNING'