fog-brightbox 1.4.2 → 1.6.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 +31 -0
- data/lib/fog/brightbox/compute/shared.rb +26 -10
- data/lib/fog/brightbox/compute.rb +17 -0
- data/lib/fog/brightbox/config.rb +12 -0
- data/lib/fog/brightbox/models/compute/server.rb +9 -1
- data/lib/fog/brightbox/models/compute/volume.rb +152 -0
- data/lib/fog/brightbox/models/compute/volumes.rb +23 -0
- data/lib/fog/brightbox/oauth2.rb +47 -7
- data/lib/fog/brightbox/requests/compute/attach_volume.rb +23 -0
- data/lib/fog/brightbox/requests/compute/copy_volume.rb +25 -0
- data/lib/fog/brightbox/requests/compute/create_volume.rb +25 -0
- data/lib/fog/brightbox/requests/compute/delete_volume.rb +20 -0
- data/lib/fog/brightbox/requests/compute/detach_volume.rb +21 -0
- data/lib/fog/brightbox/requests/compute/get_volume.rb +20 -0
- data/lib/fog/brightbox/requests/compute/list_volumes.rb +18 -0
- data/lib/fog/brightbox/requests/compute/lock_resource_volume.rb +18 -0
- data/lib/fog/brightbox/requests/compute/resize_volume.rb +26 -0
- data/lib/fog/brightbox/requests/compute/unlock_resource_volume.rb +18 -0
- data/lib/fog/brightbox/requests/compute/update_volume.rb +26 -0
- data/lib/fog/brightbox/version.rb +1 -1
- data/spec/fog/brightbox/compute/credentials_spec.rb +41 -0
- data/spec/fog/brightbox/compute/get_access_token_spec.rb +305 -0
- data/spec/fog/brightbox/compute/two_factor_spec.rb +53 -0
- data/spec/fog/brightbox/oauth2/user_credentials_strategy_spec.rb +20 -0
- data/spec/fog/compute/brightbox/volume_spec.rb +348 -0
- data/tests/brightbox/compute/schema.rb +74 -0
- data/tests/brightbox/requests/compute/volume_tests.rb +57 -0
- metadata +23 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ed1e1f608af748e905cfeafeb9f1a72674074f11720c854988e324de9e1fa84
|
4
|
+
data.tar.gz: c078791baaf84d13fb09c1f0d8ff17b9c1116f247cfb8c73647b529b97ce3bea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fbfd902483fc3bb101255c4915d8fec6e54c5edf2995f6aa1b0eebe510e210a0b6173b109aa19811fee8fabc1c5f05c294d36b49fbcc9b15056bedf22e1ebac2
|
7
|
+
data.tar.gz: e3b208fa57e74eca736fa8d53683cbfa78645a6aa75a15b680f59365bbd26538cbb373828f92ba4d6de7a79a867e2377500179c9ef18171c35748dd3fa759e17
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
### 1.6.0 / 2022-07-25
|
2
|
+
|
3
|
+
Changes:
|
4
|
+
|
5
|
+
* Added support to opt-in to support Brightbox 2FA within clients.
|
6
|
+
|
7
|
+
Two Factor Authentication (2FA) support:
|
8
|
+
|
9
|
+
Passing `brightbox_support_two_factor` into a configuration will raise a new
|
10
|
+
error when user authentication has failed BUT the presence of the
|
11
|
+
`X-Brightbox-OTP: required` HTTP header is found.
|
12
|
+
|
13
|
+
This new error `Fog::Brightbox::OAuth2::TwoFactorMissingError` can be handled
|
14
|
+
differently by the client and the second factor can be prompted for or
|
15
|
+
recovered from a secure keychain.
|
16
|
+
|
17
|
+
Without opting in, the previous error `Excon::Errors::Unauthorized` is raised.
|
18
|
+
|
19
|
+
To send the OTP, the `brightbox_one_time_password` can be passed into a
|
20
|
+
configuration object or one_time_password can be passed to a credentials
|
21
|
+
object.
|
22
|
+
|
23
|
+
### 1.5.0 / 2022-06-09
|
24
|
+
|
25
|
+
Changes:
|
26
|
+
|
27
|
+
* Added support for `Volume` resources. These are dynamic, network attached
|
28
|
+
volumes. Servers with `nbs` (Network Block Storage) types can be created
|
29
|
+
from volumes. Additional volumes can be attached to a server. The volumes
|
30
|
+
can be quickly copied and resized.
|
31
|
+
|
1
32
|
### 1.4.2 / 2022-06-09
|
2
33
|
|
3
34
|
Bug fixes:
|
@@ -39,21 +39,15 @@ module Fog
|
|
39
39
|
@persistent = @config.connection_persistent?
|
40
40
|
@connection = Fog::Core::Connection.new(@api_url, @persistent, @connection_options)
|
41
41
|
|
42
|
-
# Authentication options
|
43
|
-
client_id = @config.client_id
|
44
|
-
client_secret = @config.client_secret
|
45
|
-
|
46
|
-
username = @config.username
|
47
|
-
password = @config.password
|
48
42
|
@configured_account = @config.account
|
49
43
|
# Request account can be changed at anytime and changes behaviour of future requests
|
50
44
|
@scoped_account = @configured_account
|
51
45
|
|
52
|
-
|
53
|
-
@
|
46
|
+
@two_factor = @config.two_factor?
|
47
|
+
@one_time_password = @config.one_time_password
|
54
48
|
|
55
49
|
# If existing tokens have been cached, allow continued use of them in the service
|
56
|
-
|
50
|
+
credentials.update_tokens(@config.cached_access_token, @config.cached_refresh_token)
|
57
51
|
|
58
52
|
@token_management = @config.managed_tokens?
|
59
53
|
end
|
@@ -73,6 +67,12 @@ module Fog
|
|
73
67
|
@scoped_account = @configured_account
|
74
68
|
end
|
75
69
|
|
70
|
+
def credentials
|
71
|
+
client_id = @config.client_id
|
72
|
+
client_secret = @config.client_secret
|
73
|
+
@credentials ||= CredentialSet.new(client_id, client_secret, credential_options)
|
74
|
+
end
|
75
|
+
|
76
76
|
# Returns the scoped account being used for requests
|
77
77
|
#
|
78
78
|
# * For API clients this is the owning account
|
@@ -122,7 +122,7 @@ module Fog
|
|
122
122
|
def get_access_token
|
123
123
|
begin
|
124
124
|
get_access_token!
|
125
|
-
rescue Excon::Errors::Unauthorized, Excon::Errors::BadRequest
|
125
|
+
rescue Fog::Brightbox::OAuth2::TwoFactorMissingError, Excon::Errors::Unauthorized, Excon::Errors::BadRequest
|
126
126
|
@credentials.update_tokens(nil, nil)
|
127
127
|
end
|
128
128
|
@credentials.access_token
|
@@ -154,8 +154,24 @@ module Fog
|
|
154
154
|
@default_image_id ||= (@config.default_image_id || select_default_image)
|
155
155
|
end
|
156
156
|
|
157
|
+
def two_factor?
|
158
|
+
@two_factor || false
|
159
|
+
end
|
160
|
+
|
157
161
|
private
|
158
162
|
|
163
|
+
# This returns a formatted set of options for the credentials for this service
|
164
|
+
#
|
165
|
+
# @return [Hash]
|
166
|
+
def credential_options
|
167
|
+
{
|
168
|
+
username: @config.username,
|
169
|
+
password: @config.password
|
170
|
+
}.tap do |opts|
|
171
|
+
opts[:one_time_password] = @one_time_password if two_factor?
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
159
175
|
# This makes a request of the API based on the configured setting for
|
160
176
|
# token management.
|
161
177
|
#
|
@@ -21,6 +21,10 @@ module Fog
|
|
21
21
|
# Automatic token management
|
22
22
|
recognizes :brightbox_token_management
|
23
23
|
|
24
|
+
# Two Factor Authentication support (2FA)
|
25
|
+
recognizes :brightbox_support_two_factor
|
26
|
+
recognizes :brightbox_one_time_password
|
27
|
+
|
24
28
|
# Excon connection settings
|
25
29
|
recognizes :persistent
|
26
30
|
|
@@ -63,6 +67,8 @@ module Fog
|
|
63
67
|
model :user
|
64
68
|
collection :user_collaborations
|
65
69
|
model :user_collaboration
|
70
|
+
collection :volumes
|
71
|
+
model :volume
|
66
72
|
|
67
73
|
request_path "fog/brightbox/requests/compute"
|
68
74
|
request :accept_user_collaboration
|
@@ -72,7 +78,9 @@ module Fog
|
|
72
78
|
request :add_servers_server_group
|
73
79
|
request :apply_to_firewall_policy
|
74
80
|
request :accept_user_collaboration
|
81
|
+
request :attach_volume
|
75
82
|
request :remove_firewall_policy
|
83
|
+
request :copy_volume
|
76
84
|
request :create_api_client
|
77
85
|
request :create_application
|
78
86
|
request :create_cloud_ip
|
@@ -84,6 +92,7 @@ module Fog
|
|
84
92
|
request :create_database_server
|
85
93
|
request :create_server
|
86
94
|
request :create_server_group
|
95
|
+
request :create_volume
|
87
96
|
request :delete_api_client
|
88
97
|
request :delete_application
|
89
98
|
request :delete_cloud_ip
|
@@ -97,6 +106,8 @@ module Fog
|
|
97
106
|
request :delete_server
|
98
107
|
request :delete_server_group
|
99
108
|
request :delete_user_collaboration
|
109
|
+
request :delete_volume
|
110
|
+
request :detach_volume
|
100
111
|
request :get_account
|
101
112
|
request :get_api_client
|
102
113
|
request :get_application
|
@@ -117,6 +128,7 @@ module Fog
|
|
117
128
|
request :get_server_type
|
118
129
|
request :get_user
|
119
130
|
request :get_user_collaboration
|
131
|
+
request :get_volume
|
120
132
|
request :get_zone
|
121
133
|
request :list_accounts
|
122
134
|
request :list_api_clients
|
@@ -135,12 +147,14 @@ module Fog
|
|
135
147
|
request :list_servers
|
136
148
|
request :list_users
|
137
149
|
request :list_user_collaborations
|
150
|
+
request :list_volumes
|
138
151
|
request :list_zones
|
139
152
|
request :lock_resource_database_server
|
140
153
|
request :lock_resource_database_snapshot
|
141
154
|
request :lock_resource_image
|
142
155
|
request :lock_resource_load_balancer
|
143
156
|
request :lock_resource_server
|
157
|
+
request :lock_resource_volume
|
144
158
|
request :map_cloud_ip
|
145
159
|
request :move_servers_server_group
|
146
160
|
request :reboot_server
|
@@ -156,6 +170,7 @@ module Fog
|
|
156
170
|
request :reset_secret_application
|
157
171
|
request :reset_server
|
158
172
|
request :resend_collaboration
|
173
|
+
request :resize_volume
|
159
174
|
request :reject_user_collaboration
|
160
175
|
request :shutdown_server
|
161
176
|
request :snapshot_database_server
|
@@ -167,6 +182,7 @@ module Fog
|
|
167
182
|
request :unlock_resource_image
|
168
183
|
request :unlock_resource_load_balancer
|
169
184
|
request :unlock_resource_server
|
185
|
+
request :unlock_resource_volume
|
170
186
|
request :unmap_cloud_ip
|
171
187
|
request :update_account
|
172
188
|
request :update_api_client
|
@@ -182,6 +198,7 @@ module Fog
|
|
182
198
|
request :update_server
|
183
199
|
request :update_server_group
|
184
200
|
request :update_user
|
201
|
+
request :update_volume
|
185
202
|
|
186
203
|
# The Mock Service allows you to run a fake instance of the Service
|
187
204
|
# which makes no real connections.
|
data/lib/fog/brightbox/config.rb
CHANGED
@@ -33,6 +33,10 @@ module Fog
|
|
33
33
|
# Set to specify the client secret to use for requests.
|
34
34
|
# @option options [String] :brightbox_token_management (true)
|
35
35
|
# Set to specify if the service should handle expired tokens or raise an error instead.
|
36
|
+
# @option options [Boolean] :brightbox_support_two_factor
|
37
|
+
# Set to enable two factor authentication (2FA) for this configuration/user
|
38
|
+
# @option options [String] :brightbox_one_time_password
|
39
|
+
# Set to pass through the current one time password when using 2FA
|
36
40
|
# @option options [String] :brightbox_username
|
37
41
|
# Set to specify your user account. Either user identifier (+usr-12345+) or email address
|
38
42
|
# may be used.
|
@@ -226,6 +230,14 @@ module Fog
|
|
226
230
|
def storage_temp_key
|
227
231
|
@options[:brightbox_temp_url_key]
|
228
232
|
end
|
233
|
+
|
234
|
+
def two_factor?
|
235
|
+
@options[:brightbox_support_two_factor] || false
|
236
|
+
end
|
237
|
+
|
238
|
+
def one_time_password
|
239
|
+
@options[:brightbox_one_time_password]
|
240
|
+
end
|
229
241
|
end
|
230
242
|
end
|
231
243
|
end
|
@@ -7,6 +7,8 @@ module Fog
|
|
7
7
|
include Fog::Brightbox::ModelHelper
|
8
8
|
include Fog::Brightbox::Compute::ResourceLocking
|
9
9
|
|
10
|
+
attr_accessor :volume_id
|
11
|
+
|
10
12
|
identity :id
|
11
13
|
attribute :resource_type
|
12
14
|
attribute :url
|
@@ -38,6 +40,7 @@ module Fog
|
|
38
40
|
attribute :cloud_ips
|
39
41
|
attribute :interfaces
|
40
42
|
attribute :server_groups
|
43
|
+
attribute :volumes
|
41
44
|
attribute :zone
|
42
45
|
attribute :server_type
|
43
46
|
|
@@ -181,7 +184,6 @@ module Fog
|
|
181
184
|
raise Fog::Errors::Error.new("Resaving an existing object may create a duplicate") if persisted?
|
182
185
|
requires :image_id
|
183
186
|
options = {
|
184
|
-
:image => image_id,
|
185
187
|
:name => name,
|
186
188
|
:zone => zone_id,
|
187
189
|
:user_data => user_data,
|
@@ -192,6 +194,12 @@ module Fog
|
|
192
194
|
options.merge!(:cloud_ip => cloud_ip) unless cloud_ip.nil? || cloud_ip == ""
|
193
195
|
options.merge!(:disk_encrypted => disk_encrypted) if disk_encrypted
|
194
196
|
|
197
|
+
if volume_id
|
198
|
+
options.merge!(:volumes => [:volume => volume_id])
|
199
|
+
else
|
200
|
+
options.merge!(:image => image_id)
|
201
|
+
end
|
202
|
+
|
195
203
|
data = service.create_server(options)
|
196
204
|
merge_attributes(data)
|
197
205
|
true
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Volume < Fog::Brightbox::Model
|
5
|
+
include Fog::Brightbox::Compute::ResourceLocking
|
6
|
+
|
7
|
+
identity :id
|
8
|
+
attribute :url
|
9
|
+
attribute :resource_type
|
10
|
+
|
11
|
+
attribute :name
|
12
|
+
attribute :state, :aliases => "status"
|
13
|
+
|
14
|
+
attribute :description
|
15
|
+
attribute :filesystem_label
|
16
|
+
attribute :filesystem_type
|
17
|
+
attribute :serial
|
18
|
+
attribute :size
|
19
|
+
attribute :source
|
20
|
+
attribute :source_type
|
21
|
+
attribute :storage_type
|
22
|
+
|
23
|
+
attribute :boot
|
24
|
+
attribute :delete_with_server
|
25
|
+
attribute :encrypted
|
26
|
+
|
27
|
+
# Times
|
28
|
+
attribute :created_at, :type => :time
|
29
|
+
attribute :updated_at, :type => :time
|
30
|
+
attribute :deleted_at, :type => :time
|
31
|
+
|
32
|
+
# Links
|
33
|
+
attribute :account_id, :aliases => "account", :squash => "id"
|
34
|
+
attribute :image_id, :aliases => "image", :squash => "id"
|
35
|
+
attribute :server_id, :aliases => "server", :squash => "id"
|
36
|
+
|
37
|
+
def attach(server)
|
38
|
+
requires :identity
|
39
|
+
data = service.attach_volume(identity, server: server.id)
|
40
|
+
merge_attributes(data)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def attached?
|
45
|
+
state == "attached"
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [Hash] options
|
49
|
+
# @option options [Boolean] :delete_with_server Set +true+ the volume will be removed if attached to a server that is deleted
|
50
|
+
# @option options [String] :description
|
51
|
+
# @option options [String] :name
|
52
|
+
# @option options [String] :serial
|
53
|
+
#
|
54
|
+
# @return [Fog::Compute::Volume] a new model for the copy
|
55
|
+
def copy(options = {})
|
56
|
+
requires :identity
|
57
|
+
data = service.copy_volume(identity, options)
|
58
|
+
service.volumes.new(data)
|
59
|
+
end
|
60
|
+
|
61
|
+
def creating?
|
62
|
+
state == "creating"
|
63
|
+
end
|
64
|
+
|
65
|
+
def deleted?
|
66
|
+
state == "deleted"
|
67
|
+
end
|
68
|
+
|
69
|
+
def deleting?
|
70
|
+
state == "deleting"
|
71
|
+
end
|
72
|
+
|
73
|
+
def detach
|
74
|
+
requires :identity
|
75
|
+
data = service.detach_volume(identity)
|
76
|
+
merge_attributes(data)
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def detached?
|
81
|
+
state == "detached"
|
82
|
+
end
|
83
|
+
|
84
|
+
def failed?
|
85
|
+
state == "failed"
|
86
|
+
end
|
87
|
+
|
88
|
+
def finished?
|
89
|
+
deleted? || failed?
|
90
|
+
end
|
91
|
+
|
92
|
+
def ready?
|
93
|
+
attached? || detached?
|
94
|
+
end
|
95
|
+
|
96
|
+
# @param [Hash] options
|
97
|
+
# @option options [Integer] :to The new size in MiB to change the volume to
|
98
|
+
def resize(options)
|
99
|
+
requires :identity
|
100
|
+
|
101
|
+
# The API requires the old "from" size to avoid acting on stale data
|
102
|
+
# We can merge this and if the API rejects the request, the model was out of sync
|
103
|
+
options.merge!(:from => size)
|
104
|
+
|
105
|
+
data = service.resize_volume(identity, options)
|
106
|
+
merge_attributes(data)
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def save
|
111
|
+
if persisted?
|
112
|
+
options = {
|
113
|
+
:delete_with_server => delete_with_server,
|
114
|
+
:description => description,
|
115
|
+
:name => name,
|
116
|
+
:serial => serial
|
117
|
+
}.delete_if { |_k, v| v.nil? || v == "" }
|
118
|
+
|
119
|
+
data = service.update_volume(identity, options)
|
120
|
+
else
|
121
|
+
raise Fog::Errors::Error.new("'image_id' and 'filesystem_type' are mutually exclusive") if image_id && filesystem_type
|
122
|
+
raise Fog::Errors::Error.new("'image_id' or 'filesystem_type' is required") unless image_id || filesystem_type
|
123
|
+
|
124
|
+
options = {
|
125
|
+
:delete_with_server => delete_with_server,
|
126
|
+
:description => description,
|
127
|
+
:filesystem_label => filesystem_label,
|
128
|
+
:filesystem_type => filesystem_type,
|
129
|
+
:name => name,
|
130
|
+
:serial => serial,
|
131
|
+
:size => size
|
132
|
+
}.delete_if { |_k, v| v.nil? || v == "" }
|
133
|
+
|
134
|
+
options.merge!(:image => image_id) unless image_id.nil? || image_id == ""
|
135
|
+
|
136
|
+
data = service.create_volume(options)
|
137
|
+
end
|
138
|
+
|
139
|
+
merge_attributes(data)
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
def destroy
|
144
|
+
requires :identity
|
145
|
+
data = service.delete_volume(identity)
|
146
|
+
merge_attributes(data)
|
147
|
+
true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "fog/brightbox/models/compute/volume"
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Brightbox
|
5
|
+
class Compute
|
6
|
+
class Volumes < Fog::Collection
|
7
|
+
model Fog::Brightbox::Compute::Volume
|
8
|
+
|
9
|
+
def all
|
10
|
+
data = service.list_volumes
|
11
|
+
load(data)
|
12
|
+
end
|
13
|
+
|
14
|
+
def get(identifier)
|
15
|
+
data = service.get_volume(identifier)
|
16
|
+
new(data)
|
17
|
+
rescue Excon::Errors::NotFound
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/fog/brightbox/oauth2.rb
CHANGED
@@ -6,6 +6,10 @@ module Fog
|
|
6
6
|
# @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10
|
7
7
|
#
|
8
8
|
module OAuth2
|
9
|
+
TWO_FACTOR_HEADER = "X-Brightbox-OTP".freeze
|
10
|
+
|
11
|
+
class TwoFactorMissingError < StandardError; end
|
12
|
+
|
9
13
|
# This builds the simplest form of requesting an access token
|
10
14
|
# based on the arguments passed in
|
11
15
|
#
|
@@ -13,16 +17,38 @@ module Fog
|
|
13
17
|
# @param [CredentialSet] credentials
|
14
18
|
#
|
15
19
|
# @return [Excon::Response]
|
20
|
+
# @raise [Excon::Errors::Unauthorized] if the credentials are rejected by the server
|
21
|
+
# @raise [Fog::Brightbox::OAuth2::TwoFactorMissingError] if opted in to 2FA and server reports header is required
|
16
22
|
def request_access_token(connection, credentials)
|
17
23
|
token_strategy = credentials.best_grant_strategy
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
if two_factor?
|
26
|
+
# When 2FA opt-in is set, we can expect 401 responses as well
|
27
|
+
response = connection.request(
|
28
|
+
:path => "/token",
|
29
|
+
:expects => [200, 401],
|
30
|
+
:headers => token_strategy.headers,
|
31
|
+
:method => "POST",
|
32
|
+
:body => Fog::JSON.encode(token_strategy.authorization_body_data)
|
33
|
+
)
|
34
|
+
|
35
|
+
if response.status == 401 && response.headers[Fog::Brightbox::OAuth2::TWO_FACTOR_HEADER] == "required"
|
36
|
+
raise TwoFactorMissingError
|
37
|
+
elsif response.status == 401
|
38
|
+
raise Excon::Errors.status_error({ expects: 200 }, status: 401)
|
39
|
+
else
|
40
|
+
response
|
41
|
+
end
|
42
|
+
else
|
43
|
+
# Use classic behaviour and return Excon::
|
44
|
+
connection.request(
|
45
|
+
:path => "/token",
|
46
|
+
:expects => 200,
|
47
|
+
:headers => token_strategy.headers,
|
48
|
+
:method => "POST",
|
49
|
+
:body => Fog::JSON.encode(token_strategy.authorization_body_data)
|
50
|
+
)
|
51
|
+
end
|
26
52
|
end
|
27
53
|
|
28
54
|
# Encapsulates credentials required to request access tokens from the
|
@@ -33,12 +59,14 @@ module Fog
|
|
33
59
|
class CredentialSet
|
34
60
|
attr_reader :client_id, :client_secret, :username, :password
|
35
61
|
attr_reader :access_token, :refresh_token, :expires_in
|
62
|
+
attr_reader :one_time_password
|
36
63
|
#
|
37
64
|
# @param [String] client_id
|
38
65
|
# @param [String] client_secret
|
39
66
|
# @param [Hash] options
|
40
67
|
# @option options [String] :username
|
41
68
|
# @option options [String] :password
|
69
|
+
# @option options [String] :one_time_password One Time Password for Two Factor authentication
|
42
70
|
#
|
43
71
|
def initialize(client_id, client_secret, options = {})
|
44
72
|
@client_id = client_id
|
@@ -48,6 +76,7 @@ module Fog
|
|
48
76
|
@access_token = options[:access_token]
|
49
77
|
@refresh_token = options[:refresh_token]
|
50
78
|
@expires_in = options[:expires_in]
|
79
|
+
@one_time_password = options[:one_time_password]
|
51
80
|
end
|
52
81
|
|
53
82
|
# Returns true if user details are available
|
@@ -142,6 +171,17 @@ module Fog
|
|
142
171
|
"password" => @credentials.password
|
143
172
|
}
|
144
173
|
end
|
174
|
+
|
175
|
+
def headers
|
176
|
+
{
|
177
|
+
"Authorization" => authorization_header,
|
178
|
+
"Content-Type" => "application/json"
|
179
|
+
}.tap do |headers|
|
180
|
+
if @credentials.one_time_password
|
181
|
+
headers[TWO_FACTOR_HEADER] = @credentials.one_time_password
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
145
185
|
end
|
146
186
|
|
147
187
|
# This strategy attempts to use a refresh_token gained during an earlier
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Attach a detached server to a nominated server
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
# @option options [String] :server The identifier of the server
|
11
|
+
# @option options [Boolean] :boot Set +true+ to attach as boot volume. Only when server is stopped
|
12
|
+
#
|
13
|
+
# @return [Hash] if successful Hash version of JSON object
|
14
|
+
# @return [NilClass] if no options were passed
|
15
|
+
#
|
16
|
+
def attach_volume(identifier, options)
|
17
|
+
return nil if identifier.nil? || identifier == ""
|
18
|
+
wrapped_request("post", "/1.0/volumes/#{identifier}/attach", [202], options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Copy a volume and create a new one
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
# @option options [Boolean] :delete_with_server Set +true+ the volume will be removed if attached to a server that is deleted
|
11
|
+
# @option options [String] :description
|
12
|
+
# @option options [String] :name
|
13
|
+
# @option options [String] :serial
|
14
|
+
#
|
15
|
+
# @return [Hash] if successful Hash version of JSON object
|
16
|
+
# @return [NilClass] if no options were passed
|
17
|
+
#
|
18
|
+
def copy_volume(identifier, options)
|
19
|
+
return nil if identifier.nil? || identifier == ""
|
20
|
+
wrapped_request("post", "/1.0/volumes/#{identifier}/copy", [202], options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Create a new volume
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
# @option options [Boolean] :delete_with_server Set +true+ the volume will be removed if attached to a server that is deleted
|
11
|
+
# @option options [String] :description
|
12
|
+
# @option options [String] :name
|
13
|
+
# @option options [String] :serial
|
14
|
+
#
|
15
|
+
# @return [Hash] if successful Hash version of JSON object
|
16
|
+
# @return [NilClass] if no options were passed
|
17
|
+
#
|
18
|
+
def create_volume(options)
|
19
|
+
return nil if options.empty? || options.nil?
|
20
|
+
wrapped_request("post", "/1.0/volumes", [202], options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Destroy the volume and free up the resources.
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
#
|
11
|
+
# @return [Hash] if successful Hash version of JSON object
|
12
|
+
#
|
13
|
+
def delete_volume(identifier, options = {})
|
14
|
+
return nil if identifier.nil? || identifier == ""
|
15
|
+
wrapped_request("delete", "/1.0/volumes/#{identifier}", [202], options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Detach the volume from its server
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
#
|
11
|
+
# @return [Hash] if successful Hash version of JSON object
|
12
|
+
# @return [NilClass] if no options were passed
|
13
|
+
#
|
14
|
+
def detach_volume(identifier, options = {})
|
15
|
+
return nil if identifier.nil? || identifier == ""
|
16
|
+
wrapped_request("post", "/1.0/volumes/#{identifier}/detach", [202], options)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Fog
|
2
|
+
module Brightbox
|
3
|
+
class Compute
|
4
|
+
class Real
|
5
|
+
# Get full details of the volume.
|
6
|
+
#
|
7
|
+
# @param [String] identifier Unique reference to identify the resource
|
8
|
+
# @param [Hash] options
|
9
|
+
# @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
|
10
|
+
#
|
11
|
+
# @return [Hash] if successful Hash version of JSON object
|
12
|
+
#
|
13
|
+
def get_volume(identifier, options = {})
|
14
|
+
return nil if identifier.nil? || identifier == ""
|
15
|
+
wrapped_request("get", "/1.0/volumes/#{identifier}", [200], options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|