fog-brightbox 1.4.1 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e91c9a644e0cd1ba3d41a180c1d03f5f6b4f30170838cc8119f694dd528737f
4
- data.tar.gz: 51143d7150551695ea3027a75451c15760c0005b824df2aaeb56d1c73050db34
3
+ metadata.gz: cb1f5fab98014e9dda7db0f12f010f30e35277e6516151f3ebe4f1821c662dc3
4
+ data.tar.gz: e4bb7b22b9c9e398923ce253708acfb0dd4519b7511428973ced16e20ac77e69
5
5
  SHA512:
6
- metadata.gz: 5eb27bf573f92cb3b3ecec889bf62c1ce072a8027e2734d8d4c5238590d6c9f4599388ef52bd6ac8e73b914fb4bf80639ff6a586646f3d06ea997b28903e40c8
7
- data.tar.gz: 03a47f51347c021bbe3fafbaf1a9dc5d180d6a8995ab8ce18297234bda87aea965dc7f82b5377ba8d062b00ff76164292e420b623cf6b47aa2dc0c0e45d1da53
6
+ metadata.gz: 38c16b6810afe2ebb15edeedfff0732f54e34ccc0e8bb56af85efcbcf2d43c1776957dff2b0ca44afc5a1cbc7d6b7a98c015cb5feb95aea36c820ab0eada57fd
7
+ data.tar.gz: 86e0cd498b82639fd952f3a08c03c15d8e8f623391889c23f602e6a1d7177cbe714b5527d3940e404e902d8a2acbc3c2004de97113ff6823b8656d07a35736ee
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
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
+
10
+ ### 1.4.2 / 2022-06-09
11
+
12
+ Bug fixes:
13
+
14
+ * `Fog::Brightbox::Compute::ImageSelector#latest_ubuntu` was fixed to resolve
15
+ two bugs that prevented the latest version being found since Xenial:
16
+ * The filtering for `i686` was missing later release which are only available
17
+ as `x86_64` images following support being dropped upstream. The filter is
18
+ now swapped to only match 64bit releases.
19
+ * The reverse name sorting failed when the Ubuntu codenames returned to the
20
+ start of the alphabet so `xenial` (16.04) would appear above `bionic`
21
+ (18.04) or `jammy` (22.04). The names are now split and the version used
22
+ instead for the sorting.
23
+
1
24
  ### 1.4.1 / 2021-04-20
2
25
 
3
26
  Bug fixes:
@@ -29,11 +29,11 @@ module Fog
29
29
  @images.select do |img|
30
30
  img["official"] == true &&
31
31
  img["status"] == "available" &&
32
- img["arch"] == "i686" &&
32
+ img["arch"] == "x86_64" &&
33
33
  img["name"] =~ /ubuntu/i
34
34
  end.sort do |a, b|
35
- # Reverse sort so "raring" > "precise" and "13.10" > "13.04"
36
- b["name"].downcase <=> a["name"].downcase
35
+ # Reverse sort so "22.10" > "22.04"
36
+ NameSorter.new(b["name"]).version <=> NameSorter.new(a["name"]).version
37
37
  end.first["id"]
38
38
  rescue StandardError
39
39
  nil
@@ -55,6 +55,31 @@ module Fog
55
55
  rescue StandardError
56
56
  nil
57
57
  end
58
+
59
+ class NameSorter
60
+ PATTERN = /\A(?<ubuntu>.*?)-(?<codename>.*?)-(?<version>[\d\.]*?)-(?<arch>.*?)/
61
+
62
+ def initialize(name)
63
+ @name = name
64
+ @matches = name.match(PATTERN)
65
+ end
66
+
67
+ def arch
68
+ @matches[:arch] || ""
69
+ end
70
+
71
+ def codename
72
+ @matches[:codename] || ""
73
+ end
74
+
75
+ def ubuntu?
76
+ @name.start_with?("ubuntu")
77
+ end
78
+
79
+ def version
80
+ @matches[:version] || ""
81
+ end
82
+ end
58
83
  end
59
84
  end
60
85
  end
@@ -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.1"
3
+ VERSION = "1.5.0"
4
4
  end
5
5
  end