bbrowning-deltacloud-core 0.0.4-java

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.
Files changed (134) hide show
  1. data/COPYING +176 -0
  2. data/Rakefile +99 -0
  3. data/bin/deltacloudd +120 -0
  4. data/config.ru +5 -0
  5. data/deltacloud.rb +18 -0
  6. data/lib/deltacloud/base_driver/base_driver.rb +229 -0
  7. data/lib/deltacloud/base_driver/features.rb +166 -0
  8. data/lib/deltacloud/base_driver/mock_driver.rb +40 -0
  9. data/lib/deltacloud/base_driver.rb +20 -0
  10. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +410 -0
  11. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
  12. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +50 -0
  13. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +332 -0
  14. data/lib/deltacloud/drivers/gogrid/test.rb +13 -0
  15. data/lib/deltacloud/drivers/mock/data/images/img1.yml +3 -0
  16. data/lib/deltacloud/drivers/mock/data/images/img2.yml +3 -0
  17. data/lib/deltacloud/drivers/mock/data/images/img3.yml +3 -0
  18. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +16 -0
  19. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +9 -0
  20. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +9 -0
  21. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml +4 -0
  22. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml +4 -0
  23. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml +4 -0
  24. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +6 -0
  25. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +6 -0
  26. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +6 -0
  27. data/lib/deltacloud/drivers/mock/mock_driver.rb +277 -0
  28. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
  29. data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
  30. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
  31. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +130 -0
  32. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +182 -0
  33. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +255 -0
  34. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +85 -0
  35. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +166 -0
  36. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +286 -0
  37. data/lib/deltacloud/hardware_profile.rb +153 -0
  38. data/lib/deltacloud/helpers/application_helper.rb +115 -0
  39. data/lib/deltacloud/helpers/conversion_helper.rb +39 -0
  40. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
  41. data/lib/deltacloud/helpers.rb +5 -0
  42. data/lib/deltacloud/method_serializer.rb +85 -0
  43. data/lib/deltacloud/models/base_model.rb +59 -0
  44. data/lib/deltacloud/models/image.rb +27 -0
  45. data/lib/deltacloud/models/instance.rb +38 -0
  46. data/lib/deltacloud/models/instance_profile.rb +48 -0
  47. data/lib/deltacloud/models/key.rb +35 -0
  48. data/lib/deltacloud/models/realm.rb +26 -0
  49. data/lib/deltacloud/models/storage_snapshot.rb +27 -0
  50. data/lib/deltacloud/models/storage_volume.rb +28 -0
  51. data/lib/deltacloud/state_machine.rb +84 -0
  52. data/lib/deltacloud/validation.rb +70 -0
  53. data/lib/drivers.rb +50 -0
  54. data/lib/sinatra/accept_media_types.rb +128 -0
  55. data/lib/sinatra/lazy_auth.rb +56 -0
  56. data/lib/sinatra/rabbit.rb +273 -0
  57. data/lib/sinatra/respond_to.rb +272 -0
  58. data/lib/sinatra/static_assets.rb +83 -0
  59. data/lib/sinatra/url_for.rb +53 -0
  60. data/public/favicon.ico +0 -0
  61. data/public/images/grid.png +0 -0
  62. data/public/images/logo-wide.png +0 -0
  63. data/public/images/rails.png +0 -0
  64. data/public/images/topbar-bg.png +0 -0
  65. data/public/javascripts/application.js +32 -0
  66. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  67. data/public/stylesheets/compiled/application.css +613 -0
  68. data/public/stylesheets/compiled/ie.css +31 -0
  69. data/public/stylesheets/compiled/print.css +27 -0
  70. data/public/stylesheets/compiled/screen.css +456 -0
  71. data/server.rb +354 -0
  72. data/support/fedora/deltacloudd +68 -0
  73. data/support/fedora/rubygem-deltacloud-core.spec +91 -0
  74. data/tests/api_test.rb +37 -0
  75. data/tests/hardware_profiles_test.rb +120 -0
  76. data/tests/images_test.rb +111 -0
  77. data/tests/instance_states_test.rb +52 -0
  78. data/tests/instances_test.rb +219 -0
  79. data/tests/realms_test.rb +78 -0
  80. data/tests/url_for_test.rb +50 -0
  81. data/views/accounts/index.html.haml +11 -0
  82. data/views/accounts/show.html.haml +30 -0
  83. data/views/api/show.html.haml +15 -0
  84. data/views/api/show.xml.haml +5 -0
  85. data/views/docs/collection.html.haml +37 -0
  86. data/views/docs/collection.xml.haml +14 -0
  87. data/views/docs/index.html.haml +15 -0
  88. data/views/docs/index.xml.haml +5 -0
  89. data/views/docs/operation.html.haml +31 -0
  90. data/views/docs/operation.xml.haml +10 -0
  91. data/views/errors/auth_exception.html.haml +8 -0
  92. data/views/errors/auth_exception.xml.haml +2 -0
  93. data/views/errors/backend_error.html.haml +19 -0
  94. data/views/errors/backend_error.xml.haml +8 -0
  95. data/views/errors/not_found.html.haml +6 -0
  96. data/views/errors/not_found.xml.haml +2 -0
  97. data/views/errors/validation_failure.html.haml +11 -0
  98. data/views/errors/validation_failure.xml.haml +7 -0
  99. data/views/hardware_profiles/index.html.haml +25 -0
  100. data/views/hardware_profiles/index.xml.haml +4 -0
  101. data/views/hardware_profiles/show.html.haml +19 -0
  102. data/views/hardware_profiles/show.xml.haml +18 -0
  103. data/views/images/index.html.haml +30 -0
  104. data/views/images/index.xml.haml +8 -0
  105. data/views/images/show.html.haml +21 -0
  106. data/views/images/show.xml.haml +5 -0
  107. data/views/instance_states/show.gv.erb +45 -0
  108. data/views/instance_states/show.html.haml +31 -0
  109. data/views/instance_states/show.xml.haml +8 -0
  110. data/views/instances/index.html.haml +30 -0
  111. data/views/instances/index.xml.haml +21 -0
  112. data/views/instances/new.html.haml +55 -0
  113. data/views/instances/show.html.haml +43 -0
  114. data/views/instances/show.xml.haml +49 -0
  115. data/views/keys/index.html.haml +26 -0
  116. data/views/keys/index.xml.haml +4 -0
  117. data/views/keys/new.html.haml +8 -0
  118. data/views/keys/show.html.haml +22 -0
  119. data/views/keys/show.xml.haml +20 -0
  120. data/views/layout.html.haml +26 -0
  121. data/views/realms/index.html.haml +29 -0
  122. data/views/realms/index.xml.haml +10 -0
  123. data/views/realms/show.html.haml +15 -0
  124. data/views/realms/show.xml.haml +9 -0
  125. data/views/root/index.html.haml +4 -0
  126. data/views/storage_snapshots/index.html.haml +20 -0
  127. data/views/storage_snapshots/index.xml.haml +9 -0
  128. data/views/storage_snapshots/show.html.haml +14 -0
  129. data/views/storage_snapshots/show.xml.haml +7 -0
  130. data/views/storage_volumes/index.html.haml +21 -0
  131. data/views/storage_volumes/index.xml.haml +13 -0
  132. data/views/storage_volumes/show.html.haml +20 -0
  133. data/views/storage_volumes/show.xml.haml +11 -0
  134. metadata +334 -0
@@ -0,0 +1,166 @@
1
+ require 'deltacloud/validation'
2
+
3
+ # Add advertising of optional features to the base driver
4
+ module Deltacloud
5
+
6
+ class FeatureError < StandardError; end
7
+ class DuplicateFeatureDeclError < FeatureError; end
8
+ class UndeclaredFeatureError < FeatureError; end
9
+
10
+ class BaseDriver
11
+
12
+ # An operation on a collection like cretae or show. Features
13
+ # can add parameters to operations
14
+ class Operation
15
+ attr_reader :name
16
+
17
+ include Deltacloud::Validation
18
+
19
+ def initialize(name, &block)
20
+ @name = name
21
+ @params = {}
22
+ instance_eval &block
23
+ end
24
+ end
25
+
26
+ # The declaration of a feature, defines what operations
27
+ # are modified by it
28
+ class FeatureDecl
29
+ attr_reader :name, :operations
30
+
31
+ def initialize(name, &block)
32
+ @name = name
33
+ @operations = []
34
+ instance_eval &block
35
+ end
36
+
37
+ def description(text=nil)
38
+ @description = text if text
39
+ @description
40
+ end
41
+
42
+ # Add a new operation or modify an existing one through BLOCK
43
+ def operation(name, &block)
44
+ unless op = @operations.find { |op| op.name == name }
45
+ op = Operation.new(name, &block)
46
+ @operations << op
47
+ else
48
+ op.instance_eval(&block) if block_given?
49
+ end
50
+ op
51
+ end
52
+ end
53
+
54
+ # A specific feature enabled by a driver (see +feature+)
55
+ class Feature
56
+ attr_reader :decl
57
+
58
+ def initialize(decl, &block)
59
+ @decl = decl
60
+ instance_eval &block if block_given?
61
+ end
62
+
63
+ def name
64
+ decl.name
65
+ end
66
+
67
+ def operations
68
+ decl.operations
69
+ end
70
+
71
+ def description
72
+ decl.description
73
+ end
74
+ end
75
+
76
+ def self.feature_decls
77
+ @@feature_decls ||= {}
78
+ end
79
+
80
+ def self.feature_decl_for(collection, name)
81
+ decls = feature_decls[collection]
82
+ if decls
83
+ decls.find { |dcl| dcl.name == name }
84
+ else
85
+ nil
86
+ end
87
+ end
88
+
89
+ # Declare a new feature
90
+ def self.declare_feature(collection, name, &block)
91
+ feature_decls[collection] ||= []
92
+ raise DuplicateFeatureDeclError if feature_decl_for(collection, name)
93
+ feature_decls[collection] << FeatureDecl.new(name, &block)
94
+ end
95
+
96
+ def self.features
97
+ @@features ||= {}
98
+ end
99
+
100
+ # Declare in a driver that it supports a specific feature
101
+ #
102
+ # The same feature can be declared multiple times in a driver, so that
103
+ # it can be changed successively by passing in different blocks.
104
+ def self.feature(collection, name, &block)
105
+ features[collection] ||= []
106
+ if f = features[collection].find { |f| f.name == name }
107
+ f.instance_eval(&block) if block_given?
108
+ return f
109
+ end
110
+ unless decl = feature_decl_for(collection, name)
111
+ raise UndeclaredFeatureError, "No feature #{name} for #{collection}"
112
+ end
113
+ features[collection] << Feature.new(decl, &block)
114
+ end
115
+
116
+ def features(collection)
117
+ self.class.features[collection] || []
118
+ end
119
+
120
+ #
121
+ # Declaration of optional features
122
+ #
123
+ declare_feature :images, :owner_id do
124
+ description "Filter images using owner id"
125
+ operation :index do
126
+ param :owner_id, :string, :optional, nil, "Owner ID"
127
+ end
128
+ end
129
+
130
+ declare_feature :instances, :user_name do
131
+ description "Accept a user-defined name on instance creation"
132
+ operation :create do
133
+ param :name, :string, :optional, nil,
134
+ "The user-defined name"
135
+ end
136
+ end
137
+
138
+ declare_feature :instances, :user_data do
139
+ description "Make user-defined data available on a special webserver"
140
+ operation :create do
141
+ param :user_data, :string, :optional, nil,
142
+ "Base64 encoded user data will be published to internal webserver"
143
+ end
144
+ end
145
+
146
+ declare_feature :instances, :authentication_key do
147
+ operation :create do
148
+ param :keyname, :string, :optional, nil
149
+ "EC2 key authentification method"
150
+ end
151
+ operation :show do
152
+ end
153
+ end
154
+
155
+ declare_feature :instances, :authentication_password do
156
+ operation :create do
157
+ param :password, :string, :optional
158
+ end
159
+ end
160
+
161
+ declare_feature :instances, :hardware_profiles do
162
+ description "Size instances according to changes to a hardware profile"
163
+ # The parameters are filled in from the hardware profiles
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,40 @@
1
+ require 'deltacloud/method_serializer'
2
+
3
+ # Create 'mock' version of original driver client/gem:
4
+
5
+ module Mock
6
+ class EC2 < AWS::EC2::Base
7
+
8
+ include MethodSerializer::Cache
9
+
10
+ def self.cached_methods
11
+ [
12
+ :describe_images,
13
+ :describe_availability_zones,
14
+ :describe_keypairs,
15
+ :create_keypair,
16
+ :run_instances,
17
+ :describe_instances,
18
+ :reboot_instances,
19
+ :terminate_instances,
20
+ :delete_keypair
21
+ ]
22
+ end
23
+
24
+ MethodSerializer::Cache::wrap_methods(self, :cache_dir => File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'tests', 'ec2', 'support'))
25
+ end
26
+ end
27
+
28
+
29
+ # Replace original client with mock client
30
+ Deltacloud::Drivers::EC2::EC2Driver.class_eval do
31
+ alias_method :original_new_client, :new_client
32
+
33
+ def new_client(credentials, opts={})
34
+ Mock::EC2.new(
35
+ :access_key_id => credentials.user,
36
+ :secret_access_key => credentials.password
37
+ )
38
+ end
39
+
40
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+ require 'deltacloud/base_driver/base_driver'
20
+ require 'deltacloud/base_driver/features'
@@ -0,0 +1,410 @@
1
+ #
2
+ # Copyright (C) 2009 Red Hat, Inc.
3
+ #
4
+ # Licensed to the Apache Software Foundation (ASF) under one or more
5
+ # contributor license agreements. See the NOTICE file distributed with
6
+ # this work for additional information regarding copyright ownership. The
7
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance with the
9
+ # License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16
+ # License for the specific language governing permissions and limitations
17
+ # under the License.
18
+
19
+
20
+ require 'deltacloud/base_driver'
21
+ require 'AWS'
22
+
23
+ class Instance
24
+ attr_accessor :keyname
25
+ attr_accessor :authn_error
26
+
27
+ def authn_feature_failed?
28
+ return true unless authn_error.nil?
29
+ end
30
+
31
+ end
32
+
33
+ module Deltacloud
34
+ module Drivers
35
+ module EC2
36
+ class EC2Driver < Deltacloud::BaseDriver
37
+
38
+ def supported_collections
39
+ DEFAULT_COLLECTIONS + [ :keys ]
40
+ end
41
+
42
+ feature :instances, :user_data
43
+ feature :instances, :authentication_key
44
+ feature :images, :owner_id
45
+
46
+ define_hardware_profile('m1.small') do
47
+ cpu 1
48
+ memory 1.7 * 1024
49
+ storage 160
50
+ architecture 'i386'
51
+ end
52
+
53
+ define_hardware_profile('m1.large') do
54
+ cpu 4
55
+ memory 7.5 * 1024
56
+ storage 850
57
+ architecture 'x86_64'
58
+ end
59
+
60
+ define_hardware_profile('m1.xlarge') do
61
+ cpu 8
62
+ memory 15 * 1024
63
+ storage 1690
64
+ architecture 'x86_64'
65
+ end
66
+
67
+ define_hardware_profile('c1.medium') do
68
+ cpu 5
69
+ memory 1.7 * 1024
70
+ storage 350
71
+ architecture 'i386'
72
+ end
73
+
74
+ define_hardware_profile('c1.xlarge') do
75
+ cpu 20
76
+ memory 7 * 1024
77
+ storage 1690
78
+ architecture 'x86_64'
79
+ end
80
+
81
+ define_hardware_profile('m2.xlarge') do
82
+ cpu 6.5
83
+ memory 17.1 * 1024
84
+ storage 420
85
+ architecture 'x86_64'
86
+ end
87
+
88
+ define_hardware_profile('m2.2xlarge') do
89
+ cpu 13
90
+ memory 34.2 * 1024
91
+ storage 850
92
+ architecture 'x86_64'
93
+ end
94
+
95
+ define_hardware_profile('m2.4xlarge') do
96
+ cpu 26
97
+ memory 68.4 * 1024
98
+ storage 1690
99
+ architecture 'x86_64'
100
+ end
101
+
102
+ define_instance_states do
103
+ start.to( :pending ) .automatically
104
+ pending.to( :running ) .automatically
105
+ pending.to( :stopping ) .on( :stop )
106
+ pending.to( :stopped ) .automatically
107
+ stopped.to( :running ) .on( :start )
108
+ running.to( :running ) .on( :reboot )
109
+ running.to( :stopping ) .on( :stop )
110
+ shutting_down.to( :stopped ) .automatically
111
+ stopped.to( :finish ) .automatically
112
+ end
113
+
114
+ #
115
+ # Images
116
+ #
117
+
118
+ def images(credentials, opts={} )
119
+ ec2 = new_client(credentials)
120
+ img_arr = []
121
+ # if we know the image_id, we don't want to limit by owner_id, since this
122
+ # will exclude public images
123
+ if (opts and opts[:id])
124
+ config = { :image_id => opts[:id] }
125
+ else
126
+ config = { :owner_id => "amazon" }
127
+ config.merge!({ :owner_id => opts[:owner_id] }) if opts and opts[:owner_id]
128
+ end
129
+ safely do
130
+ ec2.describe_images(config).imagesSet.item.each do |image|
131
+ img_arr << convert_image(image)
132
+ end
133
+ end
134
+ img_arr = filter_on( img_arr, :architecture, opts )
135
+ img_arr.sort_by{|e| [e.owner_id, e.name]}
136
+ end
137
+
138
+ #
139
+ # Realms
140
+ #
141
+
142
+ def realms(credentials, opts=nil)
143
+ ec2 = new_client(credentials)
144
+ realms = []
145
+ safely do
146
+ ec2.describe_availability_zones.availabilityZoneInfo.item.each do |ec2_realm|
147
+ realms << convert_realm( ec2_realm )
148
+ end
149
+ end
150
+ realms
151
+ end
152
+
153
+ #
154
+ # Instances
155
+ #
156
+ def instances(credentials, opts=nil)
157
+ ec2 = new_client(credentials)
158
+ instances = []
159
+ safely do
160
+ param = opts.nil? ? nil : opts[:id]
161
+ ec2_instances = ec2.describe_instances.reservationSet
162
+ return [] unless ec2_instances
163
+ ec2_instances.item.each do |item|
164
+ item.instancesSet.item.each do |ec2_instance|
165
+ instances << convert_instance( ec2_instance, item.ownerId )
166
+ end
167
+ end
168
+ end
169
+ instances = filter_on( instances, :id, opts )
170
+ instances = filter_on( instances, :state, opts )
171
+ instances
172
+ end
173
+
174
+
175
+ def create_instance(credentials, image_id, opts)
176
+ ec2 = new_client( credentials )
177
+ realm_id = opts[:realm_id]
178
+ safely do
179
+ image = image(credentials, :id => image_id )
180
+ hwp = find_hardware_profile(credentials, opts[:hwp_id], image.id)
181
+ ec2_instances = ec2.run_instances(
182
+ :image_id => image.id,
183
+ :user_data => opts[:user_data],
184
+ :key_name => opts[:keyname],
185
+ :availability_zone => realm_id,
186
+ :monitoring_enabled => true,
187
+ :instance_type => hwp.name,
188
+ :disable_api_termination => false,
189
+ :instance_initiated_shutdown_behavior => 'terminate'
190
+ )
191
+ return convert_instance( ec2_instances.instancesSet.item.first, 'pending' )
192
+ end
193
+ end
194
+
195
+ def generate_instance(ec2, id, backup)
196
+ begin
197
+ this_instance = ec2.describe_instances( :instance_id => id ).reservationSet.item.first.instancesSet.item.first
198
+ convert_instance(this_instance, this_instance.ownerId)
199
+ rescue Exception => e
200
+ puts "WARNING: ignored error during instance refresh: #{e.message}"
201
+ # at this point, the action has succeeded but our follow-up
202
+ # "describe_instances" failed for some reason. Create a simple Instance
203
+ # object with only the ID and new state in place
204
+ state = backup.instancesSet.item.first.currentState.name
205
+ Instance.new( {
206
+ :id => id,
207
+ :state => state,
208
+ :actions => instance_actions_for( state ),
209
+ } )
210
+ end
211
+ end
212
+
213
+ def reboot_instance(credentials, id)
214
+ ec2 = new_client(credentials)
215
+ backup = ec2.reboot_instances( :instance_id => id )
216
+
217
+ generate_instance(ec2, id, backup)
218
+ end
219
+
220
+ def stop_instance(credentials, id)
221
+ ec2 = new_client(credentials)
222
+ backup = ec2.terminate_instances( :instance_id => id )
223
+
224
+ generate_instance(ec2, id, backup)
225
+ end
226
+
227
+ def destroy_instance(credentials, id)
228
+ ec2 = new_client(credentials)
229
+ backup = ec2.terminate_instances( :instance_id => id )
230
+
231
+ generate_instance(ec2, id, backup)
232
+ end
233
+
234
+ #
235
+ # Storage Volumes
236
+ #
237
+
238
+ def storage_volumes(credentials, opts=nil)
239
+ ec2 = new_client( credentials )
240
+ volumes = []
241
+ safely do
242
+ if (opts)
243
+ ec2.describe_volumes(:volume_id => opts[:id]).volumeSet.item.each do |ec2_volume|
244
+ volumes << convert_volume( ec2_volume )
245
+ end
246
+ else
247
+ ec2_volumes = ec2.describe_volumes.volumeSet
248
+ return [] unless ec2_volumes
249
+ ec2_volumes.item.each do |ec2_volume|
250
+ volumes << convert_volume( ec2_volume )
251
+ end
252
+ end
253
+ end
254
+ volumes
255
+ end
256
+
257
+ #
258
+ # Storage Snapshots
259
+ #
260
+
261
+ def storage_snapshots(credentials, opts=nil)
262
+ ec2 = new_client( credentials )
263
+ snapshots = []
264
+ safely do
265
+ if (opts)
266
+ ec2.describe_snapshots(:owner => 'self', :snapshot_id => opts[:id]).snapshotSet.item.each do |ec2_snapshot|
267
+ snapshots << convert_snapshot( ec2_snapshot )
268
+ end
269
+ else
270
+ ec2_snapshots = ec2.describe_snapshots(:owner => 'self').snapshotSet
271
+ return [] unless ec2_snapshots
272
+ ec2_snapshots.item.each do |ec2_snapshot|
273
+ snapshots << convert_snapshot( ec2_snapshot )
274
+ end
275
+ end
276
+ end
277
+ snapshots
278
+ end
279
+
280
+ def key(credentials, opts=nil)
281
+ keys(credentials, opts).first
282
+ end
283
+
284
+ def keys(credentials, opts=nil)
285
+ ec2 = new_client( credentials )
286
+ opts[:key_name] = opts[:id] if opts and opts[:id]
287
+ keypairs = ec2.describe_keypairs(opts || {})
288
+ result = []
289
+ safely do
290
+ keypairs.keySet.item.each do |keypair|
291
+ result << convert_key(keypair)
292
+ end
293
+ end
294
+ result
295
+ end
296
+
297
+ def create_key(credentials, opts={})
298
+ key = Key.new
299
+ ec2 = new_client( credentials )
300
+ safely do
301
+ key = convert_key(ec2.create_keypair(opts))
302
+ end
303
+ return key
304
+ end
305
+
306
+ def destroy_key(credentials, opts={})
307
+ safely do
308
+ ec2 = new_client( credentials )
309
+ ec2.delete_keypair(opts)
310
+ end
311
+ end
312
+
313
+ private
314
+
315
+ def new_client(credentials)
316
+ opts = {
317
+ :access_key_id => credentials.user,
318
+ :secret_access_key => credentials.password
319
+ }
320
+ opts[:server] = ENV['DCLOUD_EC2_URL'] if ENV['DCLOUD_EC2_URL']
321
+ safely do
322
+ AWS::EC2::Base.new(opts)
323
+ end
324
+ end
325
+
326
+ def convert_key(key)
327
+ Key.new({
328
+ :id => key['keyName'],
329
+ :fingerprint => key['keyFingerprint'],
330
+ :credential_type => :key,
331
+ :pem_rsa_key => key['keyMaterial']
332
+ })
333
+ end
334
+
335
+ def convert_image(ec2_image)
336
+ Image.new( {
337
+ :id=>ec2_image['imageId'],
338
+ :name=>ec2_image['name'] || ec2_image['imageId'],
339
+ :description=>ec2_image['description'] || ec2_image['imageLocation'] || '',
340
+ :owner_id=>ec2_image['imageOwnerId'],
341
+ :architecture=>ec2_image['architecture'],
342
+ } )
343
+ end
344
+
345
+ def convert_realm(ec2_realm)
346
+ Realm.new( {
347
+ :id=>ec2_realm['zoneName'],
348
+ :name=>ec2_realm['regionName'],
349
+ :limit=>ec2_realm['zoneState'].eql?('available') ? :unlimited : 0,
350
+ :state=>ec2_realm['zoneState'].upcase,
351
+ } )
352
+ end
353
+
354
+ def convert_instance(ec2_instance, owner_id)
355
+ state = ec2_instance['instanceState']['name'].upcase
356
+ state_key = state.downcase.underscore.to_sym
357
+ realm_id = ec2_instance['placement']['availabilityZone']
358
+ (realm_id = nil ) if ( realm_id == '' )
359
+ hwp_name = ec2_instance['instanceType']
360
+ instance = Instance.new( {
361
+ :id=>ec2_instance['instanceId'],
362
+ :name => ec2_instance['imageId'],
363
+ :state=>state,
364
+ :image_id=>ec2_instance['imageId'],
365
+ :owner_id=>owner_id,
366
+ :realm_id=>realm_id,
367
+ :public_addresses=>( ec2_instance['dnsName'] == '' ? [] : [ec2_instance['dnsName']] ),
368
+ :private_addresses=>( ec2_instance['privateDnsName'] == '' ? [] : [ec2_instance['privateDnsName']] ),
369
+ :instance_profile =>InstanceProfile.new(hwp_name),
370
+ :actions=>instance_actions_for( state ),
371
+ :keyname => ec2_instance['keyName'],
372
+ :launch_time => ec2_instance['launchTime']
373
+ } )
374
+ instance.authn_error = "Key not set for instance" unless ec2_instance['keyName']
375
+ return instance
376
+ end
377
+
378
+ def convert_volume(ec2_volume)
379
+ StorageVolume.new( {
380
+ :id=>ec2_volume['volumeId'],
381
+ :created=>ec2_volume['createTime'],
382
+ :state=>ec2_volume['status'].upcase,
383
+ :capacity=>ec2_volume['size'],
384
+ :instance_id=>ec2_volume['snapshotId'],
385
+ :device=>ec2_volume['attachmentSet'],
386
+ } )
387
+ end
388
+
389
+ def convert_snapshot(ec2_snapshot)
390
+ StorageSnapshot.new( {
391
+ :id=>ec2_snapshot['snapshotId'],
392
+ :state=>ec2_snapshot['status'].upcase,
393
+ :storage_volume_id=>ec2_snapshot['volumeId'],
394
+ :created=>ec2_snapshot['startTime'],
395
+ } )
396
+ end
397
+
398
+ def catched_exceptions_list
399
+ {
400
+ :auth => [ AWS::AuthFailure ],
401
+ :error => [],
402
+ :glob => [ /AWS::(\w+)/ ]
403
+ }
404
+ end
405
+
406
+ end
407
+
408
+ end
409
+ end
410
+ end