fog-brightbox 0.3.0 → 0.4.0

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/lib/fog/brightbox.rb +1 -0
  4. data/lib/fog/brightbox/config.rb +102 -2
  5. data/lib/fog/brightbox/core.rb +1 -0
  6. data/lib/fog/brightbox/models/compute/api_client.rb +3 -1
  7. data/lib/fog/brightbox/models/storage/directories.rb +45 -0
  8. data/lib/fog/brightbox/models/storage/directory.rb +53 -0
  9. data/lib/fog/brightbox/models/storage/file.rb +166 -0
  10. data/lib/fog/brightbox/models/storage/files.rb +104 -0
  11. data/lib/fog/brightbox/oauth2.rb +140 -136
  12. data/lib/fog/brightbox/requests/storage/copy_object.rb +27 -0
  13. data/lib/fog/brightbox/requests/storage/delete_container.rb +22 -0
  14. data/lib/fog/brightbox/requests/storage/delete_multiple_objects.rb +67 -0
  15. data/lib/fog/brightbox/requests/storage/delete_object.rb +23 -0
  16. data/lib/fog/brightbox/requests/storage/delete_static_large_object.rb +43 -0
  17. data/lib/fog/brightbox/requests/storage/get_container.rb +44 -0
  18. data/lib/fog/brightbox/requests/storage/get_containers.rb +33 -0
  19. data/lib/fog/brightbox/requests/storage/get_object.rb +29 -0
  20. data/lib/fog/brightbox/requests/storage/get_object_http_url.rb +21 -0
  21. data/lib/fog/brightbox/requests/storage/get_object_https_url.rb +85 -0
  22. data/lib/fog/brightbox/requests/storage/head_container.rb +28 -0
  23. data/lib/fog/brightbox/requests/storage/head_containers.rb +25 -0
  24. data/lib/fog/brightbox/requests/storage/head_object.rb +23 -0
  25. data/lib/fog/brightbox/requests/storage/post_set_meta_temp_url_key.rb +37 -0
  26. data/lib/fog/brightbox/requests/storage/put_container.rb +27 -0
  27. data/lib/fog/brightbox/requests/storage/put_dynamic_obj_manifest.rb +43 -0
  28. data/lib/fog/brightbox/requests/storage/put_object.rb +42 -0
  29. data/lib/fog/brightbox/requests/storage/put_object_manifest.rb +16 -0
  30. data/lib/fog/brightbox/requests/storage/put_static_obj_manifest.rb +57 -0
  31. data/lib/fog/brightbox/storage.rb +166 -0
  32. data/lib/fog/brightbox/storage/authentication_request.rb +52 -0
  33. data/lib/fog/brightbox/storage/config.rb +23 -0
  34. data/lib/fog/brightbox/storage/connection.rb +83 -0
  35. data/lib/fog/brightbox/storage/errors.rb +11 -0
  36. data/lib/fog/brightbox/version.rb +1 -1
  37. data/spec/fog/brightbox/config_spec.rb +62 -1
  38. data/spec/fog/brightbox/storage/authentication_request_spec.rb +77 -0
  39. data/spec/fog/brightbox/storage/config_spec.rb +40 -0
  40. data/spec/fog/brightbox/storage/connection_errors_spec.rb +54 -0
  41. data/spec/fog/brightbox/storage/connection_spec.rb +120 -0
  42. data/spec/fog/storage/brightbox_spec.rb +290 -0
  43. metadata +40 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c828f450aae49fe5ef940159c7cdaee50804594
4
- data.tar.gz: 6ab4e5663ebb90199b0e01b8d38cf117479c4d27
3
+ metadata.gz: 885f9a5d7a53d8239ab311b2a6fb621b147bfd82
4
+ data.tar.gz: 9bd4bb8e36fc2ee1ff504dec8f795ccf0f0aa6d8
5
5
  SHA512:
6
- metadata.gz: d7ba85e84d50f9689c9262836196c02629e470613d26cbd403c0319f16cc513bc09d06ca8d7f0e4762cbe2dec4f0dc4212058bb9289e35702c3d27a20e480381
7
- data.tar.gz: 19d9f5dfac3c1825c9bc21749a1baf5ff68c4f0b87a3a210c519dd90837c2e0fcf19a008a6c037ed4ebf106cbbf4d9543873d798abf2a3b29f124a17b1849e9b
6
+ metadata.gz: 0a87b352d2167daedb10f233d6f941c0923b4b0d10d371f5387d283ffd18e4ee7987e3fcfd27350f375331879ee883a4911b85e9f6a32c0b9180567f4e66e614
7
+ data.tar.gz: 8e3758fa7350541363f744096379c0c065ead22f479c911a945ae56d27ed81c0b3676ac3cd3ee8f0d39b27b7c3eceb054ac6103b1feaadf5a1b5b82213547867
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ### 0.4.0 / 2014-08-28
2
+
3
+ Enhancements:
4
+
5
+ * Add Add support for Brightbox Orbit cloud storage service. This adds a
6
+ `storage` service to the Brightbox provider using the standard `fog`
7
+ interfaces.
8
+
1
9
  ### 0.3.0 / 2014-08-12
2
10
 
3
11
  Enhancements:
data/lib/fog/brightbox.rb CHANGED
@@ -1 +1,2 @@
1
1
  require 'fog/brightbox/compute'
2
+ require 'fog/brightbox/storage'
@@ -1,3 +1,5 @@
1
+ require "fog/brightbox/oauth2"
2
+
1
3
  module Fog
2
4
  module Brightbox
3
5
  # The {Fog::Brightbox::Config} class is designed to encapsulate a group of settings for reuse
@@ -49,6 +51,21 @@ module Fog
49
51
  @options = options
50
52
  end
51
53
 
54
+ # @return [OAuth2::CredentialSet]
55
+ def credentials
56
+ @credentials ||= OAuth2::CredentialSet.new(client_id, client_secret, {
57
+ :username => username,
58
+ :password => password,
59
+ :access_token => cached_access_token,
60
+ :refresh_token => cached_refresh_token
61
+ })
62
+ end
63
+
64
+ # @return [Boolean]
65
+ def user_credentials?
66
+ credentials.user_details?
67
+ end
68
+
52
69
  # Can this be used to configure services? Yes, yes it can.
53
70
  #
54
71
  # @return [true]
@@ -71,7 +88,24 @@ module Fog
71
88
  end
72
89
  alias_method :api_url, :compute_url
73
90
 
74
- # @return [String] The configured identifier of the API client or user application.
91
+ def storage_url
92
+ URI.parse(@options[:brightbox_storage_url] || "https://files.gb1.brightbox.com")
93
+ end
94
+
95
+ def storage_management_url
96
+ @storage_management_url ||= if @options.key?(:brightbox_storage_management_url)
97
+ URI.parse(@options[:brightbox_storage_management_url])
98
+ else
99
+ nil
100
+ end
101
+ end
102
+
103
+ # @param [URI] management_url The URI to use for management requests.
104
+ def storage_management_url=(management_url)
105
+ @storage_management_url = management_url
106
+ end
107
+
108
+ # @return [String] The configured identifier of the API client or user application.
75
109
  def client_id
76
110
  @options[:brightbox_client_id]
77
111
  end
@@ -93,7 +127,21 @@ module Fog
93
127
 
94
128
  # @return [String] The configured account identifier to scope API requests by.
95
129
  def account
96
- @options[:brightbox_account]
130
+ @current_account ||= @options[:brightbox_account]
131
+ end
132
+
133
+ # This changes the scoped account from the originally configured one to another.
134
+ #
135
+ # @return [String] The new account identifier used to scope API requests by.
136
+ def change_account(new_account)
137
+ @current_account = new_account
138
+ end
139
+
140
+ # Sets the scoped account back to originally configured one.
141
+ #
142
+ # @return [String] The configured account identifier to scope API requests by.
143
+ def reset_account
144
+ @current_account = @options[:brightbox_account]
97
145
  end
98
146
 
99
147
  def connection_options
@@ -109,10 +157,34 @@ module Fog
109
157
  @options[:brightbox_access_token]
110
158
  end
111
159
 
160
+ def latest_access_token
161
+ credentials.access_token
162
+ end
163
+
112
164
  def cached_refresh_token
113
165
  @options[:brightbox_refresh_token]
114
166
  end
115
167
 
168
+ # This is the current, most up to date refresh token.
169
+ def latest_refresh_token
170
+ credentials.refresh_token
171
+ end
172
+
173
+ def must_authenticate?
174
+ !credentials.access_token?
175
+ end
176
+
177
+ # Allows classes sharing to mark the tokens as invalid in response to API status codes.
178
+ def expire_tokens!
179
+ update_tokens(nil)
180
+ end
181
+
182
+ # @param [String] access_token The new access token to use
183
+ # @param [String] refresh_token The new refresh token to use
184
+ def update_tokens(access_token, refresh_token = nil, expires_in = nil)
185
+ credentials.update_tokens(access_token, refresh_token, expires_in)
186
+ end
187
+
116
188
  def managed_tokens?
117
189
  @options.fetch(:brightbox_token_management, true)
118
190
  end
@@ -120,6 +192,34 @@ module Fog
120
192
  def default_image_id
121
193
  @options.fetch(:brightbox_default_image, nil)
122
194
  end
195
+
196
+ def latest_token
197
+ @options[:brightbox_access_token]
198
+ end
199
+
200
+ def service_type
201
+ @options[:brightbox_service_type] || "object-store"
202
+ end
203
+
204
+ def service_name
205
+ @options[:brightbox_service_name]
206
+ end
207
+
208
+ def region
209
+ @options[:brightbox_region]
210
+ end
211
+
212
+ def tenant
213
+ @options[:brightbox_tenant]
214
+ end
215
+
216
+ def storage_connection_options
217
+ @options[:connection_options] || {}
218
+ end
219
+
220
+ def storage_temp_key
221
+ @options[:brightbox_temp_url_key]
222
+ end
123
223
  end
124
224
  end
125
225
  end
@@ -7,5 +7,6 @@ module Fog
7
7
  extend Fog::Provider
8
8
 
9
9
  service(:compute, 'Compute')
10
+ service(:storage, 'Storage')
10
11
  end
11
12
  end
@@ -9,13 +9,15 @@ module Fog
9
9
  attribute :description
10
10
  attribute :secret
11
11
  attribute :revoked_at, :type => :time
12
+ attribute :permissions_group
12
13
  attribute :account_id
13
14
 
14
15
  def save
15
16
  raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
16
17
  options = {
17
18
  :name => name,
18
- :description => description
19
+ :description => description,
20
+ :permissions_group => permissions_group
19
21
  }.delete_if { |k, v| v.nil? || v == "" }
20
22
  data = service.create_api_client(options)
21
23
  merge_attributes(data)
@@ -0,0 +1,45 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/brightbox/models/storage/directory'
3
+
4
+ module Fog
5
+ module Storage
6
+ class Brightbox
7
+
8
+ class Directories < Fog::Collection
9
+
10
+ model Fog::Storage::Brightbox::Directory
11
+
12
+ HEADER_ATTRIBUTES = [
13
+ 'X-Container-Bytes-Used', 'X-Container-Object-Count', 'X-Container-Read',
14
+ 'X-Container-Write'
15
+ ]
16
+
17
+ def all
18
+ data = service.get_containers.body
19
+ load(data)
20
+ end
21
+
22
+ def get(key, options = {})
23
+ data = service.get_container(key, options)
24
+ directory = new(:key => key)
25
+ for key, value in data.headers
26
+ if HEADER_ATTRIBUTES.include?(key)
27
+ directory.merge_attributes(key => value)
28
+ end
29
+ end
30
+ directory.files.merge_attributes(options)
31
+ directory.files.instance_variable_set(:@loaded, true)
32
+
33
+ data.body.each do |file|
34
+ directory.files << directory.files.new(file)
35
+ end
36
+ directory
37
+ rescue Fog::Storage::Brightbox::NotFound
38
+ nil
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,53 @@
1
+ require "fog/core/model"
2
+ require "fog/brightbox/models/storage/files"
3
+
4
+ module Fog
5
+ module Storage
6
+ class Brightbox
7
+ class Directory < Fog::Model
8
+ identity :key, :aliases => "name"
9
+
10
+ attribute :bytes, :aliases => "X-Container-Bytes-Used"
11
+ attribute :count, :aliases => "X-Container-Object-Count"
12
+ attribute :read_permissions, :aliases => "X-Container-Read"
13
+ attribute :write_permissions, :aliases => "X-Container-Write"
14
+
15
+ def destroy
16
+ requires :key
17
+ service.delete_container(key)
18
+ true
19
+ rescue Excon::Errors::NotFound
20
+ false
21
+ end
22
+
23
+ def files
24
+ @files ||= begin
25
+ Fog::Storage::Brightbox::Files.new(
26
+ :directory => self,
27
+ :service => service
28
+ )
29
+ end
30
+ end
31
+
32
+ def public=(new_public)
33
+ @public = new_public
34
+ end
35
+
36
+ def public_url
37
+ #raise NotImplementedError
38
+ ""
39
+ end
40
+
41
+ def save
42
+ requires :key
43
+ options = {
44
+ 'read_permissions' => read_permissions,
45
+ 'write_permissions' => write_permissions
46
+ }
47
+ service.put_container(key, options)
48
+ true
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,166 @@
1
+ require 'fog/core/model'
2
+
3
+ module Fog
4
+ module Storage
5
+ class Brightbox
6
+
7
+ class File < Fog::Model
8
+
9
+ identity :key, :aliases => 'name'
10
+
11
+ attribute :content_length, :aliases => ['bytes', 'Content-Length'], :type => :integer
12
+ attribute :content_type, :aliases => ['content_type', 'Content-Type']
13
+ attribute :content_disposition, :aliases => ['content_disposition', 'Content-Disposition']
14
+ attribute :etag, :aliases => ['hash', 'Etag']
15
+ attribute :last_modified, :aliases => ['last_modified', 'Last-Modified'], :type => :time
16
+ attribute :access_control_allow_origin, :aliases => ['Access-Control-Allow-Origin']
17
+ attribute :origin, :aliases => ['Origin']
18
+
19
+ def body
20
+ attributes[:body] ||= if last_modified
21
+ collection.get(identity).body
22
+ else
23
+ ''
24
+ end
25
+ end
26
+
27
+ def body=(new_body)
28
+ attributes[:body] = new_body
29
+ end
30
+
31
+ def directory
32
+ @directory
33
+ end
34
+
35
+ def copy(target_directory_key, target_file_key, options={})
36
+ requires :directory, :key
37
+ options['Content-Type'] ||= content_type if content_type
38
+ options['Access-Control-Allow-Origin'] ||= access_control_allow_origin if access_control_allow_origin
39
+ options['Origin'] ||= origin if origin
40
+ service.copy_object(directory.key, key, target_directory_key, target_file_key, options)
41
+ target_directory = service.directories.new(:key => target_directory_key)
42
+ target_directory.files.get(target_file_key)
43
+ end
44
+
45
+ def destroy
46
+ requires :directory, :key
47
+ service.delete_object(directory.key, key)
48
+ true
49
+ end
50
+
51
+ def metadata
52
+ @metadata ||= headers_to_metadata
53
+ end
54
+
55
+ def owner=(new_owner)
56
+ if new_owner
57
+ attributes[:owner] = {
58
+ :display_name => new_owner['DisplayName'],
59
+ :id => new_owner['ID']
60
+ }
61
+ end
62
+ end
63
+
64
+ def public=(new_public)
65
+ new_public
66
+ end
67
+
68
+ # Get a url for file.
69
+ #
70
+ # required attributes: key
71
+ #
72
+ # @param expires [String] number of seconds (since 1970-01-01 00:00) before url expires
73
+ # @param options [Hash]
74
+ # @return [String] url
75
+ #
76
+ def url(expires, options = {})
77
+ requires :directory, :key
78
+ self.service.create_temp_url(directory.key, key, expires, "GET", options)
79
+ end
80
+
81
+ def public_url
82
+ requires :key
83
+ self.collection.get_url(self.key)
84
+ end
85
+
86
+
87
+ def save(options = {})
88
+ requires :body, :directory, :key
89
+ options['Content-Type'] = content_type if content_type
90
+ options['Content-Disposition'] = content_disposition if content_disposition
91
+ options['Access-Control-Allow-Origin'] = access_control_allow_origin if access_control_allow_origin
92
+ options['Origin'] = origin if origin
93
+ options.merge!(metadata_to_headers)
94
+
95
+ data = service.put_object(directory.key, key, body, options)
96
+ update_attributes_from(data)
97
+ refresh_metadata
98
+
99
+ self.content_length = Fog::Storage.get_body_size(body)
100
+ self.content_type ||= Fog::Storage.get_content_type(body)
101
+ true
102
+ end
103
+
104
+ private
105
+
106
+ def directory=(new_directory)
107
+ @directory = new_directory
108
+ end
109
+
110
+ def refresh_metadata
111
+ metadata.reject! {|k, v| v.nil? }
112
+ end
113
+
114
+ def headers_to_metadata
115
+ key_map = key_mapping
116
+ Hash[metadata_attributes.map {|k, v| [key_map[k], v] }]
117
+ end
118
+
119
+ def key_mapping
120
+ key_map = metadata_attributes
121
+ key_map.each_pair {|k, v| key_map[k] = header_to_key(k)}
122
+ end
123
+
124
+ def header_to_key(opt)
125
+ opt.gsub(metadata_prefix, '').split('-').map {|k| k[0, 1].downcase + k[1..-1]}.join('_').to_sym
126
+ end
127
+
128
+ def metadata_to_headers
129
+ header_map = header_mapping
130
+ Hash[metadata.map {|k, v| [header_map[k], v] }]
131
+ end
132
+
133
+ def header_mapping
134
+ header_map = metadata.dup
135
+ header_map.each_pair {|k, v| header_map[k] = key_to_header(k)}
136
+ end
137
+
138
+ def key_to_header(key)
139
+ metadata_prefix + key.to_s.split(/[-_]/).map(&:capitalize).join('-')
140
+ end
141
+
142
+ def metadata_attributes
143
+ if last_modified
144
+ headers = service.head_object(directory.key, self.key).headers
145
+ headers.reject! {|k, v| !metadata_attribute?(k)}
146
+ else
147
+ {}
148
+ end
149
+ end
150
+
151
+ def metadata_attribute?(key)
152
+ key.to_s =~ /^#{metadata_prefix}/
153
+ end
154
+
155
+ def metadata_prefix
156
+ "X-Object-Meta-"
157
+ end
158
+
159
+ def update_attributes_from(data)
160
+ merge_attributes(data.headers.reject {|key, value| ['Content-Length', 'Content-Type'].include?(key)})
161
+ end
162
+ end
163
+
164
+ end
165
+ end
166
+ end