foreman_fog_proxmox 0.19.1 → 0.20.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +61 -0
  3. data/app/helpers/proxmox_vm_attrs_helper.rb +13 -2
  4. data/app/helpers/proxmox_vm_cloudinit_helper.rb +1 -1
  5. data/app/helpers/proxmox_vm_config_helper.rb +1 -1
  6. data/app/helpers/proxmox_vm_efidisk_helper.rb +54 -0
  7. data/app/helpers/proxmox_vm_helper.rb +2 -0
  8. data/app/models/concerns/fog_extensions/proxmox/server.rb +5 -0
  9. data/app/models/foreman_fog_proxmox/proxmox_efidisks.rb +29 -0
  10. data/app/models/foreman_fog_proxmox/proxmox_images.rb +10 -3
  11. data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +10 -1
  12. data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +34 -16
  13. data/app/views/compute_resources_vms/show/_proxmox.html.erb +1 -0
  14. data/config/routes.rb +6 -0
  15. data/lib/foreman_fog_proxmox/engine.rb +4 -1
  16. data/lib/foreman_fog_proxmox/version.rb +1 -1
  17. data/package.json +3 -3
  18. data/test/functional/compute_resources_controller_test.rb +52 -4
  19. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +5 -0
  20. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +3 -0
  21. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +2 -0
  22. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb +5 -0
  23. data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +6 -0
  24. data/webpack/components/ProxmoxBiosContext.js +33 -0
  25. data/webpack/components/ProxmoxComputeSelectors.js +2 -2
  26. data/webpack/components/ProxmoxContainer/ProxmoxContainerNetwork.js +15 -14
  27. data/webpack/components/ProxmoxContainer/ProxmoxContainerOptions.js +86 -16
  28. data/webpack/components/ProxmoxContainer/ProxmoxContainerStorage.js +61 -21
  29. data/webpack/components/ProxmoxServer/ProxmoxServerNetwork.js +3 -3
  30. data/webpack/components/ProxmoxServer/ProxmoxServerOptions.js +13 -1
  31. data/webpack/components/ProxmoxServer/ProxmoxServerStorage.js +150 -22
  32. data/webpack/components/ProxmoxServer/components/CDRom.js +106 -31
  33. data/webpack/components/ProxmoxServer/components/EFIDisk.js +153 -0
  34. data/webpack/components/ProxmoxStoragesUtils.js +14 -10
  35. data/webpack/components/ProxmoxVmType.js +201 -117
  36. data/webpack/components/ProxmoxVmUtils.js +11 -1
  37. data/webpack/components/__tests__/ProxmoxComputeSelectors.test.js +40 -0
  38. data/webpack/components/__tests__/ProxmoxVmType.test.js +54 -0
  39. data/webpack/components/__tests__/ProxmoxVmUtils.test.js +8 -0
  40. data/webpack/components/common/FormInputs.js +5 -1
  41. data/webpack/components/hooks/useVolumes.js +65 -0
  42. data/webpack/global_test_setup.js +11 -0
  43. data/webpack/test_setup.js +13 -0
  44. metadata +12 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d33ba66a9b7acebd9d90dcb30dd674ce56b6dc9f163be3058e0638afdcb9d469
4
- data.tar.gz: 0dd4eea9468557e5d88f1b30acab223e17a900657a5a3e7ab609fabc4265ae8b
3
+ metadata.gz: b9245dbe8083dfb0dc96195feaafd9aed1aa448956c2fc497ec5c2c4333bfd2e
4
+ data.tar.gz: 80631b0e56427938aef3a14a08d47f61a0355d9e1928791d362fdf1ba8fcd3bc
5
5
  SHA512:
6
- metadata.gz: 879a29517ecaa8129d2253959819fae1b4e203c85b1e28fce114e08a8c248d991ccd125bbb9b9ac49c8e07621b9754dbf5ffdfdcf320edb7019074bddca65b4c
7
- data.tar.gz: 4f2a0640189b83fe993d46ded2eb8106fdc86ec69a1e9693bf0830b7cd9486f2d997adcb8265d1f70933cc1d2378831389f50d8ff853914f45ef083380cda32e
6
+ metadata.gz: 2c0d7df8aa1b9fe9e7efd370e3356abf6331c93ee291d0b3d8698cfc413b50383ef190ae62fe69076a83f42426cdeca1c83649c64558ec956d92e330462bf527
7
+ data.tar.gz: c920739b5e891307d620234cd667c481b1ab3a5fd6913b4847d87e9d344340a2cd787ba069959d7429b5847a0f30782cee907df399e98ce3aecfecc74ac290cc
@@ -78,8 +78,69 @@ module ForemanFogProxmox
78
78
  end
79
79
  end
80
80
 
81
+ # GET foreman_fog_proxmox/volumes/:compute_resource_id/:node_id/:storage
82
+ def volumes_by_node_and_storage
83
+ cr = ComputeResource.find(params[:compute_resource_id])
84
+ node_id = params[:node_id]
85
+ storage = params[:storage]
86
+
87
+ vols = cr.storages(node_id).find { |s| s.storage == storage }&.volumes || []
88
+
89
+ render json: Array(vols).map { |v|
90
+ h = v.respond_to?(:as_json) ? v.as_json : v
91
+ { volid: (h[:volid] || h['volid']), content: (h[:content] || h['content']) }
92
+ }
93
+ end
94
+
95
+ # GET foreman_fog_proxmox/metadata/:compute_resource_id
96
+ def metadata
97
+ cr = ComputeResource.find(params[:compute_resource_id])
98
+
99
+ render json: {
100
+ nodes: extract_nodes(cr),
101
+ pools: extract_pools(cr),
102
+ storages: extract_storages(cr),
103
+ bridges: extract_bridges(cr),
104
+ }
105
+ end
106
+
81
107
  private
82
108
 
109
+ def extract_nodes(compute_resource)
110
+ Array(compute_resource.nodes).map { |n| { node: n.node } }
111
+ end
112
+
113
+ def extract_pools(compute_resource)
114
+ Array(compute_resource.pools).map do |p|
115
+ poolid = p.respond_to?(:poolid) ? p.poolid : (p[:poolid] || p['poolid'])
116
+ { poolid: poolid }
117
+ end
118
+ end
119
+
120
+ def extract_storages(compute_resource)
121
+ Array(compute_resource.storages).map do |s|
122
+ h = s.respond_to?(:as_json) ? s.as_json : s
123
+ {
124
+ storage: (h[:storage] || h['storage']),
125
+ node_id: (h[:node_id] || h['node_id']),
126
+ content: (h[:content] || h['content']),
127
+ avail: (h[:avail] || h['avail']),
128
+ used: (h[:used] || h['used']),
129
+ total: (h[:total] || h['total']),
130
+ }
131
+ end
132
+ end
133
+
134
+ def extract_bridges(compute_resource)
135
+ Array(compute_resource.bridges).map do |b|
136
+ h = b.respond_to?(:as_json) ? b.as_json : b
137
+ {
138
+ node_id: (h[:node_id] || h['node_id']),
139
+ iface: (h[:iface] || h['iface']),
140
+ }
141
+ end
142
+ end
143
+
83
144
  def load_compute_resource(compute_resource_id)
84
145
  ComputeResource.find(compute_resource_id)
85
146
  end
@@ -28,7 +28,7 @@ module ProxmoxVMAttrsHelper
28
28
  def object_to_attributes_hash(vms, from_profile, start_checked)
29
29
  param_scope = from_profile ? "compute_attribute[vm_attrs]" : "host[compute_attributes]"
30
30
  vm_h = ActiveSupport::HashWithIndifferentAccess.new
31
- keys = [:vmid, :node_id, :type, :pool]
31
+ keys = [:vmid, :node_id, :type, :pool, :efidisk]
32
32
  main = vms.attributes.select { |key, _value| keys.include? key }
33
33
  vms.config.all_attributes.each do |key, value|
34
34
  camel_key = key.to_s.include?('_') ? snake_to_camel(key.to_s).to_sym : key
@@ -42,7 +42,9 @@ module ProxmoxVMAttrsHelper
42
42
  vm_h.merge!(additional_attrs(vms, param_scope, start_checked))
43
43
  vm_h[:interfaces] = network_attrs(param_scope, vms.interfaces)
44
44
  vm_h[:disks] = volumes_attrs(param_scope, vms.volumes)
45
- vm_h.merge(cpu_flags_attrs(param_scope, vms.config))
45
+ vm_h[:efidisk] = efidisk_attrs(param_scope, vms.efidisk) if vms.efidisk.present?
46
+ vm_h.merge!(cpu_flags_attrs(param_scope, vms.config))
47
+ vm_h
46
48
  end
47
49
 
48
50
  def cpu_flags_attrs(param_scope, config)
@@ -53,6 +55,15 @@ module ProxmoxVMAttrsHelper
53
55
  flag_attrs
54
56
  end
55
57
 
58
+ def efidisk_attrs(param_scope, efidisk)
59
+ attrs = ActiveSupport::HashWithIndifferentAccess.new
60
+ keys = ['id', 'volid', 'size', 'storage', 'format', 'efitype', 'pre_enrolled_keys']
61
+ keys.each do |key|
62
+ attrs[key] = { :name => "#{param_scope}[efidisk_attributes][#{key}]", :value => efidisk.public_send(key) }
63
+ end
64
+ attrs
65
+ end
66
+
56
67
  def volumes_attrs(param_scope, volumes)
57
68
  vol_attrs = []
58
69
  volumes.each_with_index do |vol, id|
@@ -48,7 +48,7 @@ module ProxmoxVMCloudinitHelper
48
48
  wd = create_temp_directory(ssh)
49
49
 
50
50
  configs.each do |config|
51
- config_file = ssh.run(%(echo '#{config[1]}' >> "#{wd}/#{config[0]}"))
51
+ config_file = ssh.run("cat <<'EOF' > '#{wd}/#{config[0]}'\n#{config[1]}\nEOF")
52
52
  unless config_file.first.status.zero?
53
53
  delete_temp_dir(ssh, wd)
54
54
  raise ::Foreman::Exception, "Failed to create file #{config[0]}: #{config_file.first.stdout}"
@@ -40,7 +40,7 @@ module ProxmoxVMConfigHelper
40
40
  end
41
41
 
42
42
  def general_a(type)
43
- general_a = ['node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes', 'image_id']
43
+ general_a = ['node_id', 'type', 'config_attributes', 'efidisk_attributes', 'volumes_attributes', 'interfaces_attributes', 'image_id']
44
44
  general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create']
45
45
  general_a += ['name'] if type == 'lxc'
46
46
  general_a
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2026 ATIX AG
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require 'fog/proxmox/helpers/efidisk_helper'
21
+ require 'foreman_fog_proxmox/value'
22
+ require 'foreman_fog_proxmox/hash_collection'
23
+
24
+ # Convert a foreman form server hash into a fog-proxmox server attributes hash
25
+ module ProxmoxVMEfidiskHelper
26
+ def parsed_typed_efidisk(args, type, parsed_vm)
27
+ attrs = args['efidisk_attributes']
28
+
29
+ # we need the vmid to create the volid if not present
30
+ vmid = args['vmid'] if args.key?('vmid')
31
+ # fallback to a dummy vmid for new vms
32
+ vmid ||= 'no_vmid_yet'
33
+
34
+ logger.debug("parsed_typed_efidisk(#{type}): attrs=#{attrs} with #{vmid}")
35
+ unless ForemanFogProxmox::Value.empty?(args['efidisk_attributes'])
36
+ efidisk = parse_typed_efidisk(attrs, vmid, type)
37
+ logger.debug("parsed_typed_efidisk(#{type}): efidisk=#{efidisk}")
38
+ parsed_vm = parsed_vm.merge(efidisk)
39
+ end
40
+ parsed_vm
41
+ end
42
+
43
+ def parse_typed_efidisk(args, _vmid, _type)
44
+ logger.debug(format(_('parse_efidisk(): args=%<args>s'), args: args))
45
+ efidisk = {}
46
+ efidisk[:id] = args['id'] if args.key?('id')
47
+ efidisk[:volid] = args['volid']
48
+ efidisk[:size] = args['size'].to_i if args.key?('size') && !args['size'].empty?
49
+ efidisk[:format] = args['format']
50
+ efidisk[:efitype] = args['efitype'] if args.key?('efitype') && !args['efitype'].empty?
51
+ efidisk[:pre_enrolled_keys] = args['pre_enrolled_keys'] if args.key?('pre_enrolled_keys')
52
+ Fog::Proxmox::EfidiskHelper.flatten(efidisk)
53
+ end
54
+ end
@@ -26,6 +26,7 @@ module ProxmoxVMHelper
26
26
  include ProxmoxVMVolumesHelper
27
27
  include ProxmoxVMConfigHelper
28
28
  include ProxmoxVMOsTemplateHelper
29
+ include ProxmoxVMEfidiskHelper
29
30
 
30
31
  def vm_collection(type)
31
32
  collection = :servers
@@ -42,6 +43,7 @@ module ProxmoxVMHelper
42
43
 
43
44
  logger.debug("parse_typed_vm(#{type}): args=#{args}")
44
45
  parsed_vm = parsed_typed_config(args, type)
46
+ parsed_vm = parsed_typed_efidisk(args, type, parsed_vm)
45
47
  parsed_vm = parsed_typed_interfaces(args, type, parsed_vm)
46
48
  parsed_vm = parsed_typed_volumes(args, type, parsed_vm)
47
49
  logger.debug("parse_typed_vm(#{type}): parsed_vm=#{parsed_vm}")
@@ -44,6 +44,10 @@ module FogExtensions
44
44
  reboot
45
45
  end
46
46
 
47
+ def poweroff
48
+ stop
49
+ end
50
+
47
51
  def mac
48
52
  config.mac_addresses.first
49
53
  end
@@ -81,6 +85,7 @@ module FogExtensions
81
85
  config.disks.collect(&:to_s)
82
86
  end
83
87
 
88
+ delegate :efidisk, to: :config
84
89
  delegate :vga, to: :config
85
90
  delegate :pool, to: :config
86
91
  delegate :cloud_init?, to: :config
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 ATIX AG
4
+
5
+ # This file is part of ForemanFogProxmox.
6
+
7
+ # ForemanFogProxmox is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+
12
+ # ForemanFogProxmox is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ module ForemanFogProxmox
21
+ module ProxmoxEfidisks
22
+ include ProxmoxVMHelper
23
+
24
+ def delete_efidisk(vmobj)
25
+ logger.info("vm #{vmobj.identity} delete efidisk0")
26
+ vmobj.detach('efidisk0')
27
+ end
28
+ end
29
+ end
@@ -48,11 +48,18 @@ module ForemanFogProxmox
48
48
  volumes = []
49
49
  nodes.each do |node|
50
50
  storages(node.node).each do |storage|
51
- # fetches volumes of QEMU servers for images
52
- volumes += storage.volumes.list_by_content_type('images')
51
+ # Skip disabled storages (enabled == 0 or nil)
52
+ unless storage.enabled.to_i == 1
53
+ logger.warn("Skipping disabled storage #{storage.identity} on #{node.node}")
54
+ next
55
+ end
53
56
 
54
- # fetches volumes of KVM containers for images
57
+ # Fetch QEMU and LXC template images
58
+ volumes += storage.volumes.list_by_content_type('images')
55
59
  volumes += storage.volumes.list_by_content_type('rootdir')
60
+ rescue StandardError => e
61
+ logger.error("Failed to fetch volumes for storage #{storage.identity} on #{node.node}: #{e.message}")
62
+ next
56
63
  end
57
64
  end
58
65
  # for creating image, only list volumes which are templated
@@ -22,6 +22,7 @@ require 'foreman_fog_proxmox/hash_collection'
22
22
  module ForemanFogProxmox
23
23
  module ProxmoxVMCommands
24
24
  include ProxmoxVolumes
25
+ include ProxmoxEfidisks
25
26
  include ProxmoxPools
26
27
  include ProxmoxVMHelper
27
28
 
@@ -72,7 +73,7 @@ module ForemanFogProxmox
72
73
  vm = find_vm_by_uuid(uuid)
73
74
  return true if vm.nil?
74
75
  vm.stop if vm.ready?
75
- vm.destroy
76
+ vm.ha&.dig("managed").to_i == 1 ? vm.destroy(query: { purge: 1 }) : vm.destroy
76
77
  rescue ActiveRecord::RecordNotFound
77
78
  # if the VM does not exists, we don't really care.
78
79
  true
@@ -109,9 +110,17 @@ module ForemanFogProxmox
109
110
  ['volumes_attributes']).merge(type: vm.type), vm.type
110
111
  )
111
112
  config_attributes = compute_config_attributes(parsed_attr)
113
+
112
114
  volumes_attributes = new_attributes['volumes_attributes']
113
115
  logger.debug("save_vm(#{uuid}) volumes_attributes=#{volumes_attributes}")
114
116
  volumes_attributes&.each_value { |volume_attributes| save_volume(vm, volume_attributes) }
117
+
118
+ efidisk_attributes = new_attributes['efidisk_attributes']
119
+ if vm.config.efidisk.present? && efidisk_attributes.empty?
120
+ logger.debug("Removing efidisk from VM #{vm}")
121
+ delete_efidisk(vm)
122
+ end
123
+
115
124
  vm.update(config_attributes[:config_attributes])
116
125
  poolid = new_attributes['pool'] if new_attributes.key?('pool')
117
126
  update_pool(vm, poolid) if poolid
@@ -14,25 +14,43 @@ GNU General Public License for more details.
14
14
 
15
15
  You should have received a copy of the GNU General Public License
16
16
  along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
17
- <% nodes = compute_resource.nodes %>
17
+
18
18
  <% unless local_assigns[:hide_image] && !new_vm %>
19
- <%
20
- arch ||= nil ; os ||= nil
21
- images = possible_images(compute_resource, arch, os)
22
- -%>
23
- <div id='image_selection'>
24
- <%= select_f f, :image_id, images, :uuid, :name, { :include_blank => true },
25
- :disabled => true,
26
- :help_inline => :indicator,
27
- :class => ("without_select2 #{'hide' if from_profile}"),
28
- :label => _('Image'),
29
- :no_label => from_profile,
30
- :label_size => "col-md-2" %>
31
- </div>
19
+ <%
20
+ arch ||= nil ; os ||= nil
21
+ images = possible_images(compute_resource, arch, os)
22
+ -%>
23
+ <div id='image_selection'>
24
+ <%= select_f f, :image_id, images, :uuid, :name, { include_blank: true },
25
+ disabled: true,
26
+ help_inline: :indicator,
27
+ class: ("without_select2 #{'hide' if from_profile}"),
28
+ label: _('Image'),
29
+ no_label: from_profile,
30
+ label_size: "col-md-2" %>
31
+ </div>
32
32
  <% end %>
33
+
33
34
  <% untemplatable = new_vm || f.object.templated? %>
34
- <% checked = params[:host] && params[:host][:compute_attributes] && params[:host][:compute_attributes][:start_after_create] || '1' %>
35
+ <% checked = (params.dig(:host, :compute_attributes, :start_after_create) || '1') %>
36
+
35
37
  <% content_for(:javascripts) do %>
36
38
  <%= webpacked_plugins_js_for :foreman_fog_proxmox %>
37
39
  <% end %>
38
- <%= react_component('ProxmoxVmType', { vmAttrs: object_to_attributes_hash(f.object, from_profile, checked), nodes: nodes.as_json, images: images.as_json, pools: compute_resource.pools.as_json, storages: compute_resource.storages.as_json, fromProfile: from_profile, newVm: new_vm, bridges: compute_resource.bridges.as_json, untemplatable: untemplatable }) %>
40
+
41
+ <%
42
+ vm_attrs = object_to_attributes_hash(f.object, from_profile, checked)
43
+
44
+ props = {
45
+ vmAttrs: vm_attrs,
46
+ computeResourceId: compute_resource.id,
47
+ propsLoaded: false,
48
+ fromProfile: from_profile,
49
+ newVm: new_vm,
50
+ untemplatable: untemplatable,
51
+ registerComp: local_assigns[:registerComp] || false,
52
+ images: (defined?(images) && images ? images.as_json : [])
53
+ }
54
+ %>
55
+
56
+ <%= react_component('ProxmoxVmType', props) %>
@@ -38,6 +38,7 @@ along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>. %>
38
38
  <%= prop :vmid %>
39
39
  <%= prop :description %>
40
40
  <%= prop :disks %>
41
+ <%= prop :efidisk, "EFI-Disk" %>
41
42
  <%= prop :nics %>
42
43
  <% end %>
43
44
  </table>
data/config/routes.rb CHANGED
@@ -30,5 +30,11 @@ Rails.application.routes.draw do
30
30
  match 'isostorages/:compute_resource_id/:node_id', :to => 'compute_resources#iso_storages_by_id_and_node',
31
31
  :via => 'get'
32
32
  match 'bridges/:compute_resource_id/:node_id', :to => 'compute_resources#bridges_by_id_and_node', :via => 'get'
33
+ match 'volumes/:compute_resource_id/:node_id/:storage',
34
+ :to => 'compute_resources#volumes_by_node_and_storage',
35
+ :via => 'get'
36
+ match 'metadata/:compute_resource_id',
37
+ :to => 'compute_resources#metadata',
38
+ :via => 'get'
33
39
  end
34
40
  end
@@ -49,7 +49,9 @@ module ForemanFogProxmox
49
49
  :isos_by_id_and_node,
50
50
  :storages_by_id_and_node,
51
51
  :iso_storages_by_id_and_node,
52
- :bridges_by_id_and_node] }
52
+ :bridges_by_id_and_node,
53
+ :volumes_by_node_and_storage,
54
+ :metadata] }
53
55
  end
54
56
  end
55
57
  end
@@ -92,6 +94,7 @@ module ForemanFogProxmox
92
94
  require 'fog/proxmox/compute/models/server'
93
95
  require 'fog/proxmox/compute/models/server_config'
94
96
  require 'fog/proxmox/compute/models/disk'
97
+ require 'fog/proxmox/compute/models/efidisk'
95
98
  require 'fog/proxmox/compute/models/interface'
96
99
  require 'fog/proxmox/compute/models/volume'
97
100
  require 'fog/proxmox/compute/models/node'
@@ -18,5 +18,5 @@
18
18
  # along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module ForemanFogProxmox
21
- VERSION = '0.19.1'
21
+ VERSION = '0.20.0'
22
22
  end
data/package.json CHANGED
@@ -5,9 +5,9 @@
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "lint": "tfm-lint --plugin -d webpack",
8
- "test": "tfm-test --plugin --passWithNoTests",
9
- "test:watch": "tfm-test --plugin --watchAll",
10
- "test:current": "tfm-test --plugin --watch",
8
+ "test": "tfm-test --config jest.config.js",
9
+ "test:watch": "tfm-test --config jest.config.js --plugin --watchAll",
10
+ "test:current": "tfm-test --config jest.config.js --plugin --watch",
11
11
  "publish-coverage": "tfm-publish-coverage",
12
12
  "stories": "tfm-stories --plugin",
13
13
  "stories:build": "tfm-build-stories --plugin",
@@ -20,31 +20,79 @@ require 'test_plugin_helper'
20
20
 
21
21
  module ForemanFogProxmox
22
22
  class ComputeResourcesControllerTest < ActionController::TestCase
23
+ tests ForemanFogProxmox::ComputeResourcesController
24
+
25
+ setup do
26
+ @compute_resource = FactoryBot.create(:proxmox_cr)
27
+ mock_storage = mock('storage')
28
+ mock_storage.stubs(:storage).returns('local')
29
+ mock_storage.stubs(:volumes).returns([])
30
+
31
+ @compute_resource.stubs(:images_by_storage).returns([])
32
+ @compute_resource.stubs(:nodes).returns([])
33
+ @compute_resource.stubs(:pools).returns([])
34
+ @compute_resource.stubs(:storages).with('proxmox').returns([mock_storage])
35
+ @compute_resource.stubs(:storages).with('proxmox', 'vztmpl').returns([])
36
+ @compute_resource.stubs(:storages).with('proxmox', 'iso').returns([])
37
+ @compute_resource.stubs(:storages).with(nil).returns([])
38
+ @compute_resource.stubs(:bridges).returns([])
39
+
40
+ # Stub ComputeResource.find to return our stubbed instance
41
+ ComputeResource.stubs(:find).with(@compute_resource.id).returns(@compute_resource)
42
+ ComputeResource.stubs(:find).with(@compute_resource.id.to_s).returns(@compute_resource)
43
+ end
44
+
23
45
  test 'should get isos by node and storage' do
24
46
  get :isos_by_id_and_node_and_storage,
25
- params: { :compute_resource_id => 1, :node_id => 'proxmox', :storage => 'local' }
47
+ params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' }
26
48
  assert_response :found
27
49
  show_response = @response.body
28
50
  assert_not show_response.empty?
29
51
  end
30
52
  test 'should get ostemplates by node and storage' do
31
53
  get :ostemplates_by_id_and_node_and_storage,
32
- params: { :compute_resource_id => 1, :node_id => 'proxmox', :storage => 'local' }
54
+ params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' }
33
55
  assert_response :found
34
56
  show_response = @response.body
35
57
  assert_not show_response.empty?
36
58
  end
37
59
  test 'should get isos by node' do
38
- get :isos_by_id_and_node, params: { :compute_resource_id => 1, :node_id => 'proxmox' }
60
+ get :isos_by_id_and_node, params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox' }
39
61
  assert_response :found
40
62
  show_response = @response.body
41
63
  assert_not show_response.empty?
42
64
  end
43
65
  test 'should get ostemplates by node' do
44
- get :ostemplates_by_id_and_node, params: { :compute_resource_id => 1, :node_id => 'proxmox' }
66
+ get :ostemplates_by_id_and_node, params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox' }
45
67
  assert_response :found
46
68
  show_response = @response.body
47
69
  assert_not show_response.empty?
48
70
  end
71
+ test 'should get volumes by node and storage' do
72
+ get :volumes_by_node_and_storage,
73
+ params: { :compute_resource_id => @compute_resource.id, :node_id => 'proxmox', :storage => 'local' },
74
+ session: set_session_user
75
+ assert_response :success
76
+ show_response = @response.body
77
+ assert_not show_response.empty?
78
+ json_response = JSON.parse(show_response)
79
+ assert_instance_of Array, json_response
80
+ end
81
+ test 'should get metadata' do
82
+ get :metadata, params: { :compute_resource_id => @compute_resource.id }, session: set_session_user
83
+ assert_response :success
84
+ show_response = @response.body
85
+ assert_not show_response.empty?
86
+ json_response = JSON.parse(show_response)
87
+ assert_instance_of Hash, json_response
88
+ assert json_response.key?('nodes')
89
+ assert json_response.key?('pools')
90
+ assert json_response.key?('storages')
91
+ assert json_response.key?('bridges')
92
+ assert_instance_of Array, json_response['nodes']
93
+ assert_instance_of Array, json_response['pools']
94
+ assert_instance_of Array, json_response['storages']
95
+ assert_instance_of Array, json_response['bridges']
96
+ end
49
97
  end
50
98
  end
@@ -39,6 +39,7 @@ module ForemanFogProxmox
39
39
  uuid = '100'
40
40
  config = mock('config')
41
41
  config.stubs(:attributes).returns(:cores => '')
42
+ config.stubs(:efidisk).returns(nil)
42
43
  vm = mock('vm')
43
44
  vm.stubs(:config).returns(config)
44
45
  vm.stubs(:container?).returns(true)
@@ -59,6 +60,7 @@ module ForemanFogProxmox
59
60
  uuid = '100'
60
61
  config = mock('config')
61
62
  config.stubs(:attributes).returns(:cores => '')
63
+ config.stubs(:efidisk).returns(nil)
62
64
  vm = mock('vm')
63
65
  vm.stubs(:config).returns(config)
64
66
  vm.stubs(:container?).returns(true)
@@ -87,6 +89,7 @@ module ForemanFogProxmox
87
89
  disk.stubs(:id).returns('mp0')
88
90
  disks.stubs(:get).returns
89
91
  config.stubs(:disks).returns(disks)
92
+ config.stubs(:efidisk).returns(nil)
90
93
  config.stubs(:attributes).returns(:cores => '')
91
94
  vm = mock('vm')
92
95
  vm.stubs(:identity).returns(uuid)
@@ -148,6 +151,7 @@ module ForemanFogProxmox
148
151
  disk.stubs(:attributes).returns(id: 'rootfs', storage: 'local-lvm', size: '1')
149
152
  disks.stubs(:get).returns(disk)
150
153
  config.stubs(:disks).returns(disks)
154
+ config.stubs(:efidisk).returns(nil)
151
155
  config.stubs(:attributes).returns(:cores => '')
152
156
  vm = mock('vm')
153
157
  vm.stubs(:identity).returns(uuid)
@@ -207,6 +211,7 @@ module ForemanFogProxmox
207
211
  disk.stubs(:attributes).returns(id: 'mp0', storage: 'local-lvm', size: '1', volid: 'local-lvm:vm-100-disk-0')
208
212
  disks.stubs(:get).returns(disk)
209
213
  config.stubs(:disks).returns(disks)
214
+ config.stubs(:efidisk).returns(nil)
210
215
  config.stubs(:attributes).returns(:cores => '')
211
216
  vm = mock('vm')
212
217
  vm.stubs(:identity).returns(uuid)
@@ -48,6 +48,7 @@ module ForemanFogProxmox
48
48
  disk.stubs(:mount_point?).returns(false)
49
49
  disks.stubs(:get).returns
50
50
  config.stubs(:disks).returns(disks)
51
+ config.stubs(:efidisk).returns(nil)
51
52
  config.stubs(:attributes).returns(:cores => '')
52
53
  vm = mock('vm')
53
54
  vm.stubs(:identity).returns(uuid)
@@ -104,6 +105,7 @@ module ForemanFogProxmox
104
105
  disk.stubs(:id).returns('ide2')
105
106
  disks.stubs(:get).returns(disk)
106
107
  config.stubs(:disks).returns(disks)
108
+ config.stubs(:efidisk).returns(nil)
107
109
  config.stubs(:attributes).returns(:cores => '1', :cpulimit => '1')
108
110
  vm = mock('vm')
109
111
  vm.stubs(:identity).returns(uuid)
@@ -159,6 +161,7 @@ module ForemanFogProxmox
159
161
  disk.stubs(:attributes).returns(id: 'ide2', storage: 'local-lvm', volid: 'local-lvm:vm-100-disk-0', size: '1')
160
162
  disks.stubs(:get).returns(disk)
161
163
  config.stubs(:disks).returns(disks)
164
+ config.stubs(:efidisk).returns(nil)
162
165
  config.stubs(:attributes).returns(:cores => '')
163
166
  vm = mock('vm')
164
167
  vm.stubs(:identity).returns(uuid)
@@ -44,6 +44,7 @@ module ForemanFogProxmox
44
44
  disk.stubs(:id).returns('ide0')
45
45
  disks.stubs(:get).returns
46
46
  config.stubs(:disks).returns(disks)
47
+ config.stubs(:efidisk).returns(nil)
47
48
  config.stubs(:attributes).returns(:cores => '')
48
49
  vm = mock('vm')
49
50
  vm.stubs(:identity).returns(uuid)
@@ -96,6 +97,7 @@ module ForemanFogProxmox
96
97
  disk.stubs(:cloud_init?).returns(true)
97
98
  disks.stubs(:get).returns(disk)
98
99
  config.stubs(:disks).returns(disks)
100
+ config.stubs(:efidisk).returns(nil)
99
101
  config.stubs(:attributes).returns(:cores => '1')
100
102
  vm = mock('vm')
101
103
  vm.stubs(:identity).returns(uuid)
@@ -50,6 +50,7 @@ module ForemanFogProxmox
50
50
  disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: '1')
51
51
  disks.stubs(:get).returns
52
52
  config.stubs(:disks).returns(disks)
53
+ config.stubs(:efidisk).returns(nil)
53
54
  config.stubs(:attributes).returns(:cores => '')
54
55
  vm = mock('vm')
55
56
  vm.stubs(:identity).returns(uuid)
@@ -101,6 +102,7 @@ module ForemanFogProxmox
101
102
  disk.stubs(:id).returns('virtio0')
102
103
  disks.stubs(:get).returns(disk)
103
104
  config.stubs(:disks).returns(disks)
105
+ config.stubs(:efidisk).returns(nil)
104
106
  config.stubs(:attributes).returns(:cores => '')
105
107
  vm = mock('vm')
106
108
  vm.stubs(:identity).returns(uuid)
@@ -157,6 +159,7 @@ module ForemanFogProxmox
157
159
  disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: 1)
158
160
  disks.stubs(:get).returns(disk)
159
161
  config.stubs(:disks).returns(disks)
162
+ config.stubs(:efidisk).returns(nil)
160
163
  config.stubs(:attributes).returns(:cores => '')
161
164
  vm = mock('vm')
162
165
  vm.stubs(:identity).returns(uuid)
@@ -264,6 +267,7 @@ module ForemanFogProxmox
264
267
  disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', size: '1', volid: 'local-lvm:vm-100-disk-0')
265
268
  disks.stubs(:get).returns(disk)
266
269
  config.stubs(:disks).returns(disks)
270
+ config.stubs(:efidisk).returns(nil)
267
271
  config.stubs(:attributes).returns(:cores => '')
268
272
  vm = mock('vm')
269
273
  vm.stubs(:identity).returns(uuid)
@@ -318,6 +322,7 @@ module ForemanFogProxmox
318
322
  disk.stubs(:attributes).returns(id: 'scsi0', storage: 'local-lvm', volid: 'local-lvm:vm-100-disk-0', size: '1')
319
323
  disks.stubs(:get).returns(disk)
320
324
  config.stubs(:disks).returns(disks)
325
+ config.stubs(:efidisk).returns(nil)
321
326
  config.stubs(:attributes).returns(:cores => '')
322
327
  vm = mock('vm')
323
328
  vm.stubs(:identity).returns(uuid)