fog-proxmox 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -1
  3. data/docs/compute.md +23 -7
  4. data/docs/identity.md +31 -6
  5. data/examples/compute.rb +11 -11
  6. data/examples/identity.rb +28 -15
  7. data/fog-proxmox.gemspec +1 -1
  8. data/lib/fog/proxmox.rb +16 -76
  9. data/lib/fog/proxmox/auth/token.rb +88 -0
  10. data/lib/fog/proxmox/auth/token/access_ticket.rb +85 -0
  11. data/lib/fog/proxmox/auth/token/user_token.rb +94 -0
  12. data/lib/fog/{compute/proxmox.rb → proxmox/compute.rb} +31 -16
  13. data/lib/fog/{compute/proxmox → proxmox/compute}/models/disk.rb +15 -2
  14. data/lib/fog/{compute/proxmox → proxmox/compute}/models/disks.rb +5 -1
  15. data/lib/fog/{compute/proxmox → proxmox/compute}/models/interface.rb +4 -0
  16. data/lib/fog/{compute/proxmox → proxmox/compute}/models/interfaces.rb +1 -1
  17. data/lib/fog/{compute/proxmox → proxmox/compute}/models/node.rb +0 -0
  18. data/lib/fog/{compute/proxmox → proxmox/compute}/models/nodes.rb +1 -1
  19. data/lib/fog/{compute/proxmox → proxmox/compute}/models/server.rb +2 -2
  20. data/lib/fog/{compute/proxmox → proxmox/compute}/models/server_config.rb +8 -0
  21. data/lib/fog/{compute/proxmox → proxmox/compute}/models/servers.rb +1 -1
  22. data/lib/fog/{compute/proxmox → proxmox/compute}/models/snapshot.rb +0 -0
  23. data/lib/fog/{compute/proxmox → proxmox/compute}/models/snapshots.rb +1 -1
  24. data/lib/fog/{compute/proxmox → proxmox/compute}/models/storage.rb +0 -0
  25. data/lib/fog/{compute/proxmox → proxmox/compute}/models/storages.rb +1 -1
  26. data/lib/fog/{compute/proxmox → proxmox/compute}/models/task.rb +0 -0
  27. data/lib/fog/{compute/proxmox → proxmox/compute}/models/tasks.rb +1 -1
  28. data/lib/fog/{compute/proxmox → proxmox/compute}/models/volume.rb +6 -0
  29. data/lib/fog/{compute/proxmox → proxmox/compute}/models/volumes.rb +1 -1
  30. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/action_server.rb +0 -0
  31. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/clone_server.rb +0 -0
  32. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_backup.rb +0 -0
  33. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_server.rb +0 -0
  34. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_snapshot.rb +0 -0
  35. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_spice.rb +0 -0
  36. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_term.rb +0 -0
  37. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/create_vnc.rb +0 -0
  38. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/delete_server.rb +0 -0
  39. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/delete_snapshot.rb +0 -0
  40. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/delete_volume.rb +0 -0
  41. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_node_statistics.rb +0 -0
  42. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_server_config.rb +0 -0
  43. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_server_status.rb +0 -0
  44. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_snapshot_config.rb +0 -0
  45. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_task.rb +0 -0
  46. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_vnc.rb +0 -0
  47. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/get_volume.rb +0 -0
  48. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_nodes.rb +0 -0
  49. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_servers.rb +0 -0
  50. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_snapshots.rb +0 -0
  51. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_storages.rb +0 -0
  52. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_tasks.rb +0 -0
  53. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/list_volumes.rb +0 -0
  54. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/log_task.rb +0 -0
  55. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/migrate_server.rb +0 -0
  56. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/move_disk.rb +0 -0
  57. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/move_volume.rb +0 -0
  58. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/next_vmid.rb +0 -0
  59. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/resize_container.rb +0 -0
  60. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/resize_server.rb +0 -0
  61. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/rollback_snapshot.rb +0 -0
  62. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/status_task.rb +0 -0
  63. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/stop_task.rb +0 -0
  64. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/template_server.rb +0 -0
  65. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/update_server.rb +0 -0
  66. data/lib/fog/{compute/proxmox → proxmox/compute}/requests/update_snapshot.rb +0 -0
  67. data/lib/fog/proxmox/core.rb +66 -57
  68. data/lib/fog/proxmox/hash.rb +2 -2
  69. data/lib/fog/proxmox/helpers/cpu_helper.rb +48 -9
  70. data/lib/fog/proxmox/helpers/disk_helper.rb +42 -22
  71. data/lib/fog/proxmox/helpers/nic_helper.rb +28 -20
  72. data/lib/fog/{identity/proxmox.rb → proxmox/identity.rb} +31 -17
  73. data/lib/fog/{identity/proxmox → proxmox/identity}/models/domain.rb +0 -0
  74. data/lib/fog/{identity/proxmox → proxmox/identity}/models/domain_type.rb +0 -0
  75. data/lib/fog/{identity/proxmox → proxmox/identity}/models/domains.rb +1 -1
  76. data/lib/fog/{identity/proxmox → proxmox/identity}/models/group.rb +4 -2
  77. data/lib/fog/{identity/proxmox → proxmox/identity}/models/groups.rb +1 -1
  78. data/lib/fog/{identity/proxmox → proxmox/identity}/models/permission.rb +0 -0
  79. data/lib/fog/{identity/proxmox → proxmox/identity}/models/permissions.rb +1 -1
  80. data/lib/fog/{identity/proxmox → proxmox/identity}/models/pool.rb +0 -0
  81. data/lib/fog/{identity/proxmox → proxmox/identity}/models/pools.rb +1 -1
  82. data/lib/fog/{identity/proxmox → proxmox/identity}/models/principal.rb +0 -0
  83. data/lib/fog/{identity/proxmox → proxmox/identity}/models/role.rb +0 -0
  84. data/lib/fog/{identity/proxmox → proxmox/identity}/models/roles.rb +1 -1
  85. data/lib/fog/proxmox/identity/models/token.rb +71 -0
  86. data/lib/fog/proxmox/identity/models/token_info.rb +41 -0
  87. data/lib/fog/proxmox/identity/models/tokens.rb +58 -0
  88. data/lib/fog/{identity/proxmox → proxmox/identity}/models/user.rb +25 -2
  89. data/lib/fog/{identity/proxmox → proxmox/identity}/models/users.rb +1 -1
  90. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/change_password.rb +0 -0
  91. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/check_permissions.rb +0 -0
  92. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/create_domain.rb +0 -0
  93. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/create_group.rb +0 -0
  94. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/create_pool.rb +0 -0
  95. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/create_role.rb +0 -0
  96. data/lib/fog/proxmox/identity/requests/create_token.rb +40 -0
  97. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/create_user.rb +0 -0
  98. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/delete_domain.rb +0 -0
  99. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/delete_group.rb +0 -0
  100. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/delete_pool.rb +0 -0
  101. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/delete_role.rb +0 -0
  102. data/lib/fog/proxmox/identity/requests/delete_token.rb +40 -0
  103. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/delete_user.rb +0 -0
  104. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/get_domain.rb +0 -0
  105. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/get_group.rb +0 -0
  106. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/get_pool.rb +0 -0
  107. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/get_role.rb +0 -0
  108. data/lib/fog/proxmox/identity/requests/get_token_info.rb +41 -0
  109. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/get_user.rb +0 -0
  110. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_domains.rb +0 -0
  111. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_groups.rb +0 -0
  112. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_permissions.rb +0 -0
  113. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_pools.rb +0 -0
  114. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_roles.rb +0 -0
  115. data/lib/fog/proxmox/identity/requests/list_tokens.rb +41 -0
  116. data/lib/fog/proxmox/identity/requests/list_user_permissions.rb +44 -0
  117. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/list_users.rb +0 -0
  118. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/read_version.rb +0 -0
  119. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_domain.rb +0 -0
  120. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_group.rb +0 -0
  121. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_permissions.rb +0 -0
  122. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_pool.rb +0 -0
  123. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_role.rb +0 -0
  124. data/lib/fog/proxmox/identity/requests/update_token.rb +41 -0
  125. data/lib/fog/{identity/proxmox → proxmox/identity}/requests/update_user.rb +0 -0
  126. data/lib/fog/{network/proxmox.rb → proxmox/network.rb} +21 -14
  127. data/lib/fog/{network/proxmox → proxmox/network}/models/network.rb +0 -0
  128. data/lib/fog/{network/proxmox → proxmox/network}/models/networks.rb +1 -1
  129. data/lib/fog/{network/proxmox → proxmox/network}/models/node.rb +1 -1
  130. data/lib/fog/{network/proxmox → proxmox/network}/models/nodes.rb +1 -1
  131. data/lib/fog/{network/proxmox → proxmox/network}/requests/create_network.rb +0 -0
  132. data/lib/fog/{network/proxmox → proxmox/network}/requests/delete_network.rb +0 -0
  133. data/lib/fog/{network/proxmox → proxmox/network}/requests/get_network.rb +0 -0
  134. data/lib/fog/{network/proxmox → proxmox/network}/requests/get_node.rb +0 -0
  135. data/lib/fog/{network/proxmox → proxmox/network}/requests/list_networks.rb +0 -0
  136. data/lib/fog/{network/proxmox → proxmox/network}/requests/list_nodes.rb +0 -0
  137. data/lib/fog/{network/proxmox → proxmox/network}/requests/power_node.rb +0 -0
  138. data/lib/fog/{network/proxmox → proxmox/network}/requests/update_network.rb +0 -0
  139. data/lib/fog/{storage/proxmox.rb → proxmox/storage.rb} +1 -1
  140. data/lib/fog/proxmox/version.rb +1 -1
  141. data/spec/compute_spec.rb +4 -4
  142. data/spec/fixtures/proxmox/compute/common_auth.yml +40 -0
  143. data/spec/fixtures/proxmox/compute/containers.yml +1752 -7568
  144. data/spec/fixtures/proxmox/compute/nodes.yml +24 -30
  145. data/spec/fixtures/proxmox/compute/servers.yml +5015 -10683
  146. data/spec/fixtures/proxmox/compute/snapshots.yml +479 -1719
  147. data/spec/fixtures/proxmox/compute/storages.yml +32 -40
  148. data/spec/fixtures/proxmox/compute/tasks.yml +118 -338
  149. data/spec/fixtures/proxmox/identity/auth.yml +10 -12
  150. data/spec/fixtures/proxmox/identity/auth_access_ticket.yml +77 -0
  151. data/spec/fixtures/proxmox/identity/auth_user_token.yml +77 -0
  152. data/spec/fixtures/proxmox/identity/common_auth.yml +40 -0
  153. data/spec/fixtures/proxmox/identity/domains.yml +145 -181
  154. data/spec/fixtures/proxmox/identity/groups.yml +72 -90
  155. data/spec/fixtures/proxmox/identity/permissions.yml +297 -189
  156. data/spec/fixtures/proxmox/identity/pools.yml +176 -421
  157. data/spec/fixtures/proxmox/identity/read_version.yml +7 -9
  158. data/spec/fixtures/proxmox/identity/roles.yml +69 -87
  159. data/spec/fixtures/proxmox/identity/tokens.yml +494 -0
  160. data/spec/fixtures/proxmox/identity/users.yml +149 -187
  161. data/spec/fixtures/proxmox/network/common_auth.yml +40 -0
  162. data/spec/fixtures/proxmox/network/networks.yml +99 -96
  163. data/spec/helpers/cpu_helper_spec.rb +27 -20
  164. data/spec/helpers/disk_helper_spec.rb +231 -187
  165. data/spec/helpers/nic_helper_spec.rb +113 -114
  166. data/spec/identity_spec.rb +110 -28
  167. data/spec/network_spec.rb +3 -3
  168. data/spec/proxmox_vcr.rb +24 -22
  169. data/spec/spec_helper.rb +4 -3
  170. metadata +155 -139
  171. data/spec/fixtures/proxmox/compute/identity_ticket.yml +0 -40
  172. data/spec/fixtures/proxmox/identity/identity_ticket.yml +0 -40
  173. data/spec/fixtures/proxmox/identity/renew.yml +0 -40
  174. data/spec/fixtures/proxmox/network/identity_ticket.yml +0 -40
@@ -17,7 +17,7 @@
17
17
  # You should have received a copy of the GNU General Public License
18
18
  # along with Fog::Proxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
- require 'fog/compute/proxmox/models/volume'
20
+ require 'fog/proxmox/compute/models/volume'
21
21
 
22
22
  module Fog
23
23
  module Proxmox
@@ -25,41 +25,55 @@ module Fog
25
25
  module Proxmox
26
26
  # Core module
27
27
  module Core
28
- attr_accessor :pve_ticket
29
- attr_reader :pve_csrftoken
30
- attr_reader :pve_username
31
- attr_reader :deadline
32
- attr_reader :principal
28
+ attr_accessor :token
29
+ attr_reader :auth_method
30
+ attr_reader :expires
31
+ attr_reader :current_user
32
+
33
+ def user_token?
34
+ @auth_token == 'user_token'
35
+ end
33
36
 
34
37
  # fallback
35
38
  def self.not_found_class
36
- Fog::Proxmox::Compute::NotFound
39
+ Fog::Proxmox::Core::NotFound
37
40
  end
38
41
 
39
- def initialize_identity(options)
40
- @principal = nil
41
- @pve_ticket = nil
42
- Fog::Proxmox::Variables.to_variables(self, options, 'pve')
43
- @pve_uri = URI.parse(@pve_url)
44
- missing_credentials = []
45
- missing_credentials << :pve_username unless @pve_username
42
+ def initialize(options = {})
43
+ setup(options)
44
+ authenticate
45
+ @auth_token.missing_credentials(options)
46
+ @connection = Fog::Core::Connection.new(@proxmox_url, @persistent, @connection_options)
47
+ end
46
48
 
47
- unless @pve_ticket
48
- missing_credentials << :pve_password unless @pve_password
49
+ def setup(options)
50
+ if options.respond_to?(:config_service?) && options.config_service?
51
+ configure(options)
52
+ return
49
53
  end
50
-
51
- raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}" unless missing_credentials.empty?
54
+ Fog::Proxmox::Variables.to_variables(self, options, 'proxmox')
55
+ @connection_options = options[:connection_options] || {}
56
+ @connection_options[:disable_proxy] = true if ENV['DISABLE_PROXY'] == 'true'
57
+ @connection_options[:ssl_verify_peer] = false if ENV['SSL_VERIFY_PEER'] == 'false'
58
+ @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
52
67
  end
53
68
 
54
69
  def credentials
55
70
  options = {
56
71
  provider: 'proxmox',
57
- pve_url: @pve_uri.to_s,
58
- pve_ticket: @pve_ticket,
59
- pve_csrftoken: @pve_csrftoken,
60
- pve_username: @pve_username
72
+ proxmox_auth_method: @auth_method,
73
+ proxmox_url: @proxmox_uri.to_s,
74
+ current_user: @current_user
61
75
  }
62
- pve_options.merge options
76
+ proxmox_options.merge options
63
77
  end
64
78
 
65
79
  def reload
@@ -68,16 +82,22 @@ module Fog
68
82
 
69
83
  private
70
84
 
85
+ def expired?
86
+ return false if @expires.nil?
87
+ return false if @expires == 0
88
+ return @expires - Time.now.utc.to_i < 60
89
+ end
90
+
71
91
  def request(params)
72
92
  retried = false
73
93
  begin
74
- response = @connection.request(params.merge(
75
- headers: headers(params[:method], params[:headers])
76
- ))
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] : {}, {}))
96
+ response = @connection.request(request_options)
77
97
  rescue Excon::Errors::Unauthorized => error
78
98
  # token expiration and token renewal possible
79
- if error.response.body != 'Bad username or password' && !retried
80
- authenticate
99
+ if !%w[Bad username or password, invalid token value!].include?(error.response.body) && @proxmox_can_reauthenticate && !retried
100
+ authenticate!
81
101
  retried = true
82
102
  retry
83
103
  # bad credentials or token renewal not possible
@@ -95,41 +115,30 @@ module Fog
95
115
  Fog::Proxmox::Json.get_data(response)
96
116
  end
97
117
 
98
- def headers(method, additional_headers)
99
- additional_headers ||= {}
100
- headers_hash = { 'Accept' => 'application/json' }
101
- # CSRF token is required to PUT, POST and DELETE http requests
102
- if %w[PUT POST DELETE].include? method
103
- headers_hash.store('CSRFPreventionToken', @pve_csrftoken)
104
- end
105
- # ticket must be present in cookie
106
- headers_hash.store('Cookie', "PVEAuthCookie=#{@pve_ticket}") if @pve_ticket
107
- headers_hash.merge additional_headers
108
- headers_hash
109
- end
110
-
111
- def pve_options
112
- Fog::Proxmox::Variables.to_hash(self, 'pve')
118
+ def proxmox_options
119
+ Fog::Proxmox::Variables.to_hash(self, 'proxmox')
113
120
  end
114
121
 
115
122
  def authenticate
116
- options = pve_options
117
- @pve_ticket = options[:pve_ticket]
118
- Fog::Proxmox.authenticate(options, @connection_options)
119
- @principal = Fog::Proxmox.credentials
120
- @pve_username = Fog::Proxmox.credentials[:username]
121
- @pve_ticket = Fog::Proxmox.credentials[:ticket]
122
- @pve_deadline = Fog::Proxmox.credentials[:deadline]
123
- @pve_csrftoken = Fog::Proxmox.credentials[:csrftoken]
124
-
125
- @host = @pve_uri.host
126
- @api_path = @pve_uri.path
127
- @api_path.sub!(%r{/$}, '')
128
- @port = @pve_uri.port
129
- @scheme = @pve_uri.scheme
130
-
123
+ if @proxmox_must_reauthenticate
124
+ @token = nil if @proxmox_must_reauthenticate
125
+ @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]
127
+ @token = @auth_token.token
128
+ @expires = @auth_token.expires
129
+ @proxmox_must_reauthenticate = false
130
+ else
131
+ @token = @proxmox_token
132
+ end
133
+ uri = URI.parse(@proxmox_url)
134
+ @path = uri.path
131
135
  true
132
136
  end
137
+
138
+ def authenticate!
139
+ @proxmox_must_reauthenticate = true
140
+ authenticate
141
+ end
133
142
  end
134
143
  end
135
144
  end
@@ -23,13 +23,13 @@ module Fog
23
23
  module Hash
24
24
 
25
25
  def self.stringify(hash)
26
- filtered = hash.reject { |_key,value| value.to_s.empty? }
26
+ filtered = hash.reject { |_key, value| value.nil? }
27
27
  a = filtered.to_a.collect { |item| item.join('=') }
28
28
  a.join(',')
29
29
  end
30
30
 
31
31
  def self.flatten(hash)
32
- filtered = hash.reject { |_key,value| value.to_s.empty? }
32
+ filtered = hash.reject { |_key, value| value.nil? }
33
33
  a = filtered.to_a.collect { |item| item.join(': ') }
34
34
  a.join(',')
35
35
  end
@@ -21,21 +21,60 @@ module Fog
21
21
  module Proxmox
22
22
  # module Cpu mixins
23
23
  module CpuHelper
24
- CPU_REGEXP = /(\bcputype=)?([\w-]+)[,]?(\bflags=)?(\+[\w-]+)?[;]?(\+[\w-]+)?/
25
- def self.extract(cpu,i)
26
- cpu ? CPU_REGEXP.match(cpu.to_s)[i] : ''
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' }
26
+ def self.flags
27
+ FLAGS
28
+ end
29
+
30
+ def self.extract(cpu, name)
31
+ captures_h = cpu ? CPU_REGEXP.match(cpu.to_s) : { cputype: '', flags: '' }
32
+ captures_h[name]
33
+ end
34
+
35
+ def self.extract_cputype(cpu)
36
+ extract(cpu, :cputype)
37
+ end
38
+
39
+ def self.extract_flags(cpu)
40
+ extract(cpu, :flags)
41
+ end
42
+
43
+ def self.flag_value(cpu, flag_key)
44
+ flag_value = '0'
45
+ raw_values = extract_flags(cpu).split(';').select { |flag| ['+' + flag_key, '-' + flag_key].include?(flag) }
46
+ unless raw_values.empty?
47
+ flag_value = raw_values[0].start_with?('+') ? '+1' : raw_values[0].start_with?('-') ? '-1' : '0'
48
+ end
49
+ flag_value
27
50
  end
28
51
 
29
- def self.extract_type(cpu)
30
- extract(cpu,2)
52
+ def self.hash_has_no_default_flag?(cpu_h, flag_name)
53
+ cpu_h.key?(flag_name) && ['-1', '+1'].include?(cpu_h[flag_name])
31
54
  end
32
55
 
33
- def self.has_pcid?(cpu)
34
- extract(cpu,5) == '+pcid'
56
+ def self.hash_flag(cpu_h, flag_name)
57
+ flag = ''
58
+ if cpu_h.key?(flag_name)
59
+ flag = '+' if cpu_h[flag_name] == '+1'
60
+ flag = '-' if cpu_h[flag_name] == '-1'
61
+ end
62
+ flag
35
63
  end
36
64
 
37
- def self.has_spectre?(cpu)
38
- extract(cpu,4) == '+spec-ctrl'
65
+ def self.flatten(cpu_h)
66
+ return '' unless cpu_h['cpu_type']
67
+
68
+ cpu_type = "cputype=#{cpu_h['cpu_type']}"
69
+ num_flags = 0
70
+ FLAGS.each_key { |flag_key| num_flags += 1 if hash_has_no_default_flag?(cpu_h, flag_key.to_s) }
71
+ 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) }
73
+ flags_with_no_default_value.each_with_index do |(flag_key, flag_value), index|
74
+ 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
+ cpu_type += ';' if num_flags > index + 1
76
+ end
77
+ cpu_type
39
78
  end
40
79
  end
41
80
  end
@@ -23,13 +23,15 @@ module Fog
23
23
  module Proxmox
24
24
  # module Disk mixins
25
25
  module DiskHelper
26
-
27
26
  DISKS_REGEXP = /^(scsi|sata|mp|rootfs|virtio|ide)(\d+){0,1}$/
28
27
  SERVER_DISK_REGEXP = /^(scsi|sata|virtio|ide)(\d+)$/
29
28
  MOUNT_POINT_REGEXP = /^(mp)(\d+)$/
30
29
  ROOTFS_REGEXP = /^(rootfs)$/
31
30
  CDROM_REGEXP = /^(.*)[,]{0,1}(media=cdrom)[,]{0,1}(.*)$/
31
+ TEMPLATE_REGEXP = /^(.*)(base-)(.*)$/
32
+ CLOUD_INIT_REGEXP = /^(.*)(cloudinit)(.*)$/
32
33
 
34
+ # Convert disk attributes hash into API Proxmox parameters string
33
35
  def self.flatten(disk)
34
36
  id = disk[:id]
35
37
  value = ''
@@ -42,12 +44,12 @@ module Fog
42
44
  value += 'none'
43
45
  end
44
46
  opts = disk[:options] if disk[:options]
45
- main_a = [:id,:volid,:storage,:size]
46
- opts = disk.reject { |key,_value| main_a.include? key } unless opts
47
+ main_a = [:id, :volid, :storage, :size]
48
+ opts ||= disk.reject { |key, _value| main_a.include? key }
47
49
  options = ''
48
50
  options += Fog::Proxmox::Hash.stringify(opts) if opts
49
- if id == 'ide2' && !self.cdrom?(options)
50
- options += ',' if !options.empty?
51
+ if id == 'ide2' && !cdrom?(options)
52
+ options += ',' unless options.empty?
51
53
  options += 'media=cdrom'
52
54
  end
53
55
  value += ',' if !options.empty? && !value.empty?
@@ -67,25 +69,26 @@ module Fog
67
69
  id.scan(/(\w+)(\d+)/).first
68
70
  end
69
71
 
72
+ # Convert API Proxmox parameter string into attribute hash value
70
73
  def self.extract_option(name, disk_value)
71
74
  values = disk_value.scan(/#{name}=(\w+)/)
72
75
  name_value = values.first if values
73
76
  name_value&.first
74
77
  end
75
78
 
79
+ # Convert API Proxmox volume/disk parameter string into volume/disk attributes hash value
76
80
  def self.extract_storage_volid_size(disk_value)
77
- #volid definition: <VOULME_ID>:=<STORAGE_ID>:<storage type dependent volume name>
81
+ # volid definition: <VOLUME_ID>:=<STORAGE_ID>:<storage type dependent volume name>
78
82
  values_a = disk_value.scan(/^(([\w-]+)[:]{0,1}([\w\/\.-]+))/)
79
83
  no_cdrom = !disk_value.match(CDROM_REGEXP)
80
84
  creation = disk_value.split(',')[0].match(/^(([\w-]+)[:]{1}([\d]+))$/)
81
85
  values = values_a.first if values_a
82
86
  if no_cdrom
87
+ storage = values[1]
83
88
  if creation
84
- storage = values[1]
85
89
  volid = nil
86
90
  size = values[2].to_i
87
91
  else
88
- storage = values[1]
89
92
  volid = values[0]
90
93
  size = extract_size(disk_value)
91
94
  end
@@ -98,16 +101,16 @@ module Fog
98
101
  end
99
102
 
100
103
  def self.to_bytes(size)
101
- val=size.match(/\d+(\w?)/)
102
- m=0
103
- case val[1]
104
- when "K" then m=1
105
- when "M" then m=2
106
- when "G" then m=3
107
- when "T" then m=4
108
- when "P" then m=5
104
+ val = size.match(/\d+(\w?)/)
105
+ m = 0
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
109
112
  end
110
- val[0].to_i*1024**m
113
+ val[0].to_i * 1024**m
111
114
  end
112
115
 
113
116
  def self.modulo_bytes(size)
@@ -115,20 +118,20 @@ module Fog
115
118
  end
116
119
 
117
120
  def self.to_human_bytes(size)
118
- units = ['Kb','Mb','Gb','Tb','Pb']
121
+ units = ['Kb', 'Mb', 'Gb', 'Tb', 'Pb']
119
122
  i = 0
120
123
  human_size = size.to_s + 'b'
121
124
  while i < 5 && size >= 1024
122
- size = self.modulo_bytes(size)
125
+ size = modulo_bytes(size)
123
126
  human_size = size.to_s + units[i]
124
- i+=1
127
+ i += 1
125
128
  end
126
129
  human_size
127
130
  end
128
131
 
129
132
  def self.extract_size(disk_value)
130
- size=extract_option('size', disk_value)
131
- size ? self.to_bytes(size) : "1G"
133
+ size = extract_option('size', disk_value)
134
+ size ? to_bytes(size) : "1G"
132
135
  end
133
136
 
134
137
  def self.disk?(id)
@@ -154,6 +157,23 @@ module Fog
154
157
  def self.container_disk?(id)
155
158
  rootfs?(id) || mount_point?(id)
156
159
  end
160
+
161
+ def self.template?(volid)
162
+ TEMPLATE_REGEXP.match(volid) ? true : false
163
+ end
164
+
165
+ def self.cloud_init?(volid)
166
+ CLOUD_INIT_REGEXP.match(volid) ? true : false
167
+ end
168
+
169
+ def self.of_type?(disk_h, vm_type)
170
+ id = disk_h['id'] if disk_h.key?('id')
171
+ id = disk_h[:id] if disk_h.key?(:id)
172
+ result = false
173
+ result = server_disk?(id) if vm_type == 'qemu'
174
+ result = container_disk?(id) if vm_type == 'lxc'
175
+ result
176
+ end
157
177
  end
158
178
  end
159
179
  end