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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/fog/brightbox/compute/shared.rb +26 -10
  4. data/lib/fog/brightbox/compute.rb +17 -0
  5. data/lib/fog/brightbox/config.rb +12 -0
  6. data/lib/fog/brightbox/models/compute/server.rb +9 -1
  7. data/lib/fog/brightbox/models/compute/volume.rb +152 -0
  8. data/lib/fog/brightbox/models/compute/volumes.rb +23 -0
  9. data/lib/fog/brightbox/oauth2.rb +47 -7
  10. data/lib/fog/brightbox/requests/compute/attach_volume.rb +23 -0
  11. data/lib/fog/brightbox/requests/compute/copy_volume.rb +25 -0
  12. data/lib/fog/brightbox/requests/compute/create_volume.rb +25 -0
  13. data/lib/fog/brightbox/requests/compute/delete_volume.rb +20 -0
  14. data/lib/fog/brightbox/requests/compute/detach_volume.rb +21 -0
  15. data/lib/fog/brightbox/requests/compute/get_volume.rb +20 -0
  16. data/lib/fog/brightbox/requests/compute/list_volumes.rb +18 -0
  17. data/lib/fog/brightbox/requests/compute/lock_resource_volume.rb +18 -0
  18. data/lib/fog/brightbox/requests/compute/resize_volume.rb +26 -0
  19. data/lib/fog/brightbox/requests/compute/unlock_resource_volume.rb +18 -0
  20. data/lib/fog/brightbox/requests/compute/update_volume.rb +26 -0
  21. data/lib/fog/brightbox/version.rb +1 -1
  22. data/spec/fog/brightbox/compute/credentials_spec.rb +41 -0
  23. data/spec/fog/brightbox/compute/get_access_token_spec.rb +305 -0
  24. data/spec/fog/brightbox/compute/two_factor_spec.rb +53 -0
  25. data/spec/fog/brightbox/oauth2/user_credentials_strategy_spec.rb +20 -0
  26. data/spec/fog/compute/brightbox/volume_spec.rb +348 -0
  27. data/tests/brightbox/compute/schema.rb +74 -0
  28. data/tests/brightbox/requests/compute/volume_tests.rb +57 -0
  29. metadata +23 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e093d1f19cc306dee85aed2df1cd8cdfd1103a4384732decce4a68855397bca5
4
- data.tar.gz: 5672ef5e5d920037120861bfa1bda35ce4ffb6f1530cc62d61a0cb02aeb22d4e
3
+ metadata.gz: 4ed1e1f608af748e905cfeafeb9f1a72674074f11720c854988e324de9e1fa84
4
+ data.tar.gz: c078791baaf84d13fb09c1f0d8ff17b9c1116f247cfb8c73647b529b97ce3bea
5
5
  SHA512:
6
- metadata.gz: cce99fc4e5978804b72374022bb42b43035709608012dbc4feb8791fa1b689d98aa2d7ee44289117986e457b8243453fe22a307b9012938a86c1485e5e43cd5d
7
- data.tar.gz: df8c06dcc583f25291bf7bd89bea248ccd7f2f0e5675330bc82cb520e6d6ab946427bce9fbbd35ef4f279b165c06c4a4e7272060ae47e5a900b12b3447f3fcc6
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
- credential_options = { :username => username, :password => password }
53
- @credentials = CredentialSet.new(client_id, client_secret, credential_options)
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
- @credentials.update_tokens(@config.cached_access_token, @config.cached_refresh_token)
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.
@@ -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
@@ -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
- connection.request(
20
- :path => "/token",
21
- :expects => 200,
22
- :headers => token_strategy.headers,
23
- :method => "POST",
24
- :body => Fog::JSON.encode(token_strategy.authorization_body_data)
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