deltacloud-core 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,6 +13,8 @@ require 'deltacloud/models/key'
13
13
  require 'deltacloud/models/instance_profile'
14
14
  require 'deltacloud/models/storage_snapshot'
15
15
  require 'deltacloud/models/storage_volume'
16
+ require 'deltacloud/models/bucket'
17
+ require 'deltacloud/models/blob'
16
18
 
17
19
  require 'deltacloud/validation'
18
20
  require 'deltacloud/helpers'
@@ -185,6 +185,36 @@ module Deltacloud
185
185
  []
186
186
  end
187
187
 
188
+ def buckets(credentials, opts = nil)
189
+ #list of buckets belonging to account
190
+ []
191
+ end
192
+
193
+ def bucket(credentials, opts = nil)
194
+ #list of objects within bucket
195
+ list = buckets(credentials, opts)
196
+ return list.first unless list.empty?
197
+ nil
198
+ end
199
+
200
+ def create_bucket(credentials, name, opts=nil)
201
+ end
202
+
203
+ def delete_bucket(credentials, name, opts=nil)
204
+ end
205
+
206
+ def blobs(credentials, opts = nil)
207
+ []
208
+ end
209
+
210
+ def blob(credentials, opts = nil)
211
+ list = blobs(credentials, opts)
212
+ return list.first unless list.empty?
213
+ end
214
+
215
+ def blob_data(credentials, bucket_id, blob_id, opts)
216
+ end
217
+
188
218
  def filter_on(collection, attribute, opts)
189
219
  return collection if opts.nil?
190
220
  return collection if opts[attribute].nil?
@@ -162,5 +162,12 @@ module Deltacloud
162
162
  description "Size instances according to changes to a hardware profile"
163
163
  # The parameters are filled in from the hardware profiles
164
164
  end
165
+
166
+ declare_feature :buckets, :bucket_location do
167
+ description "Take extra location parameter for Bucket creation (e.g. S3, 'eu' or 'us-west-1')"
168
+ operation :create do
169
+ param :location, :string, :optional
170
+ end
171
+ end
165
172
  end
166
173
  end
@@ -3,6 +3,19 @@ require 'deltacloud/method_serializer'
3
3
  # Create 'mock' version of original driver client/gem:
4
4
 
5
5
  module Mock
6
+
7
+ class S3 < RightAws::S3
8
+ include MethodSerializer::Cache
9
+
10
+ def self.cached_methods
11
+ [
12
+ :buckets
13
+ ]
14
+ end
15
+
16
+ MethodSerializer::Cache::wrap_methods(self, :cache_dir => File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'tests', 'ec2', 'support'))
17
+ end
18
+
6
19
  class EC2 < AWS::EC2::Base
7
20
 
8
21
  include MethodSerializer::Cache
@@ -29,6 +42,7 @@ end
29
42
  # Replace original client with mock client
30
43
  Deltacloud::Drivers::EC2::EC2Driver.class_eval do
31
44
  alias_method :original_new_client, :new_client
45
+ alias_method :original_s3_client, :s3_client
32
46
 
33
47
  def new_client(credentials, opts={})
34
48
  Mock::EC2.new(
@@ -37,4 +51,8 @@ Deltacloud::Drivers::EC2::EC2Driver.class_eval do
37
51
  )
38
52
  end
39
53
 
54
+ def s3_client(credentials)
55
+ Mock::S3.new(credentials.user, credentials.password)
56
+ end
57
+
40
58
  end
@@ -0,0 +1,127 @@
1
+ #
2
+ # Copyright (C) 2010 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
+ #Windows Azure (WAZ) gem at http://github.com/johnnyhalife/waz-storage
20
+ require 'waz-blobs'
21
+ require 'deltacloud/base_driver'
22
+ module Deltacloud
23
+ module Drivers
24
+ module Azure
25
+
26
+ class AzureDriver < Deltacloud::BaseDriver
27
+
28
+ def supported_collections; [:buckets]
29
+ end
30
+
31
+ #--
32
+ # Buckets
33
+ #--
34
+ def buckets(credentials, opts)
35
+ buckets = []
36
+ azure_connect(credentials)
37
+ safely do
38
+ WAZ::Blobs::Container.list.each do |waz_container|
39
+ buckets << convert_container(waz_container)
40
+ end
41
+ end
42
+ buckets = filter_on(buckets, :id, opts)
43
+ end
44
+
45
+ #--
46
+ # Create bucket
47
+ #--
48
+ def create_bucket(credentials, name, opts)
49
+ bucket = nil
50
+ azure_connect(credentials)
51
+ safely do
52
+ waz_container = WAZ::Blobs::Container.create(name)
53
+ bucket = convert_container(waz_container)
54
+ end
55
+ bucket
56
+ end
57
+
58
+ #--
59
+ # Delete bucket
60
+ #--
61
+ def delete_bucket(credentials, name, opts)
62
+ azure_connect(credentials)
63
+ safely do
64
+ WAZ::Blobs::Container.find(name).destroy!
65
+ end
66
+ end
67
+
68
+ #--
69
+ # Blobs
70
+ #--
71
+ def blobs(credentials, opts)
72
+ blob_list = []
73
+ azure_connect(credentials)
74
+ safely do
75
+ the_bucket = WAZ::Blobs::Container.find(opts['bucket'])
76
+ the_bucket.blobs.each do |waz_blob|
77
+ blob_list << convert_blob(waz_blob)
78
+ end
79
+ end
80
+ blob_list = filter_on(blob_list, :id, opts)
81
+ blob_list
82
+ end
83
+
84
+ def blob_data(credentials, bucket_id, blob_id, opts)
85
+ azure_connect(credentials)
86
+ # WAZ get blob data methods cant accept blocks for 'streaming'... FIXME
87
+ yield WAZ::Blobs::Container.find(bucket_id)[blob_id].value
88
+ end
89
+
90
+ private
91
+
92
+ def azure_connect(credentials)
93
+ options = {:account_name => credentials.user, :access_key => credentials.password}
94
+ safely do
95
+ WAZ::Storage::Base.establish_connection!(options)
96
+ end
97
+ end
98
+
99
+ def convert_container(waz_container)
100
+ blob_list = []
101
+ waz_container.blobs.each do |blob|
102
+ blob_list << blob.name
103
+ end
104
+ Bucket.new({ :id => waz_container.name,
105
+ :name => waz_container.name,
106
+ :size => blob_list.size,
107
+ :blob_list => blob_list
108
+ })
109
+ end
110
+
111
+ def convert_blob(waz_blob)
112
+ url = waz_blob.url.split('/')
113
+ bucket = url[url.length-2] #FIXME
114
+ Blob.new({ :id => waz_blob.name,
115
+ :bucket => bucket,
116
+ :content_length => waz_blob.metadata[:content_length],
117
+ :content_type => waz_blob.metadata[:content_type],
118
+ :last_modified => waz_blob.metadata[:last_modified]
119
+ })
120
+ end
121
+
122
+
123
+ end
124
+
125
+ end #module Azure
126
+ end #module Drivers
127
+ end #module Deltacloud
@@ -18,7 +18,9 @@
18
18
 
19
19
 
20
20
  require 'deltacloud/base_driver'
21
+ require 'active_support'
21
22
  require 'AWS'
23
+ require 'right_aws'
22
24
 
23
25
  class Instance
24
26
  attr_accessor :keyname
@@ -36,12 +38,13 @@ module Deltacloud
36
38
  class EC2Driver < Deltacloud::BaseDriver
37
39
 
38
40
  def supported_collections
39
- DEFAULT_COLLECTIONS + [ :keys ]
41
+ DEFAULT_COLLECTIONS + [ :keys, :buckets ]
40
42
  end
41
43
 
42
44
  feature :instances, :user_data
43
45
  feature :instances, :authentication_key
44
46
  feature :images, :owner_id
47
+ feature :buckets, :bucket_location
45
48
 
46
49
  define_hardware_profile('m1.small') do
47
50
  cpu 1
@@ -201,7 +204,7 @@ class EC2Driver < Deltacloud::BaseDriver
201
204
  # at this point, the action has succeeded but our follow-up
202
205
  # "describe_instances" failed for some reason. Create a simple Instance
203
206
  # object with only the ID and new state in place
204
- state = backup.instancesSet.item.first.currentState.name
207
+ state = convert_state(backup.instancesSet.item.first.currentState.name)
205
208
  Instance.new( {
206
209
  :id => id,
207
210
  :state => state,
@@ -319,6 +322,83 @@ class EC2Driver < Deltacloud::BaseDriver
319
322
  return realms ? true : false
320
323
  end
321
324
 
325
+ #--
326
+ # Buckets
327
+ #-- get a list of your buckets from the s3 service
328
+ def buckets(credentials, opts)
329
+ buckets = []
330
+ safely do
331
+ s3_client = s3_client(credentials)
332
+ bucket_list = s3_client.buckets
333
+ bucket_list.each do |current|
334
+ buckets << convert_bucket(current)
335
+ end
336
+ end
337
+ buckets = filter_on(buckets, :id, opts)
338
+ buckets
339
+ end
340
+
341
+ #--
342
+ # Create bucket
343
+ #--
344
+ #valid values for bucket location: 'EU'|'us-west1'|'ap-southeast-1' - if you
345
+ #don't specify a location then by default buckets are created in 'us-east'
346
+ #[but if you *do* specify 'us-east' things blow up]
347
+ def create_bucket(credentials, name, opts={})
348
+ bucket = nil
349
+ safely do
350
+ begin
351
+ s3_client = s3_client(credentials)
352
+ bucket_location = opts['location']
353
+ if bucket_location
354
+ bucket = RightAws::S3::Bucket.create(s3_client, name, true, nil, :location => bucket_location)
355
+ else
356
+ bucket = RightAws::S3::Bucket.create(s3_client, name, true)
357
+ end #if
358
+ rescue RightAws::AwsError => e
359
+ raise e unless e.message =~ /BucketAlreadyExists/
360
+ raise Deltacloud::BackendError.new(409, e.class.to_s, e.message, e.backtrace)
361
+ end #begin
362
+ end #do
363
+ convert_bucket(bucket)
364
+ end
365
+
366
+ #--
367
+ # Delete_bucket
368
+ #--
369
+ def delete_bucket(credentials, name, opts={})
370
+ s3_client = s3_client(credentials)
371
+ safely do
372
+ s3_client.interface.delete_bucket(name)
373
+ end
374
+ end
375
+
376
+ #--
377
+ # Blobs
378
+ #--
379
+ def blobs(credentials, opts = nil)
380
+ s3_client = s3_client(credentials)
381
+ blobs = []
382
+ safely do
383
+ s3_bucket = s3_client.bucket(opts['bucket'])
384
+ s3_bucket.keys({}, true).each do |s3_object|
385
+ blobs << convert_object(s3_object)
386
+ end
387
+ end
388
+ blobs = filter_on(blobs, :id, opts)
389
+ blobs
390
+ end
391
+
392
+ #--
393
+ # Blob data
394
+ #--
395
+ def blob_data(credentials, bucket_id, blob_id, opts)
396
+ s3_client = s3_client(credentials)
397
+ s3_client.interface.get(bucket_id, blob_id) do |chunk|
398
+ yield chunk
399
+ end
400
+ end
401
+
322
402
  private
323
403
 
324
404
  def new_client(credentials)
@@ -360,9 +440,23 @@ class EC2Driver < Deltacloud::BaseDriver
360
440
  } )
361
441
  end
362
442
 
443
+ def convert_state(ec2_state)
444
+ case ec2_state
445
+ when "terminated"
446
+ "STOPPED"
447
+ when "stopped"
448
+ "STOPPED"
449
+ when "running"
450
+ "RUNNING"
451
+ when "pending"
452
+ "PENDING"
453
+ when "shutting-down"
454
+ "STOPPED"
455
+ end
456
+ end
457
+
363
458
  def convert_instance(ec2_instance, owner_id)
364
- state = ec2_instance['instanceState']['name'].upcase
365
- state_key = state.downcase.underscore.to_sym
459
+ state = convert_state(ec2_instance['instanceState']['name'])
366
460
  realm_id = ec2_instance['placement']['availabilityZone']
367
461
  (realm_id = nil ) if ( realm_id == '' )
368
462
  hwp_name = ec2_instance['instanceType']
@@ -404,6 +498,36 @@ class EC2Driver < Deltacloud::BaseDriver
404
498
  } )
405
499
  end
406
500
 
501
+ def s3_client(credentials)
502
+ safely do
503
+ s3_client = RightAws::S3.new(credentials.user, credentials.password)
504
+ end
505
+ end
506
+
507
+ def convert_bucket(s3_bucket)
508
+ #get blob list:
509
+ blob_list = []
510
+ s3_bucket.keys.each do |s3_object|
511
+ blob_list << s3_object.name
512
+ end
513
+ #can use AWS::S3::Owner.current.display_name or current.id
514
+ Bucket.new( { :id => s3_bucket.name,
515
+ :name => s3_bucket.name,
516
+ :size => s3_bucket.keys.length,
517
+ :blob_list => blob_list
518
+ }
519
+ )
520
+ end
521
+
522
+ def convert_object(s3_object)
523
+ Blob.new({ :id => s3_object.name,
524
+ :bucket => s3_object.bucket.name.to_s,
525
+ :content_length => s3_object.size,
526
+ :content_type => s3_object.content_type,
527
+ :last_modified => s3_object.last_modified
528
+ })
529
+ end
530
+
407
531
  def catched_exceptions_list
408
532
  {
409
533
  :auth => [ AWS::AuthFailure ],
@@ -285,6 +285,9 @@ class GogridDriver < Deltacloud::BaseDriver
285
285
  end
286
286
  prof = InstanceProfile.new("server", opts)
287
287
 
288
+ hwp_name = instance['image']['name']
289
+ state = convert_server_state(instance['state']['name'], instance['id'])
290
+
288
291
  Instance.new(
289
292
  # note that we use 'name' as the id here, because newly created instances
290
293
  # don't get a real ID until later on. The name is good enough; from
@@ -296,8 +299,8 @@ class GogridDriver < Deltacloud::BaseDriver
296
299
  :instance_profile => prof,
297
300
  :name => instance['name'],
298
301
  :realm_id => instance['ip']['datacenter']['id'],
299
- :state => convert_server_state(instance['state']['name'], instance['id']),
300
- :actions => instance_actions_for(convert_server_state(instance['state']['name'], instance['id'])),
302
+ :state => state,
303
+ :actions => instance_actions_for(state),
301
304
  :public_addresses => [ instance['ip']['ip'] ],
302
305
  :private_addresses => [],
303
306
  :username => instance['username'],
@@ -185,34 +185,28 @@ class MockDriver < Deltacloud::BaseDriver
185
185
  Instance.new( instance )
186
186
  end
187
187
 
188
- def start_instance(credentials, id)
188
+ def update_instance_state(credentials, id, state)
189
189
  instance_file = "#{@storage_root}/instances/#{id}.yml"
190
190
  instance_yml = YAML.load( File.read( instance_file ) )
191
- instance_yml[:state] = 'RUNNING'
191
+ instance_yml[:id] = id
192
+ instance_yml[:state] = state
193
+ instance_yml[:actions] = instance_actions_for( instance_yml[:state] )
192
194
  File.open( instance_file, 'w' ) do |f|
193
195
  f << YAML.dump( instance_yml )
194
196
  end
195
197
  Instance.new( instance_yml )
196
198
  end
197
199
 
200
+ def start_instance(credentials, id)
201
+ update_instance_state(credentials, id, 'RUNNING')
202
+ end
203
+
198
204
  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 )
205
+ update_instance_state(credentials, id, 'RUNNING')
206
206
  end
207
207
 
208
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 )
209
+ update_instance_state(credentials, id, 'STOPPED')
216
210
  end
217
211
 
218
212