fog-brightbox 1.4.2 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e093d1f19cc306dee85aed2df1cd8cdfd1103a4384732decce4a68855397bca5
4
- data.tar.gz: 5672ef5e5d920037120861bfa1bda35ce4ffb6f1530cc62d61a0cb02aeb22d4e
3
+ metadata.gz: 21377239d27fb6e504db5619e6ce945fdee02066f01f75629efd9028df3ba6e5
4
+ data.tar.gz: a7d34f4986720231418c445f1d121faa7001626e7984fe4b9e022afde73f807c
5
5
  SHA512:
6
- metadata.gz: cce99fc4e5978804b72374022bb42b43035709608012dbc4feb8791fa1b689d98aa2d7ee44289117986e457b8243453fe22a307b9012938a86c1485e5e43cd5d
7
- data.tar.gz: df8c06dcc583f25291bf7bd89bea248ccd7f2f0e5675330bc82cb520e6d6ab946427bce9fbbd35ef4f279b165c06c4a4e7272060ae47e5a900b12b3447f3fcc6
6
+ metadata.gz: e69f8b23071481ccc0642a12e237f82de430e149cdf171e2d1a8b1275a69e13081ff62df96c5df0128a311a7fcf0883cb10daf699296928147f6c02d7287eb5d
7
+ data.tar.gz: 38e0912ad00a805b6828c0238cf19408a16b29011d997b4876b322d0375793701160724b0b29c328127330a0ed1328091b0338bc3e11f57f84f0f95923c60746
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ### 1.5.0 / 2022-06-09
2
+
3
+ Changes:
4
+
5
+ * Added support for `Volume` resources. These are dynamic, network attached
6
+ volumes. Servers with `nbs` (Network Block Storage) types can be created
7
+ from volumes. Additional volumes can be attached to a server. The volumes
8
+ can be quickly copied and resized.
9
+
1
10
  ### 1.4.2 / 2022-06-09
2
11
 
3
12
  Bug fixes:
@@ -63,6 +63,8 @@ module Fog
63
63
  model :user
64
64
  collection :user_collaborations
65
65
  model :user_collaboration
66
+ collection :volumes
67
+ model :volume
66
68
 
67
69
  request_path "fog/brightbox/requests/compute"
68
70
  request :accept_user_collaboration
@@ -72,7 +74,9 @@ module Fog
72
74
  request :add_servers_server_group
73
75
  request :apply_to_firewall_policy
74
76
  request :accept_user_collaboration
77
+ request :attach_volume
75
78
  request :remove_firewall_policy
79
+ request :copy_volume
76
80
  request :create_api_client
77
81
  request :create_application
78
82
  request :create_cloud_ip
@@ -84,6 +88,7 @@ module Fog
84
88
  request :create_database_server
85
89
  request :create_server
86
90
  request :create_server_group
91
+ request :create_volume
87
92
  request :delete_api_client
88
93
  request :delete_application
89
94
  request :delete_cloud_ip
@@ -97,6 +102,8 @@ module Fog
97
102
  request :delete_server
98
103
  request :delete_server_group
99
104
  request :delete_user_collaboration
105
+ request :delete_volume
106
+ request :detach_volume
100
107
  request :get_account
101
108
  request :get_api_client
102
109
  request :get_application
@@ -117,6 +124,7 @@ module Fog
117
124
  request :get_server_type
118
125
  request :get_user
119
126
  request :get_user_collaboration
127
+ request :get_volume
120
128
  request :get_zone
121
129
  request :list_accounts
122
130
  request :list_api_clients
@@ -135,12 +143,14 @@ module Fog
135
143
  request :list_servers
136
144
  request :list_users
137
145
  request :list_user_collaborations
146
+ request :list_volumes
138
147
  request :list_zones
139
148
  request :lock_resource_database_server
140
149
  request :lock_resource_database_snapshot
141
150
  request :lock_resource_image
142
151
  request :lock_resource_load_balancer
143
152
  request :lock_resource_server
153
+ request :lock_resource_volume
144
154
  request :map_cloud_ip
145
155
  request :move_servers_server_group
146
156
  request :reboot_server
@@ -156,6 +166,7 @@ module Fog
156
166
  request :reset_secret_application
157
167
  request :reset_server
158
168
  request :resend_collaboration
169
+ request :resize_volume
159
170
  request :reject_user_collaboration
160
171
  request :shutdown_server
161
172
  request :snapshot_database_server
@@ -167,6 +178,7 @@ module Fog
167
178
  request :unlock_resource_image
168
179
  request :unlock_resource_load_balancer
169
180
  request :unlock_resource_server
181
+ request :unlock_resource_volume
170
182
  request :unmap_cloud_ip
171
183
  request :update_account
172
184
  request :update_api_client
@@ -182,6 +194,7 @@ module Fog
182
194
  request :update_server
183
195
  request :update_server_group
184
196
  request :update_user
197
+ request :update_volume
185
198
 
186
199
  # The Mock Service allows you to run a fake instance of the Service
187
200
  # which makes no real connections.
@@ -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
@@ -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
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Lists summary details of volumes available for use by the Account
6
+ #
7
+ # @param [Hash] options
8
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
9
+ #
10
+ # @return [Hash] if successful Hash version of JSON object
11
+ #
12
+ def list_volumes(options = {})
13
+ wrapped_request("get", "/1.0/volumes", [200], options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # @param [String] identifier Unique reference to identify the resource
6
+ # @param [Hash] options
7
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
8
+ #
9
+ # @return [Hash] if successful Hash version of JSON object
10
+ #
11
+ def lock_resource_volume(identifier, options = {})
12
+ return nil if identifier.nil? || identifier == ""
13
+ wrapped_request("put", "/1.0/volumes/#{identifier}/lock_resource", [200], options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Resize a volume, currently limited to expanding volumes.
6
+ #
7
+ # Partitions will need to be expanded within the OS.
8
+ #
9
+ # @param [String] identifier Unique reference to identify the resource
10
+ # @param [Hash] options
11
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
12
+ # @option options [Integer] :from The original size (in MiB) to act as a preflight check to prevent duplicate requests
13
+ # @option options [Integer] :to The new size in MiB to change the volume to
14
+ #
15
+ # @return [Hash] if successful Hash version of JSON object
16
+ # @return [NilClass] if no options were passed
17
+ #
18
+ def resize_volume(identifier, options)
19
+ return nil if identifier.nil? || identifier == ""
20
+ return nil if options.empty? || options.nil?
21
+ wrapped_request("post", "/1.0/volumes/#{identifier}/resize", [202], options)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # @param [String] identifier Unique reference to identify the resource
6
+ # @param [Hash] options
7
+ # @option options [Boolean] :nested passed through with the API request. When true nested resources are expanded.
8
+ #
9
+ # @return [Hash] if successful Hash version of JSON object
10
+ #
11
+ def unlock_resource_volume(identifier, options = {})
12
+ return nil if identifier.nil? || identifier == ""
13
+ wrapped_request("put", "/1.0/volumes/#{identifier}/unlock_resource", [200], options)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module Fog
2
+ module Brightbox
3
+ class Compute
4
+ class Real
5
+ # Update some volume attributes.
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 update_volume(identifier, options)
19
+ return nil if identifier.nil? || identifier == ""
20
+ return nil if options.empty? || options.nil?
21
+ wrapped_request("put", "/1.0/volumes/#{identifier}", [202], options)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Brightbox
3
- VERSION = "1.4.2"
3
+ VERSION = "1.5.0.rc1"
4
4
  end
5
5
  end
@@ -0,0 +1,348 @@
1
+ require "spec_helper"
2
+ require "fog/brightbox/models/compute/volume"
3
+
4
+ describe Fog::Brightbox::Compute::Volume do
5
+ include ModelSetup
6
+ include SupportsResourceLocking
7
+
8
+ subject { service.volumes.new }
9
+
10
+ describe "when state is 'creating'" do
11
+ it do
12
+ subject.state = "creating"
13
+
14
+ assert subject.creating?
15
+ refute subject.attached?
16
+ refute subject.detached?
17
+ refute subject.deleting?
18
+ refute subject.deleted?
19
+ refute subject.failed?
20
+
21
+ refute subject.ready?
22
+ refute subject.finished?
23
+ end
24
+ end
25
+
26
+ describe "when state is 'attached'" do
27
+ it do
28
+ subject.state = "attached"
29
+
30
+ refute subject.creating?
31
+ assert subject.attached?
32
+ refute subject.detached?
33
+ refute subject.deleting?
34
+ refute subject.deleted?
35
+ refute subject.failed?
36
+
37
+ assert subject.ready?
38
+ refute subject.finished?
39
+ end
40
+ end
41
+
42
+ describe "when state is 'detached'" do
43
+ it do
44
+ subject.state = "detached"
45
+
46
+ refute subject.creating?
47
+ refute subject.attached?
48
+ assert subject.detached?
49
+ refute subject.deleting?
50
+ refute subject.deleted?
51
+ refute subject.failed?
52
+
53
+ assert subject.ready?
54
+ refute subject.finished?
55
+ end
56
+ end
57
+
58
+ describe "when state is 'deleting'" do
59
+ it do
60
+ subject.state = "deleting"
61
+
62
+ refute subject.creating?
63
+ refute subject.attached?
64
+ refute subject.detached?
65
+ assert subject.deleting?
66
+ refute subject.deleted?
67
+ refute subject.failed?
68
+
69
+ refute subject.ready?
70
+ refute subject.finished?
71
+ end
72
+ end
73
+
74
+ describe "when state is 'deleted'" do
75
+ it do
76
+ subject.state = "deleted"
77
+
78
+ refute subject.creating?
79
+ refute subject.attached?
80
+ refute subject.detached?
81
+ refute subject.deleting?
82
+ assert subject.deleted?
83
+ refute subject.failed?
84
+
85
+ refute subject.ready?
86
+ assert subject.finished?
87
+ end
88
+ end
89
+
90
+ describe "when state is 'failed'" do
91
+ it do
92
+ subject.state = "failed"
93
+
94
+ refute subject.creating?
95
+ refute subject.attached?
96
+ refute subject.detached?
97
+ refute subject.deleting?
98
+ refute subject.deleted?
99
+ assert subject.failed?
100
+
101
+ refute subject.ready?
102
+ assert subject.finished?
103
+ end
104
+ end
105
+
106
+ describe "#attach" do
107
+ it do
108
+ subject.id = "vol-12345"
109
+ assert subject.persisted?
110
+
111
+ server = service.servers.new
112
+ server.id = "srv-12345"
113
+
114
+ stub_request(:post, "http://localhost/1.0/volumes/vol-12345/attach").
115
+ with(:query => hash_including(:account_id),
116
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
117
+ "Content-Type" => "application/json" },
118
+ :body => hash_including(:server => "srv-12345")).
119
+ to_return(:status => 202,
120
+ :body => %q({"id":"vol-12345","status":"attached"}),
121
+ :headers => {})
122
+
123
+ subject.attach(server)
124
+
125
+ assert subject.attached?
126
+ end
127
+ end
128
+
129
+ describe "#collection_name" do
130
+ it "responds 'volumes'" do
131
+ assert_equal "volumes", subject.collection_name
132
+ end
133
+ end
134
+
135
+ describe "#copy" do
136
+ it do
137
+ subject.id = "vol-12345"
138
+ subject.state = "attached"
139
+ subject.delete_with_server = false
140
+
141
+ refute subject.delete_with_server
142
+ assert subject.persisted?
143
+
144
+ stub_request(:post, "http://localhost/1.0/volumes/vol-12345/copy").
145
+ with(:query => hash_including(:account_id),
146
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
147
+ "Content-Type" => "application/json" },
148
+ :body => hash_including(:delete_with_server => true)).
149
+ to_return(:status => 202,
150
+ :body => %q({"id":"vol-abcde","delete_with_server":true,"name":"Copy of vol-12345 (Impish Image)","status":"detached"}),
151
+ :headers => {})
152
+
153
+ copy = subject.copy(delete_with_server: true)
154
+
155
+ assert copy.persisted?
156
+ assert_equal "vol-abcde", copy.id
157
+ assert copy.delete_with_server
158
+ assert copy.detached?
159
+ end
160
+ end
161
+
162
+ describe "#detach" do
163
+ it do
164
+ subject.id = "vol-12345"
165
+ subject.state = "attached"
166
+
167
+ assert subject.persisted?
168
+
169
+ stub_request(:post, "http://localhost/1.0/volumes/vol-12345/detach").
170
+ with(:query => hash_including(:account_id),
171
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
172
+ "Content-Type" => "application/json" }).
173
+ to_return(:status => 202,
174
+ :body => %q({"id":"vol-12345","status":"detached"}),
175
+ :headers => {})
176
+
177
+ subject.detach
178
+
179
+ assert subject.detached?
180
+ end
181
+ end
182
+
183
+ describe "#destroy" do
184
+ it do
185
+ subject.id = "vol-12345"
186
+ assert subject.persisted?
187
+
188
+ stub_request(:delete, "http://localhost/1.0/volumes/vol-12345").
189
+ with(:query => hash_including(:account_id),
190
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
191
+ "Content-Type" => "application/json" }).
192
+ to_return(:status => 202,
193
+ :body => %q({"id":"vol-12345","status":"deleting"}),
194
+ :headers => {})
195
+
196
+ subject.destroy
197
+ assert_equal "deleting", subject.state
198
+ end
199
+ end
200
+
201
+ describe "#ready?" do
202
+ describe "when state is 'creating'" do
203
+ it do
204
+ subject.state = "creating"
205
+
206
+ refute subject.ready?
207
+ end
208
+ end
209
+
210
+ describe "when state is 'attached'" do
211
+ it do
212
+ subject.state = "attached"
213
+
214
+ assert subject.ready?
215
+ end
216
+ end
217
+
218
+ describe "when state is 'detached'" do
219
+ it do
220
+ subject.state = "detached"
221
+
222
+ assert subject.ready?
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#resize" do
228
+ it do
229
+ subject.id = "vol-12345"
230
+ subject.size = 40_000
231
+
232
+ assert subject.persisted?
233
+
234
+ stub_request(:post, "http://localhost/1.0/volumes/vol-12345/resize").
235
+ with(:query => hash_including(:account_id),
236
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
237
+ "Content-Type" => "application/json" },
238
+ :body => hash_including(:from => 40_000, :to => 50_000)).
239
+ to_return(:status => 202,
240
+ :body => %q({"id":"vol-12345","size": 50000}),
241
+ :headers => {})
242
+
243
+ subject.resize(to: 50_000)
244
+
245
+ assert 50_000, subject.size
246
+ end
247
+ end
248
+
249
+ describe "#resource_name" do
250
+ it "responds 'volume'" do
251
+ assert_equal "volume", subject.resource_name
252
+ end
253
+ end
254
+
255
+ describe "#save" do
256
+ describe "when creating" do
257
+ describe "with mutually exclusive arguments" do
258
+ it "raises Fog::Errors::Error" do
259
+ options = {
260
+ filesystem_type: "ext4",
261
+ image_id: "img-12345"
262
+ }
263
+
264
+ @volume = Fog::Brightbox::Compute::Volume.new({ :service => service }.merge(options))
265
+
266
+ assert_raises Fog::Errors::Error do
267
+ @volume.save
268
+ end
269
+ end
270
+ end
271
+
272
+ describe "with filesytem type" do
273
+ it "sends correct JSON" do
274
+ options = {
275
+ description: "An ext4 volume",
276
+ filesystem_type: "ext4"
277
+ }
278
+
279
+ stub_request(:post, "http://localhost/1.0/volumes").
280
+ with(:query => hash_including(:account_id),
281
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
282
+ "Content-Type" => "application/json" },
283
+ :body => hash_including(:filesystem_type => "ext4")).
284
+ to_return(:status => 202,
285
+ :body => %q({"id":"vol-12345","image":{"id":"img-blank"}}),
286
+ :headers => {})
287
+
288
+ @volume = Fog::Brightbox::Compute::Volume.new({ :service => service }.merge(options))
289
+ assert @volume.save
290
+ assert_equal @volume.filesystem_type, "ext4"
291
+ assert_equal @volume.image_id, "img-blank"
292
+ assert_equal @volume.description, "An ext4 volume"
293
+ end
294
+ end
295
+
296
+ describe "with image" do
297
+ it "sends correct JSON" do
298
+ options = {
299
+ image_id: "img-12345",
300
+ name: "My Volume"
301
+ }
302
+
303
+ stub_request(:post, "http://localhost/1.0/volumes").
304
+ with(:query => hash_including(:account_id),
305
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
306
+ "Content-Type" => "application/json" },
307
+ :body => hash_including(:image => "img-12345")).
308
+ to_return(:status => 202,
309
+ :body => %q({"id":"vol-12345","image":{"id":"img-12345"}}),
310
+ :headers => {})
311
+
312
+
313
+ @volume = Fog::Brightbox::Compute::Volume.new({ :service => service }.merge(options))
314
+ assert @volume.save
315
+ assert_equal @volume.image_id, "img-12345"
316
+ assert_equal @volume.name, "My Volume"
317
+ end
318
+ end
319
+ end
320
+
321
+ describe "when updating" do
322
+ it do
323
+ subject.id = "vol-12345"
324
+
325
+ assert subject.persisted?
326
+
327
+ subject.delete_with_server = true
328
+ subject.description = "Updated description"
329
+ subject.name = "New name"
330
+ subject.serial = "NewSerial"
331
+
332
+ stub_request(:put, "http://localhost/1.0/volumes/vol-12345").
333
+ with(:query => hash_including(:account_id),
334
+ :headers => { "Authorization" => "Bearer FAKECACHEDTOKEN",
335
+ "Content-Type" => "application/json" },
336
+ :body => hash_including(:delete_with_server => true,
337
+ :description => "Updated description",
338
+ :name => "New name",
339
+ :serial => "NewSerial")).
340
+ to_return(:status => 202,
341
+ :body => %q({"id":"vol-12345"}),
342
+ :headers => {})
343
+
344
+ subject.save
345
+ end
346
+ end
347
+ end
348
+ end
@@ -252,6 +252,29 @@ class Brightbox
252
252
  "inviter" => Brightbox::Compute::Formats::Nested::USER
253
253
  }
254
254
 
255
+ VOLUME = {
256
+ "id" => String,
257
+ "resource_type" => String,
258
+ "url" => String,
259
+ "status" => String,
260
+ "name" => Fog::Nullable::String,
261
+ "delete_with_server" => Fog::Boolean,
262
+ "description" => Fog::Nullable::String,
263
+ "boot" => Fog::Boolean,
264
+ "encrypted" => Fog::Boolean,
265
+ "filesystem_label" => Fog::Nullable::String,
266
+ "filesystem_type" => Fog::Nullable::String,
267
+ "locked" => Fog::Boolean,
268
+ "serial" => String,
269
+ "size" => Integer,
270
+ "source" => Fog::Nullable::String,
271
+ "source_type" => String,
272
+ "storage_type" => String,
273
+ "created_at" => String,
274
+ "updated_at" => String,
275
+ "deleted_at" => Fog::Nullable::String
276
+ }
277
+
255
278
  ZONE = {
256
279
  "id" => String,
257
280
  "resource_type" => String,
@@ -482,6 +505,29 @@ class Brightbox
482
505
  "inviter" => Brightbox::Compute::Formats::Nested::USER
483
506
  }
484
507
 
508
+ VOLUME = {
509
+ "id" => String,
510
+ "resource_type" => String,
511
+ "url" => String,
512
+ "status" => String,
513
+ "name" => Fog::Nullable::String,
514
+ "delete_with_server" => Fog::Boolean,
515
+ "description" => Fog::Nullable::String,
516
+ "boot" => Fog::Boolean,
517
+ "encrypted" => Fog::Boolean,
518
+ "filesystem_label" => Fog::Nullable::String,
519
+ "filesystem_type" => Fog::Nullable::String,
520
+ "locked" => Fog::Boolean,
521
+ "serial" => String,
522
+ "size" => Integer,
523
+ "source" => Fog::Nullable::String,
524
+ "source_type" => String,
525
+ "storage_type" => String,
526
+ "created_at" => String,
527
+ "updated_at" => String,
528
+ "deleted_at" => Fog::Nullable::String
529
+ }
530
+
485
531
  ZONE = {
486
532
  "id" => String,
487
533
  "resource_type" => String,
@@ -706,6 +752,7 @@ class Brightbox
706
752
  "snapshots" => [Brightbox::Compute::Formats::Nested::IMAGE],
707
753
  "server_groups" => [Brightbox::Compute::Formats::Nested::SERVER_GROUP],
708
754
  "interfaces" => [Brightbox::Compute::Formats::Nested::INTERFACE],
755
+ "volumes" => [Brightbox::Compute::Formats::Nested::VOLUME],
709
756
  "zone" => Fog::Brightbox::Nullable::Zone,
710
757
  "licence_name" => Fog::Nullable::String,
711
758
  "username" => Fog::Nullable::String,
@@ -763,6 +810,32 @@ class Brightbox
763
810
  "inviter" => Brightbox::Compute::Formats::Nested::USER
764
811
  }
765
812
 
813
+ VOLUME = {
814
+ "id" => String,
815
+ "resource_type" => String,
816
+ "url" => String,
817
+ "status" => String,
818
+ "name" => Fog::Nullable::String,
819
+ "delete_with_server" => Fog::Boolean,
820
+ "description" => Fog::Nullable::String,
821
+ "boot" => Fog::Boolean,
822
+ "encrypted" => Fog::Boolean,
823
+ "filesystem_label" => Fog::Nullable::String,
824
+ "filesystem_type" => Fog::Nullable::String,
825
+ "locked" => Fog::Boolean,
826
+ "serial" => String,
827
+ "size" => Integer,
828
+ "source" => Fog::Nullable::String,
829
+ "source_type" => String,
830
+ "storage_type" => String,
831
+ "created_at" => String,
832
+ "updated_at" => String,
833
+ "deleted_at" => Fog::Nullable::String,
834
+ "account" => Brightbox::Compute::Formats::Nested::ACCOUNT,
835
+ "image" => Fog::Brightbox::Nullable::Image,
836
+ "server" => Fog::Brightbox::Nullable::Server
837
+ }
838
+
766
839
  ZONE = {
767
840
  "id" => String,
768
841
  "resource_type" => String,
@@ -787,6 +860,7 @@ class Brightbox
787
860
  SERVER_GROUPS = [Brightbox::Compute::Formats::Collected::SERVER_GROUP]
788
861
  SERVER_TYPES = [Brightbox::Compute::Formats::Collected::SERVER_TYPE]
789
862
  USERS = [Brightbox::Compute::Formats::Collected::USER]
863
+ VOLUMES = [Brightbox::Compute::Formats::Collected::VOLUME]
790
864
  ZONES = [Brightbox::Compute::Formats::Collected::ZONE]
791
865
  end
792
866
  end
@@ -0,0 +1,57 @@
1
+ Shindo.tests("Fog::Compute[:brightbox] | volume requests", ["brightbox"]) do
2
+ pending if Fog.mocking?
3
+ image_id = Brightbox::Compute::TestSupport.image_id
4
+
5
+ tests("success") do
6
+ create_options = { image: image_id }
7
+
8
+ tests("#create_volume(#{create_options.inspect})") do
9
+ result = Fog::Compute[:brightbox].create_volume(create_options)
10
+ @volume_id = result["id"]
11
+ data_matches_schema(Brightbox::Compute::Formats::Full::VOLUME, :allow_extra_keys => true) { result }
12
+ end
13
+
14
+ tests("#list_volumes") do
15
+ result = Fog::Compute[:brightbox].list_volumes
16
+ data_matches_schema(Brightbox::Compute::Formats::Collection::VOLUMES, :allow_extra_keys => true) { result }
17
+
18
+ test("#{@volume_id} is listed") do
19
+ result.any? do |volume|
20
+ volume["id"] == @volume_id
21
+ end
22
+ end
23
+ end
24
+
25
+ tests("#get_volume('#{@volume_id}')") do
26
+ result = Fog::Compute[:brightbox].get_volume(@volume_id)
27
+ data_matches_schema(Brightbox::Compute::Formats::Full::VOLUME, :allow_extra_keys => true) { result }
28
+ end
29
+
30
+ update_options = {
31
+ name: "New name"
32
+ }
33
+ tests("#update_volume('#{@volume_id}', ...)") do
34
+ result = Fog::Compute[:brightbox].update_volume(@volume_id, update_options)
35
+ data_matches_schema(Brightbox::Compute::Formats::Full::VOLUME, :allow_extra_keys => true) { result }
36
+
37
+ test("name has updated") { result["name"] == "New name" }
38
+ end
39
+
40
+ Fog::Compute[:brightbox].volumes.get(@volume_id).wait_for { ready? }
41
+
42
+ tests("#delete_volume('#{@volume_id}')") do
43
+ result = Fog::Compute[:brightbox].delete_volume(@volume_id)
44
+ data_matches_schema(Brightbox::Compute::Formats::Full::VOLUME, :allow_extra_keys => true) { result }
45
+ end
46
+ end
47
+
48
+ tests("failure") do
49
+ tests("create_volume without options").raises(ArgumentError) do
50
+ Fog::Compute[:brightbox].create_volume
51
+ end
52
+
53
+ tests("get_volume with invalid ID").raises(Excon::Errors::NotFound) do
54
+ Fog::Compute[:brightbox].get_volume("vol-00000")
55
+ end
56
+ end
57
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-brightbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 1.5.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Thornthwaite
@@ -219,6 +219,8 @@ files:
219
219
  - lib/fog/brightbox/models/compute/user_collaboration.rb
220
220
  - lib/fog/brightbox/models/compute/user_collaborations.rb
221
221
  - lib/fog/brightbox/models/compute/users.rb
222
+ - lib/fog/brightbox/models/compute/volume.rb
223
+ - lib/fog/brightbox/models/compute/volumes.rb
222
224
  - lib/fog/brightbox/models/compute/zone.rb
223
225
  - lib/fog/brightbox/models/compute/zones.rb
224
226
  - lib/fog/brightbox/models/storage/directories.rb
@@ -232,6 +234,8 @@ files:
232
234
  - lib/fog/brightbox/requests/compute/add_nodes_load_balancer.rb
233
235
  - lib/fog/brightbox/requests/compute/add_servers_server_group.rb
234
236
  - lib/fog/brightbox/requests/compute/apply_to_firewall_policy.rb
237
+ - lib/fog/brightbox/requests/compute/attach_volume.rb
238
+ - lib/fog/brightbox/requests/compute/copy_volume.rb
235
239
  - lib/fog/brightbox/requests/compute/create_api_client.rb
236
240
  - lib/fog/brightbox/requests/compute/create_application.rb
237
241
  - lib/fog/brightbox/requests/compute/create_cloud_ip.rb
@@ -243,6 +247,7 @@ files:
243
247
  - lib/fog/brightbox/requests/compute/create_load_balancer.rb
244
248
  - lib/fog/brightbox/requests/compute/create_server.rb
245
249
  - lib/fog/brightbox/requests/compute/create_server_group.rb
250
+ - lib/fog/brightbox/requests/compute/create_volume.rb
246
251
  - lib/fog/brightbox/requests/compute/delete_api_client.rb
247
252
  - lib/fog/brightbox/requests/compute/delete_application.rb
248
253
  - lib/fog/brightbox/requests/compute/delete_cloud_ip.rb
@@ -256,6 +261,8 @@ files:
256
261
  - lib/fog/brightbox/requests/compute/delete_server.rb
257
262
  - lib/fog/brightbox/requests/compute/delete_server_group.rb
258
263
  - lib/fog/brightbox/requests/compute/delete_user_collaboration.rb
264
+ - lib/fog/brightbox/requests/compute/delete_volume.rb
265
+ - lib/fog/brightbox/requests/compute/detach_volume.rb
259
266
  - lib/fog/brightbox/requests/compute/get_account.rb
260
267
  - lib/fog/brightbox/requests/compute/get_api_client.rb
261
268
  - lib/fog/brightbox/requests/compute/get_application.rb
@@ -276,6 +283,7 @@ files:
276
283
  - lib/fog/brightbox/requests/compute/get_server_type.rb
277
284
  - lib/fog/brightbox/requests/compute/get_user.rb
278
285
  - lib/fog/brightbox/requests/compute/get_user_collaboration.rb
286
+ - lib/fog/brightbox/requests/compute/get_volume.rb
279
287
  - lib/fog/brightbox/requests/compute/get_zone.rb
280
288
  - lib/fog/brightbox/requests/compute/list_accounts.rb
281
289
  - lib/fog/brightbox/requests/compute/list_api_clients.rb
@@ -294,12 +302,14 @@ files:
294
302
  - lib/fog/brightbox/requests/compute/list_servers.rb
295
303
  - lib/fog/brightbox/requests/compute/list_user_collaborations.rb
296
304
  - lib/fog/brightbox/requests/compute/list_users.rb
305
+ - lib/fog/brightbox/requests/compute/list_volumes.rb
297
306
  - lib/fog/brightbox/requests/compute/list_zones.rb
298
307
  - lib/fog/brightbox/requests/compute/lock_resource_database_server.rb
299
308
  - lib/fog/brightbox/requests/compute/lock_resource_database_snapshot.rb
300
309
  - lib/fog/brightbox/requests/compute/lock_resource_image.rb
301
310
  - lib/fog/brightbox/requests/compute/lock_resource_load_balancer.rb
302
311
  - lib/fog/brightbox/requests/compute/lock_resource_server.rb
312
+ - lib/fog/brightbox/requests/compute/lock_resource_volume.rb
303
313
  - lib/fog/brightbox/requests/compute/map_cloud_ip.rb
304
314
  - lib/fog/brightbox/requests/compute/move_servers_server_group.rb
305
315
  - lib/fog/brightbox/requests/compute/reboot_server.rb
@@ -315,6 +325,7 @@ files:
315
325
  - lib/fog/brightbox/requests/compute/reset_secret_api_client.rb
316
326
  - lib/fog/brightbox/requests/compute/reset_secret_application.rb
317
327
  - lib/fog/brightbox/requests/compute/reset_server.rb
328
+ - lib/fog/brightbox/requests/compute/resize_volume.rb
318
329
  - lib/fog/brightbox/requests/compute/shutdown_server.rb
319
330
  - lib/fog/brightbox/requests/compute/snapshot_database_server.rb
320
331
  - lib/fog/brightbox/requests/compute/snapshot_server.rb
@@ -325,6 +336,7 @@ files:
325
336
  - lib/fog/brightbox/requests/compute/unlock_resource_image.rb
326
337
  - lib/fog/brightbox/requests/compute/unlock_resource_load_balancer.rb
327
338
  - lib/fog/brightbox/requests/compute/unlock_resource_server.rb
339
+ - lib/fog/brightbox/requests/compute/unlock_resource_volume.rb
328
340
  - lib/fog/brightbox/requests/compute/unmap_cloud_ip.rb
329
341
  - lib/fog/brightbox/requests/compute/update_account.rb
330
342
  - lib/fog/brightbox/requests/compute/update_api_client.rb
@@ -340,6 +352,7 @@ files:
340
352
  - lib/fog/brightbox/requests/compute/update_server.rb
341
353
  - lib/fog/brightbox/requests/compute/update_server_group.rb
342
354
  - lib/fog/brightbox/requests/compute/update_user.rb
355
+ - lib/fog/brightbox/requests/compute/update_volume.rb
343
356
  - lib/fog/brightbox/requests/storage/copy_object.rb
344
357
  - lib/fog/brightbox/requests/storage/delete_container.rb
345
358
  - lib/fog/brightbox/requests/storage/delete_multiple_objects.rb
@@ -398,6 +411,7 @@ files:
398
411
  - spec/fog/compute/brightbox/server_spec.rb
399
412
  - spec/fog/compute/brightbox/user_collaboration_spec.rb
400
413
  - spec/fog/compute/brightbox/user_spec.rb
414
+ - spec/fog/compute/brightbox/volume_spec.rb
401
415
  - spec/fog/compute/brightbox/zone_spec.rb
402
416
  - spec/fog/compute/brightbox_spec.rb
403
417
  - spec/fog/storage/brightbox_spec.rb
@@ -434,6 +448,7 @@ files:
434
448
  - tests/brightbox/requests/compute/server_type_tests.rb
435
449
  - tests/brightbox/requests/compute/user_collaboration_tests.rb
436
450
  - tests/brightbox/requests/compute/user_tests.rb
451
+ - tests/brightbox/requests/compute/volume_tests.rb
437
452
  - tests/brightbox/requests/compute/zone_tests.rb
438
453
  - tests/helper.rb
439
454
  - tests/helpers/collection_helper.rb
@@ -462,9 +477,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
462
477
  version: '2.0'
463
478
  required_rubygems_version: !ruby/object:Gem::Requirement
464
479
  requirements:
465
- - - ">="
480
+ - - ">"
466
481
  - !ruby/object:Gem::Version
467
- version: '0'
482
+ version: 1.3.1
468
483
  requirements: []
469
484
  rubygems_version: 3.0.6
470
485
  signing_key:
@@ -503,6 +518,7 @@ test_files:
503
518
  - spec/fog/compute/brightbox/server_spec.rb
504
519
  - spec/fog/compute/brightbox/user_collaboration_spec.rb
505
520
  - spec/fog/compute/brightbox/user_spec.rb
521
+ - spec/fog/compute/brightbox/volume_spec.rb
506
522
  - spec/fog/compute/brightbox/zone_spec.rb
507
523
  - spec/fog/compute/brightbox_spec.rb
508
524
  - spec/fog/storage/brightbox_spec.rb