fog-proxmox 0.14.0 → 0.15.1

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +28 -4
  4. data/lib/fog/proxmox/attributes.rb +3 -2
  5. data/lib/fog/proxmox/auth/token/access_ticket.rb +68 -57
  6. data/lib/fog/proxmox/auth/token/user_token.rb +79 -66
  7. data/lib/fog/proxmox/auth/token.rb +66 -60
  8. data/lib/fog/proxmox/compute/models/disk.rb +6 -1
  9. data/lib/fog/proxmox/compute/models/disks.rb +1 -1
  10. data/lib/fog/proxmox/compute/models/interface.rb +1 -1
  11. data/lib/fog/proxmox/compute/models/interfaces.rb +1 -1
  12. data/lib/fog/proxmox/compute/models/node.rb +3 -5
  13. data/lib/fog/proxmox/compute/models/nodes.rb +1 -1
  14. data/lib/fog/proxmox/compute/models/server.rb +33 -16
  15. data/lib/fog/proxmox/compute/models/server_config.rb +9 -4
  16. data/lib/fog/proxmox/compute/models/servers.rb +5 -5
  17. data/lib/fog/proxmox/compute/models/snapshot.rb +1 -1
  18. data/lib/fog/proxmox/compute/models/snapshots.rb +1 -1
  19. data/lib/fog/proxmox/compute/models/storage.rb +3 -2
  20. data/lib/fog/proxmox/compute/models/storages.rb +2 -2
  21. data/lib/fog/proxmox/compute/models/task.rb +1 -1
  22. data/lib/fog/proxmox/compute/models/tasks.rb +1 -0
  23. data/lib/fog/proxmox/compute/models/volume.rb +2 -1
  24. data/lib/fog/proxmox/compute/models/volumes.rb +2 -2
  25. data/lib/fog/proxmox/compute/requests/get_server_config.rb +14 -14
  26. data/lib/fog/proxmox/compute/requests/get_server_status.rb +17 -17
  27. data/lib/fog/proxmox/compute/requests/log_task.rb +1 -1
  28. data/lib/fog/proxmox/core.rb +28 -24
  29. data/lib/fog/proxmox/errors.rb +2 -1
  30. data/lib/fog/proxmox/hash.rb +0 -2
  31. data/lib/fog/proxmox/helpers/controller_helper.rb +3 -4
  32. data/lib/fog/proxmox/helpers/cpu_helper.rb +13 -6
  33. data/lib/fog/proxmox/helpers/disk_helper.rb +18 -12
  34. data/lib/fog/proxmox/helpers/ip_helper.rb +21 -20
  35. data/lib/fog/proxmox/helpers/nic_helper.rb +23 -14
  36. data/lib/fog/proxmox/identity/models/domain.rb +7 -3
  37. data/lib/fog/proxmox/identity/models/domain_type.rb +0 -1
  38. data/lib/fog/proxmox/identity/models/domains.rb +1 -2
  39. data/lib/fog/proxmox/identity/models/group.rb +4 -2
  40. data/lib/fog/proxmox/identity/models/groups.rb +1 -1
  41. data/lib/fog/proxmox/identity/models/permission.rb +5 -4
  42. data/lib/fog/proxmox/identity/models/permissions.rb +3 -1
  43. data/lib/fog/proxmox/identity/models/pool.rb +4 -4
  44. data/lib/fog/proxmox/identity/models/pools.rb +4 -4
  45. data/lib/fog/proxmox/identity/models/role.rb +1 -1
  46. data/lib/fog/proxmox/identity/models/roles.rb +1 -1
  47. data/lib/fog/proxmox/identity/models/token.rb +4 -3
  48. data/lib/fog/proxmox/identity/models/token_info.rb +2 -2
  49. data/lib/fog/proxmox/identity/models/tokens.rb +9 -13
  50. data/lib/fog/proxmox/identity/models/user.rb +1 -2
  51. data/lib/fog/proxmox/identity/models/users.rb +1 -1
  52. data/lib/fog/proxmox/identity/requests/get_user.rb +1 -0
  53. data/lib/fog/proxmox/identity/requests/list_user_permissions.rb +1 -1
  54. data/lib/fog/proxmox/network/models/networks.rb +1 -1
  55. data/lib/fog/proxmox/network/models/node.rb +1 -0
  56. data/lib/fog/proxmox/network/models/nodes.rb +1 -1
  57. data/lib/fog/proxmox/string.rb +4 -3
  58. data/lib/fog/proxmox/version.rb +1 -1
  59. data/lib/fog/proxmox.rb +1 -3
  60. data/spec/compute_spec.rb +3 -2
  61. data/spec/fixtures/proxmox/compute/snapshots.yml +350 -1055
  62. data/spec/hash_spec.rb +2 -1
  63. data/spec/helpers/controller_helper_spec.rb +135 -123
  64. data/spec/helpers/cpu_helper_spec.rb +58 -53
  65. data/spec/helpers/disk_helper_spec.rb +104 -54
  66. data/spec/helpers/ip_helper_spec.rb +155 -138
  67. data/spec/helpers/nic_helper_spec.rb +29 -20
  68. data/spec/identity_spec.rb +86 -74
  69. data/spec/proxmox_vcr.rb +3 -3
  70. metadata +89 -90
  71. data/.bundle/config +0 -4
  72. data/.codeclimate.yml +0 -14
  73. data/.github/CODE_OF_CONDUCT.md +0 -74
  74. data/.github/CONTRIBUTING.md +0 -20
  75. data/.github/CONTRIBUTORS.md +0 -9
  76. data/.github/FUNDING.yml +0 -12
  77. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  78. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  79. data/.github/ISSUE_TEMPLATE.md +0 -43
  80. data/.github/SUPPORT.md +0 -9
  81. data/.github/fogproxmox.png +0 -0
  82. data/.github/workflows/ci.yml +0 -79
  83. data/.gitignore +0 -8
  84. data/.rubocop.yml +0 -13
  85. data/.ruby-gemset +0 -1
  86. data/.solargraph.yml +0 -10
  87. data/.vscode/launch.json +0 -96
  88. data/.vscode/settings.json +0 -45
  89. data/.vscode/tasks.json +0 -27
  90. data/Gemfile +0 -23
  91. data/Rakefile +0 -58
  92. data/bin/console +0 -29
  93. data/bin/setup +0 -29
  94. data/fog-proxmox.gemspec +0 -63
@@ -26,6 +26,7 @@ module Fog
26
26
  module Proxmox
27
27
  class Compute
28
28
  # Server model
29
+ # rubocop:disable ClassLength
29
30
  class Server < Fog::Compute::Server
30
31
  identity :vmid
31
32
  attribute :type
@@ -72,20 +73,21 @@ module Fog
72
73
  super(new_attributes)
73
74
  end
74
75
 
76
+ def to_s
77
+ name
78
+ end
79
+
75
80
  def container?
76
81
  type == 'lxc'
77
82
  end
78
83
 
79
84
  def persisted?
80
85
  service.next_vmid(vmid: vmid)
81
- persisted = false
82
- persisted
86
+ false
83
87
  rescue Excon::Error::InternalServerError
84
- persisted = false
85
- persisted
88
+ false
86
89
  rescue Excon::Error::BadRequest
87
- persisted = true
88
- persisted
90
+ true
89
91
  end
90
92
 
91
93
  # request with async task
@@ -122,6 +124,7 @@ module Fog
122
124
  action_known = %w[start stop resume suspend shutdown reset].include? action
123
125
  message = "Action #{action} not implemented"
124
126
  raise Fog::Errors::Error, message unless action_known
127
+
125
128
  request(:action_server, options, action: action, vmid: vmid)
126
129
  reload
127
130
  end
@@ -136,11 +139,11 @@ module Fog
136
139
  end
137
140
 
138
141
  def restore(backup, options = {})
139
- if container?
140
- attr_hash = options.merge(ostemplate: backup.volid, force: 1, restore: 1)
141
- else
142
- attr_hash = options.merge(archive: backup.volid, force: 1)
143
- end
142
+ attr_hash = if container?
143
+ options.merge(ostemplate: backup.volid, force: 1, restore: 1)
144
+ else
145
+ options.merge(archive: backup.volid, force: 1)
146
+ end
144
147
  save(attr_hash)
145
148
  end
146
149
 
@@ -186,14 +189,24 @@ module Fog
186
189
  end
187
190
 
188
191
  def start_console(options = {})
189
- raise ::Fog::Proxmox::Errors::ServiceError, "Unable to start console because server not running." unless ready?
192
+ unless ready?
193
+ raise ::Fog::Proxmox::Errors::ServiceError,
194
+ 'Unable to start console because server not running.'
195
+ end
196
+
190
197
  if container?
191
198
  type_console = options[:console]
192
199
  options.delete_if { |option| [:console].include? option }
193
- raise ::Fog::Proxmox::Errors::ServiceError, "Unable to start console because console container config is not set or unknown." unless type_console
200
+ unless type_console
201
+ raise ::Fog::Proxmox::Errors::ServiceError,
202
+ 'Unable to start console because console container config is not set or unknown.'
203
+ end
194
204
  else
195
205
  type_console = config.type_console
196
- raise ::Fog::Proxmox::Errors::ServiceError, "Unable to start console because VGA display server config is not set or unknown." unless type_console
206
+ unless type_console
207
+ raise ::Fog::Proxmox::Errors::ServiceError,
208
+ 'Unable to start console because VGA display server config is not set or unknown.'
209
+ end
197
210
  end
198
211
  requires :vmid, :node_id, :type
199
212
  path_params = { node: node_id, type: type, vmid: vmid }
@@ -238,17 +251,21 @@ module Fog
238
251
  private
239
252
 
240
253
  def initialize_snapshots
241
- attributes[:snapshots] = Fog::Proxmox::Compute::Snapshots.new(service: service, server_id: vmid, server_type: type, node_id: node_id)
254
+ attributes[:snapshots] =
255
+ Fog::Proxmox::Compute::Snapshots.new(service: service, server_id: vmid, server_type: type, node_id: node_id)
242
256
  end
243
257
 
244
258
  def initialize_tasks
245
- attributes[:tasks] = Fog::Proxmox::Compute::Tasks.new(service: service, node_id: node_id).select { |task| task.id == vmid }
259
+ attributes[:tasks] = Fog::Proxmox::Compute::Tasks.new(service: service, node_id: node_id).select do |task|
260
+ task.id == vmid
261
+ end
246
262
  end
247
263
 
248
264
  def node
249
265
  Fog::Proxmox::Compute::Node.new(service: service, node: node_id)
250
266
  end
251
267
  end
268
+ # rubocop:enable ClassLength
252
269
  end
253
270
  end
254
271
  end
@@ -24,7 +24,8 @@ require 'fog/proxmox/helpers/controller_helper'
24
24
  module Fog
25
25
  module Proxmox
26
26
  class Compute
27
- # ServerConfig model
27
+ # ServerConfig model: https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/{qemu|lxc}/{vmid}/config
28
+ # memory, balloon, shares and swap are in Mb
28
29
  class ServerConfig < Fog::Model
29
30
  identity :vmid
30
31
  attribute :description
@@ -99,7 +100,7 @@ module Fog
99
100
  end
100
101
 
101
102
  def flatten
102
- flat_hash = attributes.reject { |attribute| [:node_id, :type, :vmid, :disks, :interfaces].include? attribute }
103
+ flat_hash = attributes.reject { |attribute| %i[node_id type vmid disks interfaces].include? attribute }
103
104
  flat_hash.merge(interfaces_flatten)
104
105
  flat_hash.merge(disks_flatten)
105
106
  flat_hash
@@ -128,7 +129,9 @@ module Fog
128
129
  model: Fog::Proxmox::NicHelper.extract_nic_id(value),
129
130
  macaddr: Fog::Proxmox::NicHelper.extract_mac_address(value)
130
131
  }
131
- names = Fog::Proxmox::Compute::Interface.attributes.reject { |attribute| [:id, :macaddr, :model].include? attribute }
132
+ names = Fog::Proxmox::Compute::Interface.attributes.reject do |attribute|
133
+ %i[id macaddr model].include? attribute
134
+ end
132
135
  names.each { |name| nic_hash.store(name.to_sym, Fog::Proxmox::ControllerHelper.extract(name, value)) }
133
136
  attributes[:interfaces] << Fog::Proxmox::Compute::Interface.new(nic_hash)
134
137
  end
@@ -145,7 +148,9 @@ module Fog
145
148
  volid: volid,
146
149
  storage: storage
147
150
  }
148
- names = Fog::Proxmox::Compute::Disk.attributes.reject { |attribute| [:id, :size, :storage, :volid].include? attribute }
151
+ names = Fog::Proxmox::Compute::Disk.attributes.reject do |attribute|
152
+ %i[id size storage volid].include? attribute
153
+ end
149
154
  names.each { |name| disk_hash.store(name.to_sym, Fog::Proxmox::ControllerHelper.extract(name, value)) }
150
155
  attributes[:disks] << Fog::Proxmox::Compute::Disk.new(disk_hash)
151
156
  end
@@ -52,12 +52,12 @@ module Fog
52
52
  begin
53
53
  status_data = service.get_server_status path_params
54
54
  config_data = service.get_server_config path_params
55
- rescue => e
55
+ rescue StandardError => e
56
56
  if e.respond_to?('response') && e.response.respond_to?('data') && e.response.data.has_key?(:reason_phrase) && e.response.data[:reason_phrase].end_with?('does not exist')
57
57
  raise(Fog::Errors::NotFound)
58
- else
59
- raise(e)
60
58
  end
59
+
60
+ raise(e)
61
61
  else
62
62
  data = status_data.merge(config_data).merge(node: node_id, vmid: id)
63
63
  new(data)
@@ -70,8 +70,8 @@ module Fog
70
70
  end
71
71
 
72
72
  def create(new_attributes = {})
73
- object = new(new_attributes.select { |key, _value| [:node_id, :vmid, :type].include? key.to_sym })
74
- object.save(new_attributes.reject { |key, _value| [:node_id, :vmid, :type].include? key.to_sym })
73
+ object = new(new_attributes.select { |key, _value| %i[node_id vmid type].include? key.to_sym })
74
+ object.save(new_attributes.reject { |key, _value| %i[node_id vmid type].include? key.to_sym })
75
75
  object
76
76
  end
77
77
  end
@@ -51,7 +51,7 @@ module Fog
51
51
 
52
52
  def save
53
53
  path_params = { node: node_id, type: server_type, vmid: server_id }
54
- body_params = { snapname: name }
54
+ body_params = { snapname: name, vmstate: vmstate }
55
55
  server.tasks.wait_for(service.create_snapshot(path_params, body_params))
56
56
  end
57
57
 
@@ -39,7 +39,7 @@ module Fog
39
39
  end
40
40
 
41
41
  def get(name)
42
- all.find { |snapshot| snapshot.identity === name }
42
+ all.find { |snapshot| snapshot.identity == name }
43
43
  end
44
44
  end
45
45
  end
@@ -29,7 +29,7 @@
29
29
  module Fog
30
30
  module Proxmox
31
31
  class Compute
32
- # class Storage model
32
+ # class Storage model: https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/storage/{storage}
33
33
  class Storage < Fog::Model
34
34
  identity :storage
35
35
  attribute :node_id, aliases: :node
@@ -56,7 +56,8 @@ module Fog
56
56
  private
57
57
 
58
58
  def initialize_volumes
59
- attributes[:volumes] = Fog::Proxmox::Compute::Volumes.new(service: service, node_id: node_id, storage_id: identity)
59
+ attributes[:volumes] =
60
+ Fog::Proxmox::Compute::Volumes.new(service: service, node_id: node_id, storage_id: identity)
60
61
  end
61
62
  end
62
63
  end
@@ -26,7 +26,7 @@ module Fog
26
26
  class Storages < Fog::Collection
27
27
  model Fog::Proxmox::Compute::Storage
28
28
  attribute :node_id
29
-
29
+
30
30
  def new(new_attributes = {})
31
31
  super({ node_id: node_id }.merge(new_attributes))
32
32
  end
@@ -43,7 +43,7 @@ module Fog
43
43
 
44
44
  def get(id)
45
45
  requires :node_id
46
- all.find { |storage| storage.identity === id }
46
+ all.find { |storage| storage.identity == id }
47
47
  end
48
48
  end
49
49
  end
@@ -54,7 +54,7 @@ module Fog
54
54
  end
55
55
 
56
56
  def succeeded?
57
- finished? && exitstatus == 'OK'
57
+ finished? && (exitstatus == 'OK' || exitstatus.include?('WARNING'))
58
58
  end
59
59
 
60
60
  def finished?
@@ -56,6 +56,7 @@ module Fog
56
56
  task.wait_for { finished? }
57
57
  message = "Task #{task_upid} failed because #{task.exitstatus}"
58
58
  raise Fog::Errors::Error, message unless task.succeeded?
59
+
59
60
  task.succeeded?
60
61
  end
61
62
  end
@@ -31,7 +31,8 @@ require 'fog/proxmox/helpers/disk_helper'
31
31
  module Fog
32
32
  module Proxmox
33
33
  class Compute
34
- # class Volume model
34
+ # class Volume model: https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/storage/{storage}/content/{volume}
35
+ # size is in bytes
35
36
  class Volume < Fog::Model
36
37
  identity :volid
37
38
  attribute :content
@@ -37,10 +37,10 @@ module Fog
37
37
  end
38
38
 
39
39
  def list_by_content_type(content)
40
- all.select { |volume| volume.content.include? content}
40
+ all.select { |volume| volume.content.include? content }
41
41
  end
42
42
 
43
- def list_by_content_type_and_by_server(content, vmid)
43
+ def list_by_content_type_and_by_server(_content, vmid)
44
44
  all(vmid: vmid)
45
45
  end
46
46
 
@@ -38,20 +38,20 @@ module Fog
38
38
  class Mock
39
39
  def get_server_config(_path_params)
40
40
  {
41
- :onboot => 0,
42
- :memory => 512,
43
- :ostype => 'l26',
44
- :cores => 1,
45
- :keyboard => 'en-us',
46
- :digest => nil,
47
- :smbios1 => nil,
48
- :vmgenid => nil,
49
- :balloon => 0,
50
- :kvm => 0,
51
- :cpu => 'cputype=kvm64',
52
- :sockets => 1,
53
- :bootdisk => 'scsi0',
54
- :vga => 'std'
41
+ onboot: 0,
42
+ memory: 512,
43
+ ostype: 'l26',
44
+ cores: 1,
45
+ keyboard: 'en-us',
46
+ digest: nil,
47
+ smbios1: nil,
48
+ vmgenid: nil,
49
+ balloon: 0,
50
+ kvm: 0,
51
+ cpu: 'cputype=kvm64',
52
+ sockets: 1,
53
+ bootdisk: 'scsi0',
54
+ vga: 'std'
55
55
  }
56
56
  end
57
57
  end
@@ -38,23 +38,23 @@ module Fog
38
38
  class Mock
39
39
  def get_server_status(_path_params)
40
40
  {
41
- :netout => 0,
42
- :ha => { 'managed' => 0 },
43
- :mem => 0,
44
- :vmid => '100',
45
- :maxdisk => 8_589_934_592,
46
- :diskread => 0,
47
- :template => '',
48
- :qmpstatus => 'stopped',
49
- :diskwrite => 0,
50
- :maxmem => 536_870_912,
51
- :pid => nil,
52
- :uptime => 0,
53
- :status => 'stopped',
54
- :cpu => 'cputype=kvm64',
55
- :cpus => 1,
56
- :disk => 0,
57
- :netin => 0
41
+ netout: 0,
42
+ ha: { 'managed' => 0 },
43
+ mem: 0,
44
+ vmid: '100',
45
+ maxdisk: 8_589_934_592,
46
+ diskread: 0,
47
+ template: '',
48
+ qmpstatus: 'stopped',
49
+ diskwrite: 0,
50
+ maxmem: 536_870_912,
51
+ pid: nil,
52
+ uptime: 0,
53
+ status: 'stopped',
54
+ cpu: 'cputype=kvm64',
55
+ cpus: 1,
56
+ disk: 0,
57
+ netin: 0
58
58
  }
59
59
  end
60
60
  end
@@ -35,7 +35,7 @@ module Fog
35
35
 
36
36
  # class Mock status_task
37
37
  class Mock
38
- def log_task(_node, _upid, options = {})
38
+ def log_task(_node, _upid, _options = {})
39
39
  [{ 't' => 'TASK OK', 'n' => 1 }]
40
40
  end
41
41
  end
@@ -26,9 +26,7 @@ module Fog
26
26
  # Core module
27
27
  module Core
28
28
  attr_accessor :token
29
- attr_reader :auth_method
30
- attr_reader :expires
31
- attr_reader :current_user
29
+ attr_reader :auth_method, :expires, :current_user
32
30
 
33
31
  def user_token?
34
32
  @auth_token == 'user_token'
@@ -46,24 +44,25 @@ module Fog
46
44
  @connection = Fog::Core::Connection.new(@proxmox_url, @persistent, @connection_options)
47
45
  end
48
46
 
49
- def setup(options)
47
+ def setup(options)
50
48
  if options.respond_to?(:config_service?) && options.config_service?
51
49
  configure(options)
52
50
  return
53
51
  end
54
52
  Fog::Proxmox::Variables.to_variables(self, options, 'proxmox')
55
53
  @connection_options = options[:connection_options] || {}
56
- @connection_options[:disable_proxy] = true if ENV['DISABLE_PROXY'] == 'true'
54
+ @connection_options[:disable_proxy] = true if ENV['DISABLE_PROXY'] == 'true'
57
55
  @connection_options[:ssl_verify_peer] = false if ENV['SSL_VERIFY_PEER'] == 'false'
56
+ @connection_options[:ignore_unexpected_eof] = true
58
57
  @proxmox_must_reauthenticate = true
59
- @persistent = options[:persistent] || false
60
- @token ||= options[:proxmox_token]
61
- @auth_method ||= options[:proxmox_auth_method]
62
- if @token
63
- @proxmox_can_reauthenticate = false
64
- else
65
- @proxmox_can_reauthenticate = true
66
- end
58
+ @persistent = options[:persistent] || false
59
+ @token ||= options[:proxmox_token]
60
+ @auth_method ||= options[:proxmox_auth_method]
61
+ @proxmox_can_reauthenticate = if @token
62
+ false
63
+ else
64
+ true
65
+ end
67
66
  end
68
67
 
69
68
  def credentials
@@ -85,31 +84,36 @@ module Fog
85
84
  def expired?
86
85
  return false if @expires.nil?
87
86
  return false if @expires == 0
88
- return @expires - Time.now.utc.to_i < 60
87
+
88
+ @expires - Time.now.utc.to_i < 60
89
89
  end
90
90
 
91
91
  def request(params)
92
- retried = false
92
+ retried = false
93
93
  begin
94
94
  authenticate! if expired?
95
- request_options = params.merge(path: "#{@path}/#{params[:path]}", headers: @auth_token.headers(params[:method], params.respond_to?(:headers) ? params[:headers] : {}, {}))
95
+ request_options = params.merge(path: "#{@path}/#{params[:path]}",
96
+ headers: @auth_token.headers(
97
+ params[:method], params.respond_to?(:headers) ? params[:headers] : {}, {}
98
+ ))
96
99
  response = @connection.request(request_options)
97
- rescue Excon::Errors::Unauthorized => error
100
+ rescue Excon::Errors::Unauthorized => e
98
101
  # token expiration and token renewal possible
99
- if !%w[Bad username or password, invalid token value!].include?(error.response.body) && @proxmox_can_reauthenticate && !retried
102
+ if !%w[Bad username or password, invalid token
103
+ value!].include?(e.response.body) && @proxmox_can_reauthenticate && !retried
100
104
  authenticate!
101
105
  retried = true
102
106
  retry
103
107
  # bad credentials or token renewal not possible
104
108
  else
105
- raise error
109
+ raise e
106
110
  end
107
- rescue Excon::Errors::HTTPStatusError => error
108
- raise case error
111
+ rescue Excon::Errors::HTTPStatusError => e
112
+ raise case e
109
113
  when Excon::Errors::NotFound
110
- self.class.not_found_class.slurp(error)
114
+ self.class.not_found_class.slurp(e)
111
115
  else
112
- error
116
+ e
113
117
  end
114
118
  end
115
119
  Fog::Proxmox::Json.get_data(response)
@@ -123,7 +127,7 @@ module Fog
123
127
  if @proxmox_must_reauthenticate
124
128
  @token = nil if @proxmox_must_reauthenticate
125
129
  @auth_token = Fog::Proxmox::Auth::Token.build(proxmox_options, @connection_options)
126
- @current_user = proxmox_options[:proxmox_userid] ? proxmox_options[:proxmox_userid] : proxmox_options[:proxmox_username]
130
+ @current_user = proxmox_options[:proxmox_userid] || proxmox_options[:proxmox_username]
127
131
  @token = @auth_token.token
128
132
  @expires = @auth_token.expires
129
133
  @proxmox_must_reauthenticate = false
@@ -51,7 +51,8 @@ module Fog
51
51
  def self.slurp(error)
52
52
  new_error = super(error)
53
53
  unless new_error.response_data.nil? || new_error.response_data['badRequest'].nil?
54
- new_error.instance_variable_set(:@validation_errors, new_error.response_data['badRequest']['validationErrors'])
54
+ new_error.instance_variable_set(:@validation_errors,
55
+ new_error.response_data['badRequest']['validationErrors'])
55
56
  end
56
57
  new_error
57
58
  end
@@ -21,7 +21,6 @@ module Fog
21
21
  module Proxmox
22
22
  # module Hash mixins
23
23
  module Hash
24
-
25
24
  def self.stringify(hash)
26
25
  filtered = hash.reject { |_key, value| value.nil? }
27
26
  a = filtered.to_a.collect { |item| item.join('=') }
@@ -33,7 +32,6 @@ module Fog
33
32
  a = filtered.to_a.collect { |item| item.join(': ') }
34
33
  a.join(',')
35
34
  end
36
-
37
35
  end
38
36
  end
39
37
  end
@@ -21,10 +21,9 @@ module Fog
21
21
  module Proxmox
22
22
  # module ControllerHelper mixins
23
23
  module ControllerHelper
24
-
25
24
  CONTROLLERS = %w[ide sata scsi virtio mp rootfs].freeze
26
25
  def self.extract(name, controller_value)
27
- matches = controller_value.match(/[,]{0,1}#{name}[=]{1}(?<name_value>[\w\/\.\:]+)/)
26
+ matches = controller_value.match(%r{,{0,1}#{name}={1}(?<name_value>[\w/.:]+)})
28
27
  matches ? matches[:name_value] : matches
29
28
  end
30
29
 
@@ -40,6 +39,7 @@ module Fog
40
39
 
41
40
  def self.last_index(name, values)
42
41
  return -1 if values.empty?
42
+
43
43
  indexes = []
44
44
  values.each do |value|
45
45
  index = extract_index(name, value)
@@ -49,7 +49,7 @@ module Fog
49
49
  indexes.empty? ? -1 : indexes.last
50
50
  end
51
51
 
52
- def self.select(hash,name)
52
+ def self.select(hash, name)
53
53
  hash.select { |key| valid?(name, key.to_s) }
54
54
  end
55
55
 
@@ -58,7 +58,6 @@ module Fog
58
58
  CONTROLLERS.each { |controller| controllers.merge!(select(attributes, controller)) }
59
59
  controllers
60
60
  end
61
-
62
61
  end
63
62
  end
64
63
  end
@@ -21,12 +21,13 @@ module Fog
21
21
  module Proxmox
22
22
  # module Cpu mixins
23
23
  module CpuHelper
24
- CPU_REGEXP = /(\bcputype=)?(?<cputype>[\w-]+)[,]?(\bflags=)?(?<flags>[[\+\-][\w-]+[;]?]*)/
25
- FLAGS = { spectre: 'spec-ctrl', pcid: 'pcid', ssbd: 'ssbd', ibpb: 'ibpb', virt_ssbd: 'virt-ssbd', amd_ssbd: 'amd-ssbd', amd_no_ssb: 'amd-no-ssb', md_clear: 'md-clear', pdpe1gb: 'pdpe1gb', hv_tlbflush: 'hv-tlbflush', aes: 'aes', hv_evmcs: 'hv-evmcs' }
24
+ CPU_REGEXP = /(\bcputype=)?(?<cputype>[\w-]+),?(\bflags=)?(?<flags>[[+-][\w-]+;?]*)/
25
+ FLAGS = { spectre: 'spec-ctrl', pcid: 'pcid', ssbd: 'ssbd', ibpb: 'ibpb', virt_ssbd: 'virt-ssbd',
26
+ amd_ssbd: 'amd-ssbd', amd_no_ssb: 'amd-no-ssb', md_clear: 'md-clear', pdpe1gb: 'pdpe1gb', hv_tlbflush: 'hv-tlbflush', aes: 'aes', hv_evmcs: 'hv-evmcs' }
26
27
  def self.flags
27
28
  FLAGS
28
29
  end
29
-
30
+
30
31
  def self.extract(cpu, name)
31
32
  captures_h = cpu ? CPU_REGEXP.match(cpu.to_s) : { cputype: '', flags: '' }
32
33
  captures_h[name]
@@ -44,7 +45,11 @@ module Fog
44
45
  flag_value = '0'
45
46
  raw_values = extract_flags(cpu).split(';').select { |flag| ['+' + flag_key, '-' + flag_key].include?(flag) }
46
47
  unless raw_values.empty?
47
- flag_value = raw_values[0].start_with?('+') ? '+1' : raw_values[0].start_with?('-') ? '-1' : '0'
48
+ flag_value = if raw_values[0].start_with?('+')
49
+ '+1'
50
+ else
51
+ raw_values[0].start_with?('-') ? '-1' : '0'
52
+ end
48
53
  end
49
54
  flag_value
50
55
  end
@@ -64,12 +69,14 @@ module Fog
64
69
 
65
70
  def self.flatten(cpu_h)
66
71
  return '' unless cpu_h['cpu_type']
67
-
72
+
68
73
  cpu_type = "cputype=#{cpu_h['cpu_type']}"
69
74
  num_flags = 0
70
75
  FLAGS.each_key { |flag_key| num_flags += 1 if hash_has_no_default_flag?(cpu_h, flag_key.to_s) }
71
76
  cpu_type += ',flags=' if num_flags > 0
72
- flags_with_no_default_value = FLAGS.select { |flag_key, _flag_value| hash_has_no_default_flag?(cpu_h, flag_key.to_s) }
77
+ flags_with_no_default_value = FLAGS.select do |flag_key, _flag_value|
78
+ hash_has_no_default_flag?(cpu_h, flag_key.to_s)
79
+ end
73
80
  flags_with_no_default_value.each_with_index do |(flag_key, flag_value), index|
74
81
  cpu_type += hash_flag(cpu_h, flag_key.to_s) + flag_value if hash_has_no_default_flag?(cpu_h, flag_key.to_s)
75
82
  cpu_type += ';' if num_flags > index + 1
@@ -27,7 +27,7 @@ module Fog
27
27
  SERVER_DISK_REGEXP = /^(scsi|sata|virtio|ide)(\d+)$/
28
28
  MOUNT_POINT_REGEXP = /^(mp)(\d+)$/
29
29
  ROOTFS_REGEXP = /^(rootfs)$/
30
- CDROM_REGEXP = /^(.*)[,]{0,1}(media=cdrom)[,]{0,1}(.*)$/
30
+ CDROM_REGEXP = /^(.*),{0,1}(media=cdrom),{0,1}(.*)$/
31
31
  TEMPLATE_REGEXP = /^(.*)(base-)(.*)$/
32
32
  CLOUD_INIT_REGEXP = /^(.*)(cloudinit)(.*)$/
33
33
 
@@ -44,7 +44,7 @@ module Fog
44
44
  value += 'none'
45
45
  end
46
46
  opts = disk[:options] if disk[:options]
47
- main_a = [:id, :volid, :storage, :size]
47
+ main_a = %i[id volid storage size]
48
48
  opts ||= disk.reject { |key, _value| main_a.include? key }
49
49
  options = ''
50
50
  options += Fog::Proxmox::Hash.stringify(opts) if opts
@@ -79,9 +79,9 @@ module Fog
79
79
  # Convert API Proxmox volume/disk parameter string into volume/disk attributes hash value
80
80
  def self.extract_storage_volid_size(disk_value)
81
81
  # volid definition: <VOLUME_ID>:=<STORAGE_ID>:<storage type dependent volume name>
82
- values_a = disk_value.scan(/^(([\w-]+)[:]{0,1}([\w\/\.-]+))/)
82
+ values_a = disk_value.scan(%r{^(([\w-]+):{0,1}([\w/.-]+))})
83
83
  no_cdrom = !disk_value.match(CDROM_REGEXP)
84
- creation = disk_value.split(',')[0].match(/^(([\w-]+)[:]{1}([\d]+))$/)
84
+ creation = disk_value.split(',')[0].match(/^(([\w-]+):{1}(\d+))$/)
85
85
  values = values_a.first if values_a
86
86
  if no_cdrom
87
87
  storage = values[1]
@@ -104,11 +104,11 @@ module Fog
104
104
  val = size.match(/\d+(\w?)/)
105
105
  m = 0
106
106
  case val[1]
107
- when "K" then m = 1
108
- when "M" then m = 2
109
- when "G" then m = 3
110
- when "T" then m = 4
111
- when "P" then m = 5
107
+ when 'K' then m = 1
108
+ when 'M' then m = 2
109
+ when 'G' then m = 3
110
+ when 'T' then m = 4
111
+ when 'P' then m = 5
112
112
  end
113
113
  val[0].to_i * 1024**m
114
114
  end
@@ -118,10 +118,10 @@ module Fog
118
118
  end
119
119
 
120
120
  def self.to_human_bytes(size)
121
- units = ['Kb', 'Mb', 'Gb', 'Tb', 'Pb']
121
+ units = %w[Kb Mb Gb]
122
122
  i = 0
123
123
  human_size = size.to_s + 'b'
124
- while i < 5 && size >= 1024
124
+ while i < 3 && size >= 1024
125
125
  size = modulo_bytes(size)
126
126
  human_size = size.to_s + units[i]
127
127
  i += 1
@@ -129,9 +129,15 @@ module Fog
129
129
  human_size
130
130
  end
131
131
 
132
+ def self.to_int_gb(size_bytes)
133
+ val = to_human_bytes(size_bytes.to_i).match(/\d+(Gb)/)
134
+ val ? val[0].to_i : 0
135
+ end
136
+
132
137
  def self.extract_size(disk_value)
133
138
  size = extract_option('size', disk_value)
134
- size ? to_bytes(size) : "1G"
139
+ size = to_int_gb(to_bytes(size)).to_s if size.match?(/\d+(G)/)
140
+ size
135
141
  end
136
142
 
137
143
  def self.disk?(id)