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,277 @@
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
+ ( REALMS = [
29
+ Realm.new({
30
+ :id=>'us',
31
+ :name=>'United States',
32
+ :limit=>:unlimited,
33
+ :state=>'AVAILABLE',
34
+ }),
35
+ Realm.new({
36
+ :id=>'eu',
37
+ :name=>'Europe',
38
+ :limit=>:unlimited,
39
+ :state=>'AVAILABLE',
40
+ }),
41
+ ] ) unless defined?( REALMS )
42
+
43
+ define_hardware_profile('m1-small') do
44
+ cpu 1
45
+ memory 1.7 * 1024
46
+ storage 160
47
+ architecture 'i386'
48
+ end
49
+
50
+ define_hardware_profile('m1-large') do
51
+ cpu 2
52
+ memory (7.5*1024 .. 15*1024), :default => 10 * 1024
53
+ storage [ 850, 1024 ]
54
+ architecture 'x86_64'
55
+ end
56
+
57
+ define_hardware_profile('m1-xlarge') do
58
+ cpu 4
59
+ memory (12*1024 .. 32*1024)
60
+ storage [ 1024, 2048, 4096 ]
61
+ architecture 'x86_64'
62
+ end
63
+
64
+ # Some clouds tell us nothing about hardware profiles (e.g., OpenNebula)
65
+ define_hardware_profile 'opaque'
66
+
67
+ define_instance_states do
68
+ start.to( :pending ) .on( :create )
69
+
70
+ pending.to( :running ) .automatically
71
+
72
+ running.to( :running ) .on( :reboot )
73
+ running.to( :stopped ) .on( :stop )
74
+
75
+ stopped.to( :running ) .on( :start )
76
+ stopped.to( :finish ) .on( :destroy )
77
+ end
78
+
79
+ feature :instances, :user_name
80
+
81
+ def initialize
82
+ if ENV["DELTACLOUD_MOCK_STORAGE"]
83
+ @storage_root = ENV["DELTACLOUD_MOCK_STORAGE"]
84
+ elsif ENV["USER"]
85
+ @storage_root = File::join("/var/tmp", "deltacloud-mock-#{ENV["USER"]}")
86
+ else
87
+ raise "Please set either the DELTACLOUD_MOCK_STORAGE or USER environment variable"
88
+ end
89
+ if ! File::directory?(@storage_root)
90
+ FileUtils::rm_rf(@storage_root)
91
+ FileUtils::mkdir_p(@storage_root)
92
+ data = Dir::glob(File::join(File::dirname(__FILE__), "data", "*"))
93
+ FileUtils::cp_r(data, @storage_root)
94
+ end
95
+ end
96
+
97
+ def realms(credentials, opts=nil)
98
+ return REALMS if ( opts.nil? )
99
+ results = REALMS
100
+ results = filter_on( results, :id, opts )
101
+ results
102
+ end
103
+
104
+ #
105
+ # Images
106
+ #
107
+
108
+ def images(credentials, opts=nil )
109
+ check_credentials( credentials )
110
+ images = []
111
+ Dir[ "#{@storage_root}/images/*.yml" ].each do |image_file|
112
+ image = YAML.load( File.read( image_file ) )
113
+ image[:id] = File.basename( image_file, ".yml" )
114
+ image[:name] = image[:description]
115
+ images << Image.new( image )
116
+ end
117
+ images = filter_on( images, :id, opts )
118
+ images = filter_on( images, :architecture, opts )
119
+ if ( opts && opts[:owner_id] == 'self' )
120
+ images = images.select{|e| e.owner_id == credentials.user }
121
+ else
122
+ images = filter_on( images, :owner_id, opts )
123
+ end
124
+ images.sort_by{|e| [e.owner_id,e.description]}
125
+ end
126
+
127
+ #
128
+ # Instances
129
+ #
130
+
131
+ def instances(credentials, opts=nil)
132
+ check_credentials( credentials )
133
+ instances = []
134
+ Dir[ "#{@storage_root}/instances/*.yml" ].each do |instance_file|
135
+ instance = YAML.load( File.read( instance_file ) )
136
+ if ( instance[:owner_id] == credentials.user )
137
+ instance[:id] = File.basename( instance_file, ".yml" )
138
+ instance[:actions] = instance_actions_for( instance[:state] )
139
+ instances << Instance.new( instance )
140
+ end
141
+ end
142
+ instances = filter_on( instances, :id, opts )
143
+ instances = filter_on( instances, :state, opts )
144
+ instances
145
+ end
146
+
147
+ def create_instance(credentials, image_id, opts)
148
+ check_credentials( credentials )
149
+ ids = Dir[ "#{@storage_root}/instances/*.yml" ].collect{|e| File.basename( e, ".yml" )}
150
+
151
+ count = 0
152
+ while true
153
+ next_id = "inst" + count.to_s
154
+ if not ids.include?(next_id)
155
+ break
156
+ end
157
+ count = count + 1
158
+ end
159
+
160
+ realm_id = opts[:realm_id]
161
+ if ( realm_id.nil? )
162
+ realm = realms(credentials).first
163
+ ( realm_id = realm.id ) if realm
164
+ end
165
+
166
+ hwp = find_hardware_profile(credentials, opts[:hwp_id], image_id)
167
+
168
+ name = opts[:name] || "i-#{Time.now.to_i}"
169
+
170
+ instance = {
171
+ :name=>name,
172
+ :state=>'RUNNING',
173
+ :image_id=>image_id,
174
+ :owner_id=>credentials.user,
175
+ :public_addresses=>["#{image_id}.#{next_id}.public.com"],
176
+ :private_addresses=>["#{image_id}.#{next_id}.private.com"],
177
+ :instance_profile => InstanceProfile.new(hwp.name, opts),
178
+ :realm_id=>realm_id,
179
+ :actions=>instance_actions_for( 'RUNNING' )
180
+ }
181
+ File.open( "#{@storage_root}/instances/#{next_id}.yml", 'w' ) {|f|
182
+ YAML.dump( instance, f )
183
+ }
184
+ instance[:id] = next_id
185
+ Instance.new( instance )
186
+ end
187
+
188
+ def start_instance(credentials, id)
189
+ instance_file = "#{@storage_root}/instances/#{id}.yml"
190
+ instance_yml = YAML.load( File.read( instance_file ) )
191
+ instance_yml[:state] = 'RUNNING'
192
+ File.open( instance_file, 'w' ) do |f|
193
+ f << YAML.dump( instance_yml )
194
+ end
195
+ Instance.new( instance_yml )
196
+ end
197
+
198
+ def reboot_instance(credentials, id)
199
+ instance_file = "#{@storage_root}/instances/#{id}.yml"
200
+ instance_yml = YAML.load( File.read( instance_file ) )
201
+ instance_yml[:state] = 'RUNNING'
202
+ File.open( instance_file, 'w' ) do |f|
203
+ f << YAML.dump( instance_yml )
204
+ end
205
+ Instance.new( instance_yml )
206
+ end
207
+
208
+ def stop_instance(credentials, id)
209
+ instance_file = "#{@storage_root}/instances/#{id}.yml"
210
+ instance_yml = YAML.load( File.read( instance_file ) )
211
+ instance_yml[:state] = 'STOPPED'
212
+ File.open( instance_file, 'w' ) do |f|
213
+ f << YAML.dump( instance_yml )
214
+ end
215
+ Instance.new( instance_yml )
216
+ end
217
+
218
+
219
+ def destroy_instance(credentials, id)
220
+ check_credentials( credentials )
221
+ FileUtils.rm( "#{@storage_root}/instances/#{id}.yml" )
222
+ end
223
+
224
+ #
225
+ # Storage Volumes
226
+ #
227
+
228
+ def storage_volumes(credentials, opts=nil)
229
+ check_credentials( credentials )
230
+ volumes = []
231
+ Dir[ "#{@storage_root}/storage_volumes/*.yml" ].each do |storage_volume_file|
232
+ storage_volume = YAML.load( File.read( storage_volume_file ) )
233
+ if ( storage_volume[:owner_id] == credentials.user )
234
+ storage_volume[:id] = File.basename( storage_volume_file, ".yml" )
235
+ volumes << StorageVolume.new( storage_volume )
236
+ end
237
+ end
238
+ volumes = filter_on( volumes, :id, opts )
239
+ volumes
240
+ end
241
+
242
+ #
243
+ # Storage Snapshots
244
+ #
245
+
246
+ def storage_snapshots(credentials, opts=nil)
247
+ check_credentials( credentials )
248
+ snapshots = []
249
+ Dir[ "#{@storage_root}/storage_snapshots/*.yml" ].each do |storage_snapshot_file|
250
+ storage_snapshot = YAML.load( File.read( storage_snapshot_file ) )
251
+ if ( storage_snapshot[:owner_id] == credentials.user )
252
+ storage_snapshot[:id] = File.basename( storage_snapshot_file, ".yml" )
253
+ snapshots << StorageSnapshot.new( storage_snapshot )
254
+ end
255
+ end
256
+ snapshots = filter_on( snapshots, :id, opts )
257
+ snapshots
258
+ end
259
+
260
+ private
261
+
262
+ def check_credentials(credentials)
263
+ if ( credentials.user != 'mockuser' )
264
+ raise Deltacloud::AuthException.new
265
+ end
266
+
267
+ if ( credentials.password != 'mockpassword' )
268
+ raise Deltacloud::AuthException.new
269
+ end
270
+ end
271
+
272
+
273
+ end
274
+
275
+ end
276
+ end
277
+ 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