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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/fog/brightbox.rb +1 -0
- data/lib/fog/brightbox/config.rb +102 -2
- data/lib/fog/brightbox/core.rb +1 -0
- data/lib/fog/brightbox/models/compute/api_client.rb +3 -1
- data/lib/fog/brightbox/models/storage/directories.rb +45 -0
- data/lib/fog/brightbox/models/storage/directory.rb +53 -0
- data/lib/fog/brightbox/models/storage/file.rb +166 -0
- data/lib/fog/brightbox/models/storage/files.rb +104 -0
- data/lib/fog/brightbox/oauth2.rb +140 -136
- data/lib/fog/brightbox/requests/storage/copy_object.rb +27 -0
- data/lib/fog/brightbox/requests/storage/delete_container.rb +22 -0
- data/lib/fog/brightbox/requests/storage/delete_multiple_objects.rb +67 -0
- data/lib/fog/brightbox/requests/storage/delete_object.rb +23 -0
- data/lib/fog/brightbox/requests/storage/delete_static_large_object.rb +43 -0
- data/lib/fog/brightbox/requests/storage/get_container.rb +44 -0
- data/lib/fog/brightbox/requests/storage/get_containers.rb +33 -0
- data/lib/fog/brightbox/requests/storage/get_object.rb +29 -0
- data/lib/fog/brightbox/requests/storage/get_object_http_url.rb +21 -0
- data/lib/fog/brightbox/requests/storage/get_object_https_url.rb +85 -0
- data/lib/fog/brightbox/requests/storage/head_container.rb +28 -0
- data/lib/fog/brightbox/requests/storage/head_containers.rb +25 -0
- data/lib/fog/brightbox/requests/storage/head_object.rb +23 -0
- data/lib/fog/brightbox/requests/storage/post_set_meta_temp_url_key.rb +37 -0
- data/lib/fog/brightbox/requests/storage/put_container.rb +27 -0
- data/lib/fog/brightbox/requests/storage/put_dynamic_obj_manifest.rb +43 -0
- data/lib/fog/brightbox/requests/storage/put_object.rb +42 -0
- data/lib/fog/brightbox/requests/storage/put_object_manifest.rb +16 -0
- data/lib/fog/brightbox/requests/storage/put_static_obj_manifest.rb +57 -0
- data/lib/fog/brightbox/storage.rb +166 -0
- data/lib/fog/brightbox/storage/authentication_request.rb +52 -0
- data/lib/fog/brightbox/storage/config.rb +23 -0
- data/lib/fog/brightbox/storage/connection.rb +83 -0
- data/lib/fog/brightbox/storage/errors.rb +11 -0
- data/lib/fog/brightbox/version.rb +1 -1
- data/spec/fog/brightbox/config_spec.rb +62 -1
- data/spec/fog/brightbox/storage/authentication_request_spec.rb +77 -0
- data/spec/fog/brightbox/storage/config_spec.rb +40 -0
- data/spec/fog/brightbox/storage/connection_errors_spec.rb +54 -0
- data/spec/fog/brightbox/storage/connection_spec.rb +120 -0
- data/spec/fog/storage/brightbox_spec.rb +290 -0
- metadata +40 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 885f9a5d7a53d8239ab311b2a6fb621b147bfd82
|
4
|
+
data.tar.gz: 9bd4bb8e36fc2ee1ff504dec8f795ccf0f0aa6d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a87b352d2167daedb10f233d6f941c0923b4b0d10d371f5387d283ffd18e4ee7987e3fcfd27350f375331879ee883a4911b85e9f6a32c0b9180567f4e66e614
|
7
|
+
data.tar.gz: 8e3758fa7350541363f744096379c0c065ead22f479c911a945ae56d27ed81c0b3676ac3cd3ee8f0d39b27b7c3eceb054ac6103b1feaadf5a1b5b82213547867
|
data/CHANGELOG.md
CHANGED
data/lib/fog/brightbox.rb
CHANGED
data/lib/fog/brightbox/config.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/fog/brightbox/core.rb
CHANGED
@@ -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
|