steamcannon-deltacloud-core 0.0.7.1-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 (152) hide show
  1. data/COPYING +176 -0
  2. data/Rakefile +106 -0
  3. data/bin/deltacloudd +120 -0
  4. data/config.ru +5 -0
  5. data/deltacloud.rb +20 -0
  6. data/lib/deltacloud/base_driver/base_driver.rb +259 -0
  7. data/lib/deltacloud/base_driver/features.rb +173 -0
  8. data/lib/deltacloud/base_driver/mock_driver.rb +58 -0
  9. data/lib/deltacloud/base_driver.rb +20 -0
  10. data/lib/deltacloud/drivers/azure/azure_driver.rb +127 -0
  11. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +580 -0
  12. data/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb +170 -0
  13. data/lib/deltacloud/drivers/gogrid/gogrid_client.rb +50 -0
  14. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +343 -0
  15. data/lib/deltacloud/drivers/gogrid/test.rb +13 -0
  16. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob1.yml +5 -0
  17. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob2.yml +5 -0
  18. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob3.yml +5 -0
  19. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob4.yml +5 -0
  20. data/lib/deltacloud/drivers/mock/data/buckets/blobs/blob5.yml +5 -0
  21. data/lib/deltacloud/drivers/mock/data/buckets/bucket1.yml +2 -0
  22. data/lib/deltacloud/drivers/mock/data/buckets/bucket2.yml +2 -0
  23. data/lib/deltacloud/drivers/mock/data/images/img1.yml +3 -0
  24. data/lib/deltacloud/drivers/mock/data/images/img2.yml +3 -0
  25. data/lib/deltacloud/drivers/mock/data/images/img3.yml +3 -0
  26. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +16 -0
  27. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +9 -0
  28. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +9 -0
  29. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap1.yml +4 -0
  30. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap2.yml +4 -0
  31. data/lib/deltacloud/drivers/mock/data/storage_snapshots/snap3.yml +4 -0
  32. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol1.yml +6 -0
  33. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol2.yml +6 -0
  34. data/lib/deltacloud/drivers/mock/data/storage_volumes/vol3.yml +6 -0
  35. data/lib/deltacloud/drivers/mock/mock_driver.rb +356 -0
  36. data/lib/deltacloud/drivers/opennebula/cloud_client.rb +116 -0
  37. data/lib/deltacloud/drivers/opennebula/occi_client.rb +204 -0
  38. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +241 -0
  39. data/lib/deltacloud/drivers/rackspace/rackspace_client.rb +130 -0
  40. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +290 -0
  41. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +258 -0
  42. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_client.rb +85 -0
  43. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +166 -0
  44. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +295 -0
  45. data/lib/deltacloud/hardware_profile.rb +153 -0
  46. data/lib/deltacloud/helpers/application_helper.rb +122 -0
  47. data/lib/deltacloud/helpers/blob_stream.rb +51 -0
  48. data/lib/deltacloud/helpers/conversion_helper.rb +39 -0
  49. data/lib/deltacloud/helpers/hardware_profiles_helper.rb +35 -0
  50. data/lib/deltacloud/helpers.rb +5 -0
  51. data/lib/deltacloud/method_serializer.rb +85 -0
  52. data/lib/deltacloud/models/base_model.rb +59 -0
  53. data/lib/deltacloud/models/blob.rb +26 -0
  54. data/lib/deltacloud/models/bucket.rb +24 -0
  55. data/lib/deltacloud/models/image.rb +27 -0
  56. data/lib/deltacloud/models/instance.rb +38 -0
  57. data/lib/deltacloud/models/instance_profile.rb +48 -0
  58. data/lib/deltacloud/models/key.rb +35 -0
  59. data/lib/deltacloud/models/realm.rb +26 -0
  60. data/lib/deltacloud/models/storage_snapshot.rb +27 -0
  61. data/lib/deltacloud/models/storage_volume.rb +28 -0
  62. data/lib/deltacloud/state_machine.rb +84 -0
  63. data/lib/deltacloud/validation.rb +70 -0
  64. data/lib/drivers.rb +51 -0
  65. data/lib/sinatra/accept_media_types.rb +128 -0
  66. data/lib/sinatra/lazy_auth.rb +56 -0
  67. data/lib/sinatra/rabbit.rb +279 -0
  68. data/lib/sinatra/respond_to.rb +238 -0
  69. data/lib/sinatra/static_assets.rb +83 -0
  70. data/lib/sinatra/url_for.rb +53 -0
  71. data/public/favicon.ico +0 -0
  72. data/public/images/grid.png +0 -0
  73. data/public/images/logo-wide.png +0 -0
  74. data/public/images/rails.png +0 -0
  75. data/public/images/topbar-bg.png +0 -0
  76. data/public/javascripts/application.js +32 -0
  77. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  78. data/public/stylesheets/compiled/application.css +613 -0
  79. data/public/stylesheets/compiled/ie.css +31 -0
  80. data/public/stylesheets/compiled/print.css +27 -0
  81. data/public/stylesheets/compiled/screen.css +456 -0
  82. data/server.rb +516 -0
  83. data/support/fedora/deltacloudd +68 -0
  84. data/support/fedora/rubygem-deltacloud-core.spec +91 -0
  85. data/tests/api_test.rb +37 -0
  86. data/tests/hardware_profiles_test.rb +120 -0
  87. data/tests/images_test.rb +111 -0
  88. data/tests/instance_states_test.rb +51 -0
  89. data/tests/instances_test.rb +222 -0
  90. data/tests/realms_test.rb +78 -0
  91. data/tests/url_for_test.rb +50 -0
  92. data/views/accounts/index.html.haml +11 -0
  93. data/views/accounts/show.html.haml +30 -0
  94. data/views/api/show.html.haml +15 -0
  95. data/views/api/show.xml.haml +5 -0
  96. data/views/blobs/show.html.haml +20 -0
  97. data/views/blobs/show.xml.haml +7 -0
  98. data/views/buckets/index.html.haml +33 -0
  99. data/views/buckets/index.xml.haml +10 -0
  100. data/views/buckets/new.html.haml +13 -0
  101. data/views/buckets/show.html.haml +19 -0
  102. data/views/buckets/show.xml.haml +8 -0
  103. data/views/docs/collection.html.haml +37 -0
  104. data/views/docs/collection.xml.haml +14 -0
  105. data/views/docs/index.html.haml +15 -0
  106. data/views/docs/index.xml.haml +5 -0
  107. data/views/docs/operation.html.haml +31 -0
  108. data/views/docs/operation.xml.haml +10 -0
  109. data/views/errors/auth_exception.html.haml +8 -0
  110. data/views/errors/auth_exception.xml.haml +2 -0
  111. data/views/errors/backend_error.html.haml +19 -0
  112. data/views/errors/backend_error.xml.haml +8 -0
  113. data/views/errors/not_found.html.haml +6 -0
  114. data/views/errors/not_found.xml.haml +2 -0
  115. data/views/errors/validation_failure.html.haml +11 -0
  116. data/views/errors/validation_failure.xml.haml +7 -0
  117. data/views/hardware_profiles/index.html.haml +25 -0
  118. data/views/hardware_profiles/index.xml.haml +4 -0
  119. data/views/hardware_profiles/show.html.haml +19 -0
  120. data/views/hardware_profiles/show.xml.haml +18 -0
  121. data/views/images/index.html.haml +30 -0
  122. data/views/images/index.xml.haml +8 -0
  123. data/views/images/show.html.haml +21 -0
  124. data/views/images/show.xml.haml +5 -0
  125. data/views/instance_states/show.html.haml +31 -0
  126. data/views/instance_states/show.png.erb +45 -0
  127. data/views/instance_states/show.xml.haml +8 -0
  128. data/views/instances/index.html.haml +30 -0
  129. data/views/instances/index.xml.haml +21 -0
  130. data/views/instances/new.html.haml +55 -0
  131. data/views/instances/show.html.haml +43 -0
  132. data/views/instances/show.xml.haml +49 -0
  133. data/views/keys/index.html.haml +26 -0
  134. data/views/keys/index.xml.haml +4 -0
  135. data/views/keys/new.html.haml +8 -0
  136. data/views/keys/show.html.haml +22 -0
  137. data/views/keys/show.xml.haml +20 -0
  138. data/views/layout.html.haml +26 -0
  139. data/views/realms/index.html.haml +29 -0
  140. data/views/realms/index.xml.haml +10 -0
  141. data/views/realms/show.html.haml +15 -0
  142. data/views/realms/show.xml.haml +9 -0
  143. data/views/root/index.html.haml +4 -0
  144. data/views/storage_snapshots/index.html.haml +20 -0
  145. data/views/storage_snapshots/index.xml.haml +9 -0
  146. data/views/storage_snapshots/show.html.haml +14 -0
  147. data/views/storage_snapshots/show.xml.haml +7 -0
  148. data/views/storage_volumes/index.html.haml +21 -0
  149. data/views/storage_volumes/index.xml.haml +23 -0
  150. data/views/storage_volumes/show.html.haml +20 -0
  151. data/views/storage_volumes/show.xml.haml +24 -0
  152. metadata +367 -0
@@ -0,0 +1,6 @@
1
+ :owner_id: fedoraproject
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: AVAILABLE
4
+ :capacity: 1
5
+ :device:
6
+ :instance_id:
@@ -0,0 +1,6 @@
1
+ :owner_id: mockuser
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: AVAILABLE
4
+ :capacity: 1
5
+ :device:
6
+ :instance_id:
@@ -0,0 +1,6 @@
1
+ :owner_id: mockuser
2
+ :created: Thu Jul 30 14:35:11 UTC 2009
3
+ :state: IN-USE
4
+ :capacity: 1
5
+ :device: /dev/sda1
6
+ :instance_id: inst1
@@ -0,0 +1,356 @@
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 'yaml'
22
+
23
+ module Deltacloud
24
+ module Drivers
25
+ module Mock
26
+ class MockDriver < Deltacloud::BaseDriver
27
+
28
+ def supported_collections
29
+ DEFAULT_COLLECTIONS + [ :buckets ]
30
+ end
31
+
32
+ ( REALMS = [
33
+ Realm.new({
34
+ :id=>'us',
35
+ :name=>'United States',
36
+ :limit=>:unlimited,
37
+ :state=>'AVAILABLE',
38
+ }),
39
+ Realm.new({
40
+ :id=>'eu',
41
+ :name=>'Europe',
42
+ :limit=>:unlimited,
43
+ :state=>'AVAILABLE',
44
+ }),
45
+ ] ) unless defined?( REALMS )
46
+
47
+ define_hardware_profile('m1-small') do
48
+ cpu 1
49
+ memory 1.7 * 1024
50
+ storage 160
51
+ architecture 'i386'
52
+ end
53
+
54
+ define_hardware_profile('m1-large') do
55
+ cpu 2
56
+ memory (7.5*1024 .. 15*1024), :default => 10 * 1024
57
+ storage [ 850, 1024 ]
58
+ architecture 'x86_64'
59
+ end
60
+
61
+ define_hardware_profile('m1-xlarge') do
62
+ cpu 4
63
+ memory (12*1024 .. 32*1024)
64
+ storage [ 1024, 2048, 4096 ]
65
+ architecture 'x86_64'
66
+ end
67
+
68
+ # Some clouds tell us nothing about hardware profiles (e.g., OpenNebula)
69
+ define_hardware_profile 'opaque'
70
+
71
+ define_instance_states do
72
+ start.to( :pending ) .on( :create )
73
+
74
+ pending.to( :running ) .automatically
75
+
76
+ running.to( :running ) .on( :reboot )
77
+ running.to( :stopped ) .on( :stop )
78
+
79
+ stopped.to( :running ) .on( :start )
80
+ stopped.to( :finish ) .on( :destroy )
81
+ end
82
+
83
+ feature :instances, :user_name
84
+
85
+ def initialize
86
+ if ENV["DELTACLOUD_MOCK_STORAGE"]
87
+ @storage_root = ENV["DELTACLOUD_MOCK_STORAGE"]
88
+ elsif ENV["USER"]
89
+ @storage_root = File::join("/var/tmp", "deltacloud-mock-#{ENV["USER"]}")
90
+ else
91
+ raise "Please set either the DELTACLOUD_MOCK_STORAGE or USER environment variable"
92
+ end
93
+ if ! File::directory?(@storage_root)
94
+ FileUtils::rm_rf(@storage_root)
95
+ FileUtils::mkdir_p(@storage_root)
96
+ data = Dir::glob(File::join(File::dirname(__FILE__), "data", "*"))
97
+ FileUtils::cp_r(data, @storage_root)
98
+ end
99
+ end
100
+
101
+ def realms(credentials, opts=nil)
102
+ return REALMS if ( opts.nil? )
103
+ results = REALMS
104
+ results = filter_on( results, :id, opts )
105
+ results
106
+ end
107
+
108
+ #
109
+ # Images
110
+ #
111
+ def images(credentials, opts=nil )
112
+ check_credentials( credentials )
113
+ images = []
114
+ Dir[ "#{@storage_root}/images/*.yml" ].each do |image_file|
115
+ image = YAML.load( File.read( image_file ) )
116
+ image[:id] = File.basename( image_file, ".yml" )
117
+ image[:name] = image[:description]
118
+ images << Image.new( image )
119
+ end
120
+ images = filter_on( images, :id, opts )
121
+ images = filter_on( images, :architecture, opts )
122
+ if ( opts && opts[:owner_id] == 'self' )
123
+ images = images.select{|e| e.owner_id == credentials.user }
124
+ else
125
+ images = filter_on( images, :owner_id, opts )
126
+ end
127
+ images.sort_by{|e| [e.owner_id,e.description]}
128
+ end
129
+
130
+ #
131
+ # Instances
132
+ #
133
+
134
+ def instances(credentials, opts=nil)
135
+ check_credentials( credentials )
136
+ instances = []
137
+ Dir[ "#{@storage_root}/instances/*.yml" ].each do |instance_file|
138
+ instance = YAML.load( File.read( instance_file ) )
139
+ if ( instance[:owner_id] == credentials.user )
140
+ instance[:id] = File.basename( instance_file, ".yml" )
141
+ instance[:actions] = instance_actions_for( instance[:state] )
142
+ instances << Instance.new( instance )
143
+ end
144
+ end
145
+ instances = filter_on( instances, :id, opts )
146
+ instances = filter_on( instances, :state, opts )
147
+ instances
148
+ end
149
+
150
+ def create_instance(credentials, image_id, opts)
151
+ check_credentials( credentials )
152
+ ids = Dir[ "#{@storage_root}/instances/*.yml" ].collect{|e| File.basename( e, ".yml" )}
153
+
154
+ count = 0
155
+ while true
156
+ next_id = "inst" + count.to_s
157
+ if not ids.include?(next_id)
158
+ break
159
+ end
160
+ count = count + 1
161
+ end
162
+
163
+ realm_id = opts[:realm_id]
164
+ if ( realm_id.nil? )
165
+ realm = realms(credentials).first
166
+ ( realm_id = realm.id ) if realm
167
+ end
168
+
169
+ hwp = find_hardware_profile(credentials, opts[:hwp_id], image_id)
170
+
171
+ name = opts[:name] || "i-#{Time.now.to_i}"
172
+
173
+ instance = {
174
+ :name=>name,
175
+ :state=>'RUNNING',
176
+ :image_id=>image_id,
177
+ :owner_id=>credentials.user,
178
+ :public_addresses=>["#{image_id}.#{next_id}.public.com"],
179
+ :private_addresses=>["#{image_id}.#{next_id}.private.com"],
180
+ :instance_profile => InstanceProfile.new(hwp.name, opts),
181
+ :realm_id=>realm_id,
182
+ :actions=>instance_actions_for( 'RUNNING' )
183
+ }
184
+ File.open( "#{@storage_root}/instances/#{next_id}.yml", 'w' ) {|f|
185
+ YAML.dump( instance, f )
186
+ }
187
+ instance[:id] = next_id
188
+ Instance.new( instance )
189
+ end
190
+
191
+ def update_instance_state(credentials, id, state)
192
+ instance_file = "#{@storage_root}/instances/#{id}.yml"
193
+ instance_yml = YAML.load( File.read( instance_file ) )
194
+ instance_yml[:id] = id
195
+ instance_yml[:state] = state
196
+ instance_yml[:actions] = instance_actions_for( instance_yml[:state] )
197
+ File.open( instance_file, 'w' ) do |f|
198
+ f << YAML.dump( instance_yml )
199
+ end
200
+ Instance.new( instance_yml )
201
+ end
202
+
203
+ def start_instance(credentials, id)
204
+ update_instance_state(credentials, id, 'RUNNING')
205
+ end
206
+
207
+ def reboot_instance(credentials, id)
208
+ update_instance_state(credentials, id, 'RUNNING')
209
+ end
210
+
211
+ def stop_instance(credentials, id)
212
+ update_instance_state(credentials, id, 'STOPPED')
213
+ end
214
+
215
+
216
+ def destroy_instance(credentials, id)
217
+ check_credentials( credentials )
218
+ FileUtils.rm( "#{@storage_root}/instances/#{id}.yml" )
219
+ end
220
+
221
+ #
222
+ # Storage Volumes
223
+ #
224
+
225
+ def storage_volumes(credentials, opts=nil)
226
+ check_credentials( credentials )
227
+ volumes = []
228
+ Dir[ "#{@storage_root}/storage_volumes/*.yml" ].each do |storage_volume_file|
229
+ storage_volume = YAML.load( File.read( storage_volume_file ) )
230
+ if ( storage_volume[:owner_id] == credentials.user )
231
+ storage_volume[:id] = File.basename( storage_volume_file, ".yml" )
232
+ volumes << StorageVolume.new( storage_volume )
233
+ end
234
+ end
235
+ volumes = filter_on( volumes, :id, opts )
236
+ volumes
237
+ end
238
+
239
+ #
240
+ # Storage Snapshots
241
+ #
242
+
243
+ def storage_snapshots(credentials, opts=nil)
244
+ check_credentials( credentials )
245
+ snapshots = []
246
+ Dir[ "#{@storage_root}/storage_snapshots/*.yml" ].each do |storage_snapshot_file|
247
+ storage_snapshot = YAML.load( File.read( storage_snapshot_file ) )
248
+ if ( storage_snapshot[:owner_id] == credentials.user )
249
+ storage_snapshot[:id] = File.basename( storage_snapshot_file, ".yml" )
250
+ snapshots << StorageSnapshot.new( storage_snapshot )
251
+ end
252
+ end
253
+ snapshots = filter_on( snapshots, :id, opts )
254
+ snapshots
255
+ end
256
+
257
+ #--
258
+ # Buckets
259
+ #--
260
+ def buckets(credentials, opts=nil)
261
+ check_credentials(credentials)
262
+ buckets=[]
263
+ Dir[ "#{@storage_root}/buckets/*.yml" ].each do |bucket_file|
264
+ bucket = YAML.load( File.read( bucket_file ) )
265
+ bucket[:id] = File.basename( bucket_file, ".yml" )
266
+ bucket[:name] = bucket[:id]
267
+ buckets << Bucket.new( bucket )
268
+ end
269
+ buckets = filter_on( buckets, :id, opts )
270
+ buckets
271
+ end
272
+
273
+ #--
274
+ # Create bucket
275
+ #--
276
+ def create_bucket(credentials, name, opts=nil)
277
+ check_credentials(credentials)
278
+ bucket = {
279
+ :name=>name,
280
+ :size=>'0',
281
+ :blob_list=>[]
282
+ }
283
+ File.open( "#{@storage_root}/buckets/#{name}.yml", 'w' ) {|b| YAML.dump( bucket, b )}
284
+ Bucket.new(bucket)
285
+ end
286
+
287
+ #--
288
+ # Delete bucket
289
+ #--
290
+ def delete_bucket(credentials, name, opts=nil)
291
+ bucket = bucket(credentials, {:id => name})
292
+ unless (bucket.size == "0")
293
+ raise Deltacloud::BackendError.new(403, self.class.to_s, "bucket-not-empty", "delete operation not valid for non-empty bucket")
294
+ end
295
+ safely do
296
+ File.delete("#{@storage_root}/buckets/#{name}.yml")
297
+ end
298
+ end
299
+
300
+ #--
301
+ # Blobs
302
+ #--
303
+ def blobs(credentials, opts = nil)
304
+ check_credentials(credentials)
305
+ blobs=[]
306
+ Dir[ "#{@storage_root}/buckets/blobs/*.yml" ].each do |blob_file|
307
+ blob = YAML.load( File.read( blob_file ) )
308
+ blob[:id] = File.basename( blob_file, ".yml" )
309
+ blob[:name] = blob[:id]
310
+ blobs << Blob.new( blob )
311
+ end
312
+ blobs = filter_on( blobs, :id, opts )
313
+ blobs
314
+ end
315
+
316
+ #--
317
+ # Blob content
318
+ #--
319
+ def blob_data(credentials, bucket_id, blob_id, opts = nil)
320
+ check_credentials(credentials)
321
+ blob=nil
322
+ Dir[ "#{@storage_root}/buckets/blobs/*.yml" ].each do |blob_file|
323
+ if File.basename(blob_file, ".yml") == blob_id
324
+ blob = YAML.load(File.read(blob_file))
325
+ blob[:content].each {|part| yield part}
326
+ end
327
+ end
328
+ end
329
+
330
+ def valid_credentials?(credentials)
331
+ begin
332
+ check_credentials(credentials)
333
+ return true
334
+ rescue Deltacloud::AuthException
335
+ end
336
+ return false
337
+ end
338
+
339
+ private
340
+
341
+ def check_credentials(credentials)
342
+ if ( credentials.user != 'mockuser' )
343
+ raise Deltacloud::AuthException.new
344
+ end
345
+
346
+ if ( credentials.password != 'mockpassword' )
347
+ raise Deltacloud::AuthException.new
348
+ end
349
+ end
350
+
351
+
352
+ end
353
+
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,116 @@
1
+ #--------------------------------------------------------------------------- #
2
+ # Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
3
+ # Complutense de Madrid (dsa-research.org)
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #--------------------------------------------------------------------------- #
19
+
20
+ require 'rubygems'
21
+ require 'uri'
22
+
23
+ require 'net/https'
24
+
25
+ begin
26
+ require 'net/http/post/multipart'
27
+ rescue LoadError
28
+ end
29
+
30
+ ###############################################################################
31
+ # The CloudClient module contains general functionality to implement a
32
+ # Cloud Client
33
+ ###############################################################################
34
+ module CloudClient
35
+ # #########################################################################
36
+ # Default location for the authentication file
37
+ # #########################################################################
38
+ DEFAULT_AUTH_FILE = ENV["HOME"]+"/.one/one_auth"
39
+
40
+ # #########################################################################
41
+ # Gets authorization credentials from ONE_AUTH or default
42
+ # auth file.
43
+ #
44
+ # Raises an error if authorization is not found
45
+ # #########################################################################
46
+ def self.get_one_auth
47
+ if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and
48
+ File.file?(ENV["ONE_AUTH"])
49
+ one_auth=File.read(ENV["ONE_AUTH"]).strip.split(':')
50
+ elsif File.file?(DEFAULT_AUTH_FILE)
51
+ one_auth=File.read(DEFAULT_AUTH_FILE).strip.split(':')
52
+ else
53
+ raise "No authorization data present"
54
+ end
55
+
56
+ raise "Authorization data malformed" if one_auth.length < 2
57
+
58
+ one_auth
59
+ end
60
+
61
+ # #########################################################################
62
+ # Starts an http connection and calls the block provided. SSL flag
63
+ # is set if needed.
64
+ # #########################################################################
65
+ def self.http_start(url, &block)
66
+ http = Net::HTTP.new(url.host, url.port)
67
+ if url.scheme=='https'
68
+ http.use_ssl = true
69
+ http.verify_mode=OpenSSL::SSL::VERIFY_NONE
70
+ end
71
+
72
+ begin
73
+ http.start do |connection|
74
+ block.call(connection)
75
+ end
76
+ rescue Errno::ECONNREFUSED => e
77
+ str = "Error connecting to server (#{e.to_s})."
78
+ str << "Server: #{url.host}:#{url.port}"
79
+
80
+ return CloudClient::Error.new(str)
81
+ end
82
+ end
83
+
84
+ # #########################################################################
85
+ # The Error Class represents a generic error in the Cloud Client
86
+ # library. It contains a readable representation of the error.
87
+ # #########################################################################
88
+ class Error
89
+ attr_reader :message
90
+
91
+ # +message+ a description of the error
92
+ def initialize(message=nil)
93
+ @message=message
94
+ end
95
+
96
+ def to_s()
97
+ @message
98
+ end
99
+ end
100
+
101
+ # #########################################################################
102
+ # Returns true if the object returned by a method of the OpenNebula
103
+ # library is an Error
104
+ # #########################################################################
105
+ def self.is_error?(value)
106
+ value.class==CloudClient::Error
107
+ end
108
+ end
109
+
110
+ # Command line help functions
111
+ module CloudCLI
112
+ # Returns the command name
113
+ def cmd_name
114
+ File.basename($0)
115
+ end
116
+ end
@@ -0,0 +1,204 @@
1
+ #--------------------------------------------------------------------------- #
2
+ # Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
3
+ # Complutense de Madrid (dsa-research.org)
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #--------------------------------------------------------------------------- #
19
+
20
+ require 'rubygems'
21
+ require 'uri'
22
+ require 'rexml/document'
23
+
24
+ require 'deltacloud/drivers/opennebula/cloud_client'
25
+
26
+
27
+ module OCCIClient
28
+
29
+ #####################################################################
30
+ # Client Library to interface with the OpenNebula OCCI Service
31
+ #####################################################################
32
+ class Client
33
+
34
+ ######################################################################
35
+ # Initialize client library
36
+ ######################################################################
37
+ def initialize(endpoint_str=nil, user=nil, pass=nil, debug_flag=true)
38
+ @debug = debug_flag
39
+
40
+ # Server location
41
+ if endpoint_str
42
+ @endpoint = endpoint_str
43
+ elsif ENV["OCCI_URL"]
44
+ @endpoint = ENV["OCCI_URL"]
45
+ else
46
+ @endpoint = "http://localhost:4567"
47
+ end
48
+
49
+ # Autentication
50
+ if user && pass
51
+ @occiauth = [user, pass]
52
+ else
53
+ @occiauth = CloudClient::get_one_auth
54
+ end
55
+
56
+ if !@occiauth
57
+ raise "No authorization data present"
58
+ end
59
+
60
+ @occiauth[1] = Digest::SHA1.hexdigest(@occiauth[1])
61
+ end
62
+
63
+ #################################
64
+ # Pool Resource Request Methods #
65
+ #################################
66
+
67
+ ######################################################################
68
+ # Post a new VM to the VM Pool
69
+ # :instance_type
70
+ # :xmlfile
71
+ ######################################################################
72
+ def post_vms(xmlfile)
73
+ xml=File.read(xmlfile)
74
+
75
+ url = URI.parse(@endpoint+"/compute")
76
+
77
+ req = Net::HTTP::Post.new(url.path)
78
+ req.body=xml
79
+
80
+ req.basic_auth @occiauth[0], @occiauth[1]
81
+
82
+ res = CloudClient::http_start(url) do |http|
83
+ http.request(req)
84
+ end
85
+
86
+ if CloudClient::is_error?(res)
87
+ return res
88
+ else
89
+ return res.body
90
+ end
91
+ end
92
+
93
+ ######################################################################
94
+ # Retieves the pool of Virtual Machines
95
+ ######################################################################
96
+ def get_vms
97
+ url = URI.parse(@endpoint+"/compute")
98
+ req = Net::HTTP::Get.new(url.path)
99
+
100
+ req.basic_auth @occiauth[0], @occiauth[1]
101
+
102
+ res = CloudClient::http_start(url) {|http|
103
+ http.request(req)
104
+ }
105
+
106
+ if CloudClient::is_error?(res)
107
+ return res
108
+ else
109
+ return res.body
110
+ end
111
+ end
112
+
113
+ ######################################################################
114
+ # Retieves the pool of Images owned by the user
115
+ ######################################################################
116
+ def get_images
117
+ url = URI.parse(@endpoint+"/storage")
118
+ req = Net::HTTP::Get.new(url.path)
119
+
120
+ req.basic_auth @occiauth[0], @occiauth[1]
121
+
122
+ res = CloudClient::http_start(url) {|http|
123
+ http.request(req)
124
+ }
125
+
126
+ if CloudClient::is_error?(res)
127
+ return res
128
+ else
129
+ return res.body
130
+ end
131
+ end
132
+
133
+ ####################################
134
+ # Entity Resource Request Methods #
135
+ ####################################
136
+
137
+ ######################################################################
138
+ # :id VM identifier
139
+ ######################################################################
140
+ def get_vm(id)
141
+ url = URI.parse(@endpoint+"/compute/" + id.to_s)
142
+ req = Net::HTTP::Get.new(url.path)
143
+
144
+ req.basic_auth @occiauth[0], @occiauth[1]
145
+
146
+ res = CloudClient::http_start(url) {|http|
147
+ http.request(req)
148
+ }
149
+
150
+ if CloudClient::is_error?(res)
151
+ return res
152
+ else
153
+ return res.body
154
+ end
155
+ end
156
+
157
+ ######################################################################
158
+ # Puts a new Compute representation in order to change its state
159
+ # :xmlfile Compute OCCI xml representation
160
+ ######################################################################
161
+ def put_vm(xmlfile)
162
+ xml=File.read(xmlfile)
163
+ vm_info=REXML::Document.new(xml).root.elements
164
+
165
+ url = URI.parse(@endpoint+'/compute/' + vm_info['ID'].text)
166
+
167
+ req = Net::HTTP::Put.new(url.path)
168
+ req.body = xml
169
+
170
+ req.basic_auth @occiauth[0], @occiauth[1]
171
+
172
+ res = CloudClient::http_start(url) do |http|
173
+ http.request(req)
174
+ end
175
+
176
+ if CloudClient::is_error?(res)
177
+ return res
178
+ else
179
+ return res.body
180
+ end
181
+ end
182
+
183
+ #######################################################################
184
+ # Retieves an Image
185
+ # :image_uuid Image identifier
186
+ ######################################################################
187
+ def get_image(image_uuid)
188
+ url = URI.parse(@endpoint+"/storage/"+image_uuid)
189
+ req = Net::HTTP::Get.new(url.path)
190
+
191
+ req.basic_auth @occiauth[0], @occiauth[1]
192
+
193
+ res = CloudClient::http_start(url) {|http|
194
+ http.request(req)
195
+ }
196
+
197
+ if CloudClient::is_error?(res)
198
+ return res
199
+ else
200
+ return res.body
201
+ end
202
+ end
203
+ end
204
+ end