fog-brightbox 1.4.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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