deltacloud-core 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. data/Rakefile +63 -7
  2. data/bin/deltacloudd +29 -17
  3. data/config.ru +5 -3
  4. data/config/drivers/ec2.yaml +9 -0
  5. data/config/drivers/google.yaml +3 -0
  6. data/config/drivers/openstack.yaml +3 -0
  7. data/deltacloud-core.gemspec +1 -1
  8. data/lib/cimi/dependencies.rb +62 -0
  9. data/lib/cimi/helpers/cimi_helper.rb +50 -0
  10. data/lib/cimi/model.rb +52 -0
  11. data/lib/cimi/model/action.rb +24 -0
  12. data/lib/cimi/model/base.rb +249 -0
  13. data/lib/cimi/model/cloud_entry_point.rb +48 -0
  14. data/lib/cimi/model/entity_metadata.rb +83 -0
  15. data/lib/cimi/model/entity_metadata_collection.rb +31 -0
  16. data/lib/cimi/model/errors.rb +40 -0
  17. data/lib/cimi/model/machine.rb +227 -0
  18. data/lib/cimi/model/machine_admin.rb +59 -0
  19. data/lib/cimi/model/machine_admin_collection.rb +34 -0
  20. data/lib/cimi/model/machine_collection.rb +34 -0
  21. data/lib/cimi/model/machine_configuration.rb +67 -0
  22. data/lib/cimi/model/machine_configuration_collection.rb +34 -0
  23. data/lib/cimi/model/machine_image.rb +46 -0
  24. data/lib/cimi/model/machine_image_collection.rb +34 -0
  25. data/lib/cimi/model/machine_template.rb +41 -0
  26. data/lib/cimi/model/machine_template_collection.rb +34 -0
  27. data/lib/cimi/model/network.rb +69 -0
  28. data/lib/cimi/model/network_collection.rb +34 -0
  29. data/lib/cimi/model/network_configuration.rb +50 -0
  30. data/lib/cimi/model/network_configuration_collection.rb +34 -0
  31. data/lib/cimi/model/network_template.rb +26 -0
  32. data/lib/cimi/model/schema.rb +277 -0
  33. data/lib/cimi/model/volume.rb +103 -0
  34. data/lib/cimi/model/volume_collection.rb +34 -0
  35. data/lib/cimi/model/volume_configuration.rb +60 -0
  36. data/lib/cimi/model/volume_configuration_collection.rb +34 -0
  37. data/lib/cimi/model/volume_image.rb +49 -0
  38. data/lib/cimi/model/volume_image_collection.rb +34 -0
  39. data/lib/cimi/model/volume_template.rb +23 -0
  40. data/lib/cimi/model/volume_template_collection.rb +34 -0
  41. data/lib/cimi/server.rb +575 -0
  42. data/lib/deltacloud/base_driver/base_driver.rb +11 -1
  43. data/lib/deltacloud/core_ext.rb +2 -0
  44. data/lib/deltacloud/core_ext/array.rb +25 -0
  45. data/lib/deltacloud/core_ext/hash.rb +7 -0
  46. data/lib/deltacloud/core_ext/proc.rb +31 -0
  47. data/lib/deltacloud/core_ext/string.rb +15 -0
  48. data/lib/deltacloud/drivers/condor/condor_driver.rb +2 -1
  49. data/lib/deltacloud/drivers/ec2/ec2_driver.rb +32 -10
  50. data/lib/deltacloud/drivers/eucalyptus/eucalyptus_driver.rb +1 -1
  51. data/lib/deltacloud/drivers/gogrid/gogrid_driver.rb +1 -1
  52. data/lib/deltacloud/drivers/google/google_driver.rb +233 -0
  53. data/lib/deltacloud/drivers/mock/data/instances/inst0.yml +7 -2
  54. data/lib/deltacloud/drivers/mock/data/instances/inst1.yml +7 -2
  55. data/lib/deltacloud/drivers/mock/data/instances/inst2.yml +7 -2
  56. data/lib/deltacloud/drivers/mock/mock_client.rb +17 -0
  57. data/lib/deltacloud/drivers/mock/mock_driver.rb +82 -8
  58. data/lib/deltacloud/drivers/opennebula/opennebula_driver.rb +1 -1
  59. data/lib/deltacloud/drivers/openstack/openstack_driver.rb +47 -0
  60. data/lib/deltacloud/drivers/rackspace/rackspace_driver.rb +8 -8
  61. data/lib/deltacloud/drivers/rhevm/rhevm_client.rb +122 -49
  62. data/lib/deltacloud/drivers/rhevm/rhevm_driver.rb +42 -22
  63. data/lib/deltacloud/drivers/rimuhosting/rimuhosting_driver.rb +1 -1
  64. data/lib/deltacloud/drivers/sbc/sbc_driver.rb +3 -2
  65. data/lib/deltacloud/drivers/terremark/terremark_driver.rb +2 -2
  66. data/lib/deltacloud/drivers/vsphere/vsphere_client.rb +25 -4
  67. data/lib/deltacloud/drivers/vsphere/vsphere_driver.rb +35 -12
  68. data/lib/deltacloud/hardware_profile.rb +34 -10
  69. data/lib/deltacloud/helpers/application_helper.rb +3 -28
  70. data/lib/deltacloud/helpers/blob_stream.rb +2 -1
  71. data/lib/deltacloud/models.rb +2 -0
  72. data/lib/deltacloud/models/bucket.rb +1 -1
  73. data/lib/deltacloud/models/image.rb +1 -1
  74. data/lib/deltacloud/models/instance.rb +2 -1
  75. data/lib/deltacloud/models/instance_address.rb +56 -0
  76. data/lib/deltacloud/models/provider.rb +27 -0
  77. data/{server.rb → lib/deltacloud/server.rb} +72 -14
  78. data/lib/deltacloud/validation.rb +31 -10
  79. data/lib/sinatra/rabbit.rb +34 -26
  80. data/lib/sinatra/rack_accept.rb +5 -5
  81. data/lib/sinatra/rack_matrix_params.rb +6 -2
  82. data/lib/sinatra/rack_syslog.rb +3 -3
  83. data/lib/sinatra/static_assets.rb +1 -1
  84. data/lib/sinatra/url_for.rb +1 -7
  85. data/public/images/bread-bg.png +0 -0
  86. data/public/images/logo-wide.png +0 -0
  87. data/public/images/topbar-bg.png +0 -0
  88. data/public/javascripts/application.js +5 -0
  89. data/public/javascripts/cmwgapp.js +249 -0
  90. data/public/javascripts/jquery-1.4.2.min.js +154 -0
  91. data/public/javascripts/jquery.mobile-1.0rc1.min.js +170 -0
  92. data/public/stylesheets/images/icons-18-black.png +0 -0
  93. data/public/stylesheets/images/icons-18-white.png +0 -0
  94. data/public/stylesheets/images/icons-36-black.png +0 -0
  95. data/public/stylesheets/images/icons-36-white.png +0 -0
  96. data/public/stylesheets/jquery.mobile-1.0rc1.min.css +12 -0
  97. data/public/stylesheets/new.css +4 -0
  98. data/support/fedora/deltacloud-core.init +20 -13
  99. data/tests/cimi/features/step_definitions/common_steps.rb +59 -0
  100. data/tests/cimi/features/step_definitions/machine_images_steps.rb +0 -0
  101. data/tests/cimi/features/step_definitions/machines_steps.rb +99 -0
  102. data/tests/cimi/features/step_definitions/volumes_steps.rb +115 -0
  103. data/tests/cimi/features/support/env.rb +53 -0
  104. data/tests/common.rb +89 -11
  105. data/tests/core_ext/string.rb +31 -0
  106. data/tests/drivers/google/api_test.rb +35 -0
  107. data/tests/drivers/google/buckets_test.rb +116 -0
  108. data/tests/drivers/google/setup.rb +38 -0
  109. data/tests/drivers/mock/instances_test.rb +20 -5
  110. data/tests/drivers/openstack/api_test.rb +41 -0
  111. data/tests/drivers/openstack/hardware_profiles_test.rb +53 -0
  112. data/tests/drivers/openstack/images_test.rb +40 -0
  113. data/tests/drivers/openstack/instances_test.rb +163 -0
  114. data/tests/drivers/openstack/realms_test.rb +36 -0
  115. data/tests/drivers/openstack/setup.rb +20 -0
  116. data/tests/drivers/rackspace/buckets_test.rb +145 -0
  117. data/tests/drivers/rackspace/setup.rb +3 -3
  118. data/tests/drivers/rhevm/api_test.rb +1 -1
  119. data/tests/drivers/rhevm/images_test.rb +2 -2
  120. data/tests/drivers/rhevm/instances_test.rb +10 -12
  121. data/tests/drivers/rhevm/realms_test.rb +4 -4
  122. data/tests/drivers/rhevm/setup.rb +3 -3
  123. data/tests/rabbit_test.rb +1 -1
  124. data/views/api/show.html.haml +13 -0
  125. data/views/cimi/cloudEntryPoint/index.html.haml +5 -0
  126. data/views/cimi/cloudEntryPoint/index.xml.haml +9 -0
  127. data/views/cimi/collection/index.html.haml +45 -0
  128. data/views/cimi/collection/response.xml.haml +3 -0
  129. data/views/cimi/error.html.haml +31 -0
  130. data/views/cimi/errors/400.html.haml +41 -0
  131. data/views/cimi/errors/400.xml.haml +3 -0
  132. data/views/cimi/errors/401.html.haml +41 -0
  133. data/views/cimi/errors/401.xml.haml +2 -0
  134. data/views/cimi/errors/403.html.haml +42 -0
  135. data/views/cimi/errors/403.xml.haml +2 -0
  136. data/views/cimi/errors/404.html.haml +29 -0
  137. data/views/cimi/errors/404.xml.haml +2 -0
  138. data/views/cimi/errors/405.html.haml +29 -0
  139. data/views/cimi/errors/405.xml.haml +5 -0
  140. data/views/cimi/errors/500.html.haml +43 -0
  141. data/views/cimi/errors/500.xml.haml +6 -0
  142. data/views/cimi/errors/502.html.haml +43 -0
  143. data/views/cimi/errors/502.xml.haml +7 -0
  144. data/views/cimi/errors/backend_capability_failure.html.haml +29 -0
  145. data/views/cimi/layout.html.haml +32 -0
  146. data/views/cimi/machine_configurations/show.html.haml +159 -0
  147. data/views/cimi/machine_configurations/show.xml.haml +27 -0
  148. data/views/cimi/machine_images/show.html.haml +79 -0
  149. data/views/cimi/machine_images/show.xml.haml +17 -0
  150. data/views/cimi/machines/show.html.haml +177 -0
  151. data/views/cimi/machines/show.xml.haml +28 -0
  152. data/views/cimi/volumes/show.html.haml +68 -0
  153. data/views/cimi/volumes/show.xml.haml +17 -0
  154. data/views/drivers/show.html.haml +10 -5
  155. data/views/drivers/show.xml.haml +9 -4
  156. data/views/error.html.haml +2 -2
  157. data/views/errors/500.xml.haml +7 -1
  158. data/views/instances/index.html.haml +1 -1
  159. data/views/instances/new.html.haml +19 -16
  160. data/views/instances/show.html.haml +7 -2
  161. data/views/instances/show.xml.haml +8 -7
  162. data/views/layout.html.haml +2 -2
  163. data/views/storage_volumes/show.html.haml +1 -1
  164. metadata +296 -204
  165. data/public/javascripts/jquery.mobile-1.0b1.min.js +0 -146
  166. data/public/stylesheets/jquery.mobile-1.0b1.min.css +0 -8
@@ -14,7 +14,7 @@
14
14
  # License for the specific language governing permissions and limitations
15
15
  # under the License.
16
16
 
17
- require 'lib/deltacloud/base_driver/exceptions'
17
+ require 'deltacloud/base_driver/exceptions'
18
18
 
19
19
  module Deltacloud
20
20
 
@@ -22,6 +22,10 @@ module Deltacloud
22
22
 
23
23
  include ExceptionHandler
24
24
 
25
+ def name
26
+ self.class.name.split('::').last.gsub('Driver', '').downcase
27
+ end
28
+
25
29
  def self.exceptions(&block)
26
30
  ExceptionHandler::exceptions(&block)
27
31
  end
@@ -155,6 +159,7 @@ module Deltacloud
155
159
  # def delete_firewall(credentials, opts)
156
160
  # def create_firewall_rule(credentials, opts)
157
161
  # def delete_firewall_rule(credentials, opts)
162
+ # def providers(credentials)
158
163
  def realm(credentials, opts)
159
164
  realms = realms(credentials, opts).first if has_capability?(:realms)
160
165
  end
@@ -230,6 +235,11 @@ module Deltacloud
230
235
  Thread.current[:provider] || ENV['API_PROVIDER']
231
236
  end
232
237
 
238
+ # Return an array of the providers statically configured
239
+ # in the driver's YAML file
240
+ def configured_providers
241
+ []
242
+ end
233
243
  end
234
244
 
235
245
  end
@@ -17,3 +17,5 @@
17
17
  require 'deltacloud/core_ext/string'
18
18
  require 'deltacloud/core_ext/integer'
19
19
  require 'deltacloud/core_ext/hash'
20
+ require 'deltacloud/core_ext/array'
21
+ require 'deltacloud/core_ext/proc'
@@ -0,0 +1,25 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ class Array
17
+ def expand_opts!(more_opts)
18
+ self << {} unless last.is_a?(Hash)
19
+ last.update(more_opts)
20
+ end
21
+
22
+ def extract_opts!
23
+ last.is_a?(Hash) ? pop : {}
24
+ end
25
+ end
@@ -26,4 +26,11 @@ class Hash
26
26
  #remove the original keys
27
27
  self.delete_if{|k,v| remove.include?(k)}
28
28
  end
29
+
30
+ # Method copied from https://github.com/rails/rails/blob/77efc20a54708ba37ba679ffe90021bf8a8d3a8a/activesupport/lib/active_support/core_ext/hash/keys.rb#L23
31
+ def symbolize_keys
32
+ keys.each { |key| self[(key.to_sym rescue key) || key] = delete(key) }
33
+ self
34
+ end
35
+
29
36
  end
@@ -0,0 +1,31 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ # Original code copied from https://gist.github.com/1417762
17
+ # Copyright 2011 Emmanuel Oga.
18
+
19
+ class Proc
20
+
21
+ Callback = Struct.new(:called, :args) do
22
+ def method_missing(name, *)
23
+ name == :"#{called}?" || (name == called && block_given? && yield(*args))
24
+ end
25
+ end
26
+
27
+ def callback(callable, *args)
28
+ call Callback.new(callable, *args)
29
+ end
30
+
31
+ end
@@ -34,6 +34,8 @@ class String
34
34
 
35
35
  def pluralize
36
36
  return self + 'es' if self =~ /ess$/
37
+ return self[0, self.length-1] + "ies" if self =~ /ty$/
38
+ return self if self =~ /data$/
37
39
  self + "s"
38
40
  end
39
41
 
@@ -49,4 +51,17 @@ class String
49
51
  tr("-", "_").
50
52
  downcase
51
53
  end
54
+
55
+ def camelize(lowercase_first_letter=nil)
56
+ s = split('_').map { |w| w.capitalize }.join
57
+ lowercase_first_letter ? s.uncapitalize : s
58
+ end
59
+
60
+ def uncapitalize
61
+ self[0, 1].downcase + self[1..-1]
62
+ end
63
+
64
+ def upcase_first
65
+ self[0, 1].upcase + self[1..-1]
66
+ end
52
67
  end
@@ -105,7 +105,8 @@ module Deltacloud
105
105
  :realm_id => 'default',
106
106
  :instance_profile => InstanceProfile::new(instance.instance_profile.name),
107
107
  :image_id => instance.image_id,
108
- :public_addresses => [ ip_address ],
108
+ :public_addresses => [ InstanceAddress.new(ip_address) ],
109
+ :private_addresses => [],
109
110
  :owner_id => instance.owner_id,
110
111
  :description => instance.name,
111
112
  :architecture => 'x86_64',
@@ -51,7 +51,7 @@ module Deltacloud
51
51
  cpu 1
52
52
  memory 0.63 * 1024
53
53
  storage 160
54
- architecture 'i386'
54
+ architecture ['i386','x86_64']
55
55
  end
56
56
 
57
57
  define_hardware_profile('m1.small') do
@@ -134,7 +134,7 @@ module Deltacloud
134
134
  opts ||= {}
135
135
  if opts[:id]
136
136
  safely do
137
- img_arr = ec2.describe_images(opts[:id]).collect do |image|
137
+ img_arr = ec2.describe_images([opts[:id]]).collect do |image|
138
138
  convert_image(image)
139
139
  end
140
140
  end
@@ -142,7 +142,7 @@ module Deltacloud
142
142
  end
143
143
  owner_id = opts[:owner_id] || default_image_owner
144
144
  safely do
145
- img_arr = ec2.describe_images_by_owner(owner_id, default_image_type).collect do |image|
145
+ img_arr = ec2.describe_images_by_owner([owner_id], default_image_type).collect do |image|
146
146
  convert_image(image)
147
147
  end
148
148
  end
@@ -231,8 +231,14 @@ module Deltacloud
231
231
  }]
232
232
  end
233
233
  safely do
234
- new_instance = convert_instance(ec2.launch_instances(image_id, instance_options).first)
235
- new_instance
234
+ new_instances = ec2.launch_instances(image_id, instance_options).collect do |i|
235
+ convert_instance(i)
236
+ end
237
+ if new_instances.size == 1
238
+ new_instances.first
239
+ else
240
+ new_instances
241
+ end
236
242
  end
237
243
  end
238
244
 
@@ -372,7 +378,8 @@ module Deltacloud
372
378
  safely do
373
379
  s3_client = new_client(credentials, :s3)
374
380
  bucket_location = opts['location']
375
- if (bucket_location && bucket_location.size >0)
381
+ if (bucket_location && bucket_location.size >0 &&
382
+ (not bucket_location.eql?(DEFAULT_REGION)) )
376
383
  bucket = Aws::S3::Bucket.create(s3_client, name, true, nil, :location => bucket_location)
377
384
  else
378
385
  bucket = Aws::S3::Bucket.create(s3_client, name, true)
@@ -694,6 +701,16 @@ module Deltacloud
694
701
  end
695
702
  end
696
703
 
704
+ def providers(credentials, opts={})
705
+ ec2 = new_client(credentials)
706
+ providers = ec2.describe_regions.map{|r| Provider.new( {:id=>r, :name=>r,
707
+ :url=>"#{ENV['API_HOST']}:#{ENV['API_PORT']}#{settings.root_url}\;provider=#{r}" }) }
708
+ end
709
+
710
+ def configured_providers
711
+ Deltacloud::Drivers::driver_config[:ec2][:entrypoints]["ec2"].keys
712
+ end
713
+
697
714
  def valid_credentials?(credentials)
698
715
  retval = true
699
716
  begin
@@ -778,7 +795,11 @@ module Deltacloud
778
795
 
779
796
  def convert_instance(instance)
780
797
  can_create_image = 'ebs'.eql?(instance[:root_device_type]) and 'RUNNING'.eql?(convert_state(instance[:aws_state]))
781
- Instance.new(
798
+ inst_profile_opts={}
799
+ if instance[:aws_instance_type] == "t1.micro"
800
+ inst_profile_opts[:hwp_architecture]=instance[:architecture]
801
+ end
802
+ Instance.new(
782
803
  :id => instance[:aws_instance_id],
783
804
  :name => instance[:aws_image_id],
784
805
  :state => convert_state(instance[:aws_state]),
@@ -787,11 +808,12 @@ module Deltacloud
787
808
  :actions => instance_actions_for(convert_state(instance[:aws_state])),
788
809
  :keyname => instance[:ssh_key_name],
789
810
  :launch_time => instance[:aws_launch_time],
790
- :instance_profile => InstanceProfile.new(instance[:aws_instance_type]),
811
+ :instance_profile => InstanceProfile.new(instance[:aws_instance_type], inst_profile_opts),
791
812
  :realm_id => instance[:aws_availability_zone],
792
- :private_addresses => instance[:private_dns_name],
793
- :public_addresses => instance[:dns_name],
813
+ :public_addresses => [InstanceAddress.new(instance[:dns_name], :type => :hostname)],
814
+ :private_addresses => [InstanceAddress.new(instance[:private_dns_name], :type => :hostname)],
794
815
  :firewalls => instance[:aws_groups],
816
+ :storage_volumes => instance[:block_device_mappings].map{|vol| {vol.values.first=>vol.keys.first } },
795
817
  :create_image => can_create_image
796
818
  )
797
819
  end
@@ -75,7 +75,7 @@ module Deltacloud
75
75
  end
76
76
 
77
77
  def default_image_owner
78
- nil # list all images
78
+ "self"
79
79
  end
80
80
 
81
81
  def default_image_type
@@ -471,7 +471,7 @@ class GogridDriver < Deltacloud::BaseDriver
471
471
  :realm_id => instance['ip']['datacenter']['id'],
472
472
  :state => state,
473
473
  :actions => instance_actions_for(state),
474
- :public_addresses => [ instance['ip']['ip'] ],
474
+ :public_addresses => [ InstanceAddress.new(instance['ip']['ip']) ],
475
475
  :private_addresses => [],
476
476
  :username => instance['username'],
477
477
  :password => instance['password'],
@@ -0,0 +1,233 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with
3
+ # this work for additional information regarding copyright ownership. The
4
+ # ASF licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the
6
+ # License. You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ require 'fog'
17
+
18
+ module Deltacloud
19
+ module Drivers
20
+ module Google
21
+
22
+ class GoogleDriver < Deltacloud::BaseDriver
23
+
24
+ def supported_collections; [:buckets]
25
+ end
26
+
27
+ feature :buckets, :bucket_location
28
+
29
+ #--
30
+ # Buckets
31
+ #--
32
+ def buckets(credentials, opts={})
33
+ buckets = []
34
+ google_client = new_client(credentials)
35
+ safely do
36
+ if opts[:id]
37
+ bucket = google_client.get_bucket(opts[:id])
38
+ buckets << convert_bucket(bucket.body)
39
+ else
40
+ google_client.get_service.body['Buckets'].each do |bucket|
41
+ buckets << Bucket.new({:name => bucket['Name'], :id => bucket['Name']})
42
+ end
43
+ end
44
+ end
45
+ buckets = filter_on(buckets, :id, opts)
46
+ end
47
+
48
+ #--
49
+ # Create bucket - valid values for location {'EU','US'}
50
+ #--
51
+ def create_bucket(credentials, name, opts={})
52
+ google_client = new_client(credentials)
53
+ safely do
54
+ bucket_location = opts['location']
55
+ if (bucket_location && bucket_location.size > 0)
56
+ res = google_client.put_bucket(name, {"LocationConstraint" => opts['location']})
57
+ else
58
+ google_client.put_bucket(name)
59
+ end
60
+ #res.status should be eql 200 - but fog will explode if not all ok...
61
+ Bucket.new({ :id => name,
62
+ :name => name,
63
+ :size => 0,
64
+ :blob_list => [] })
65
+ end
66
+ end
67
+
68
+ #--
69
+ # Delete bucket
70
+ #--
71
+ def delete_bucket(credentials, name, opts={})
72
+ google_client = new_client(credentials)
73
+ safely do
74
+ google_client.delete_bucket(name)
75
+ end
76
+ end
77
+
78
+ #--
79
+ # Blobs
80
+ #--
81
+ def blobs(credentials, opts={})
82
+ blobs = []
83
+ google_client = new_client(credentials)
84
+ safely do
85
+ google_blob = google_client.head_object(opts['bucket'], opts[:id]).headers
86
+ meta_hash = google_blob.inject({}){|result, (k,v)| result[k]=v if k=~/^x-goog-meta-/i ; result}
87
+ meta_hash.gsub_keys("x-goog-meta-", "")
88
+ blobs << Blob.new({ :id => opts[:id],
89
+ :bucket => opts['bucket'],
90
+ :content_length => google_blob['Content-Length'],
91
+ :content_type => google_blob['Content-Type'],
92
+ :last_modified => google_blob['Last-Modified'],
93
+ :user_metadata => meta_hash
94
+ })
95
+
96
+ end
97
+ blobs
98
+ end
99
+
100
+ def blob_data(credentials, bucket_id, blob_id, opts={})
101
+ google_client = new_client(credentials)
102
+ safely do
103
+ google_client.get_object(bucket_id, blob_id) do |chunk|
104
+ yield chunk
105
+ end
106
+ end
107
+ end
108
+
109
+ #--
110
+ # Create Blob
111
+ #--
112
+ def create_blob(credentials, bucket_id, blob_id, blob_data, opts={})
113
+ google_client = new_client(credentials)
114
+ safely do
115
+ dcloud_blob_metadata = BlobHelper::extract_blob_metadata_hash(opts)
116
+ BlobHelper::rename_metadata_headers(opts, 'x-goog-meta-')
117
+ opts['Content-Type'] = blob_data[:type]
118
+ google_client.put_object(bucket_id, blob_id, blob_data[:tempfile], opts)
119
+ Blob.new({ :id => blob_id,
120
+ :bucket => bucket_id,
121
+ :content_length => File.size(blob_data[:tempfile]).to_s,
122
+ :content_type => blob_data[:type],
123
+ :last_modified => "",
124
+ :user_metadata => dcloud_blob_metadata })
125
+ end
126
+ end
127
+
128
+ #params: {:user,:password,:bucket,:blob,:content_type,:content_length,:metadata}
129
+ def blob_stream_connection(params)
130
+ client = Fog::Storage.new({:provider => :google, :google_storage_access_key_id => params[:user],
131
+ :google_storage_secret_access_key => params[:password]})
132
+ google_request_uri = "https://#{client.instance_variable_get(:@host)}"
133
+ uri = URI.parse(google_request_uri)
134
+ conn_params = {} # build hash for the Fog signature method
135
+ conn_params[:headers] = {} #put the metadata here
136
+ conn_params[:host] = uri.host
137
+ conn_params[:path] = "#{params[:bucket]}/#{CGI.escape(params[:blob])}"
138
+ conn_params[:method] = "PUT"
139
+ timestamp = Fog::Time.now.to_date_header
140
+ conn_params[:headers]['Date'] = timestamp
141
+ conn_params[:headers]['Content-Type'] = params[:content_type]
142
+ metadata = params[:metadata] || {}
143
+ BlobHelper::rename_metadata_headers(metadata, 'x-goog-meta-')
144
+ metadata.each{|k,v| conn_params[:headers][k]=v}
145
+ auth_string = "GOOG1 #{params[:user]}:#{client.signature(conn_params)}"
146
+
147
+ http = Net::HTTP.new(uri.host, uri.port)
148
+ http.use_ssl = true
149
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
150
+ request = Net::HTTP::Put.new("/#{conn_params[:path]}")
151
+ request['Host'] = conn_params[:host]
152
+ request['Date'] = conn_params[:headers]['Date']
153
+ request['Content-Type'] = conn_params[:headers]['Content-Type']
154
+ request['Content-Length'] = params[:content_length]
155
+ request['Authorization'] = auth_string
156
+ metadata.each{|k,v| request[k] = v}
157
+ return http, request
158
+ end
159
+
160
+ #--
161
+ # Delete Blob
162
+ #--
163
+ def delete_blob(credentials, bucket_id, blob_id, opts={})
164
+ google_client = new_client(credentials)
165
+ safely do
166
+ google_client.delete_object(bucket_id, blob_id)
167
+ end
168
+ end
169
+
170
+ #-
171
+ # Blob Metadada
172
+ #-
173
+ def blob_metadata(credentials, opts = {})
174
+ google_client = new_client(credentials)
175
+ safely do
176
+ google_blob = google_client.head_object(opts['bucket'], opts[:id]).headers
177
+ meta_hash = google_blob.inject({}){|result, (k,v)| result[k]=v if k=~/^x-goog-meta-/i ; result}
178
+ meta_hash.gsub_keys("x-goog-meta-", "")
179
+ end
180
+ end
181
+
182
+ #-
183
+ # Update Blob Metadata
184
+ #-
185
+ def update_blob_metadata(credentials, opts={})
186
+ google_client = new_client(credentials)
187
+ safely do
188
+ meta_hash = BlobHelper::rename_metadata_headers(opts['meta_hash'], 'x-goog-meta-')
189
+ options = {'x-goog-metadata-directive'=>'REPLACE'}
190
+ options.merge!(meta_hash)
191
+ bucket = opts['bucket']
192
+ blob = opts[:id]
193
+ google_client.copy_object(bucket, blob, bucket, blob, options) #source,source,target,target,options
194
+ meta_hash.gsub_keys("x-goog-meta-", "")
195
+ end
196
+ end
197
+
198
+ def valid_credentials?(credentials)
199
+ begin
200
+ new_client(credentials)
201
+ rescue
202
+ return false
203
+ end
204
+ return true
205
+ end
206
+
207
+ private
208
+
209
+ def new_client(credentials)
210
+ safely do
211
+ Fog::Storage.new({ :provider => :google, :google_storage_access_key_id => credentials.user,
212
+ :google_storage_secret_access_key => credentials.password})
213
+
214
+ end
215
+ end
216
+
217
+ def convert_bucket(bucket)
218
+ blob_list = []
219
+ bucket['Contents'].each do |blob|
220
+ blob_list << blob['Key']
221
+ end
222
+ Bucket.new({ :id => bucket['Name'],
223
+ :name => bucket['Name'],
224
+ :size => blob_list.size,
225
+ :blob_list => blob_list
226
+ })
227
+ end
228
+
229
+ end
230
+
231
+ end
232
+ end
233
+ end