foreman_fog_proxmox 0.13.4 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +63 -52
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_compute_resource.js +0 -2
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm.js +0 -1
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_vm_server.js +0 -2
- data/app/assets/javascripts/foreman_fog_proxmox/proxmox_volume_cloudinit.js +0 -1
- data/app/controllers/concerns/foreman_fog_proxmox/compute_resources_vms_controller.rb +17 -7
- data/app/controllers/concerns/foreman_fog_proxmox/controller/parameters/compute_resource.rb +1 -1
- data/app/controllers/concerns/foreman_fog_proxmox/hosts_controller.rb +58 -0
- data/app/controllers/foreman_fog_proxmox/compute_resources_controller.rb +6 -3
- data/app/helpers/proxmox_compute_controllers_helper.rb +2 -1
- data/app/helpers/proxmox_compute_resources_helper.rb +3 -3
- data/app/helpers/proxmox_compute_resources_vms_helper.rb +16 -7
- data/app/helpers/proxmox_form_helper.rb +10 -6
- data/app/helpers/proxmox_vm_config_helper.rb +16 -25
- data/app/helpers/proxmox_vm_interfaces_helper.rb +19 -6
- data/app/helpers/proxmox_vm_os_template_helper.rb +2 -5
- data/app/helpers/proxmox_vm_uuid_helper.rb +1 -1
- data/app/helpers/proxmox_vm_volumes_helper.rb +22 -25
- data/app/models/concerns/fog_extensions/proxmox/node.rb +2 -2
- data/app/models/concerns/fog_extensions/proxmox/server.rb +10 -6
- data/app/models/concerns/host_ext/proxmox/associator.rb +3 -2
- data/app/models/concerns/host_ext/proxmox/for_vm.rb +1 -1
- data/app/models/concerns/host_ext/proxmox/interfaces.rb +7 -3
- data/app/models/concerns/orchestration/proxmox/compute.rb +11 -4
- data/app/models/foreman_fog_proxmox/options_select.rb +1 -3
- data/app/models/foreman_fog_proxmox/proxmox.rb +12 -10
- data/app/models/foreman_fog_proxmox/proxmox_compute_attributes.rb +15 -3
- data/app/models/foreman_fog_proxmox/proxmox_connection.rb +6 -2
- data/app/models/foreman_fog_proxmox/proxmox_console.rb +3 -1
- data/app/models/foreman_fog_proxmox/proxmox_images.rb +2 -2
- data/app/models/foreman_fog_proxmox/proxmox_interfaces.rb +37 -14
- data/app/models/foreman_fog_proxmox/proxmox_operating_systems.rb +6 -1
- data/app/models/foreman_fog_proxmox/proxmox_pools.rb +4 -4
- data/app/models/foreman_fog_proxmox/proxmox_version.rb +7 -3
- data/app/models/foreman_fog_proxmox/proxmox_vm_commands.rb +9 -7
- data/app/models/foreman_fog_proxmox/proxmox_vm_new.rb +37 -24
- data/app/models/foreman_fog_proxmox/proxmox_vm_queries.rb +4 -5
- data/app/models/foreman_fog_proxmox/proxmox_volumes.rb +23 -12
- data/app/models/foreman_fog_proxmox/vms.rb +2 -2
- data/app/overrides/compute_resources_vms/form/add_clone_to_new_vm_compute_detail.rb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_compute_form.html.erb +2 -2
- data/app/views/compute_resources_vms/form/proxmox/_add_from_profile_to_hosts_compute_detail_form.html.erb +4 -2
- data/app/views/compute_resources_vms/form/proxmox/_base.html.erb +0 -1
- data/app/views/compute_resources_vms/form/proxmox/container/_config.html.erb +2 -2
- data/app/views/compute_resources_vms/form/proxmox/container/_network.html.erb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/container/_volume_mp.html.erb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/container/_volume_rootfs.html.erb +1 -1
- data/app/views/compute_resources_vms/form/proxmox/server/_config.html.erb +3 -3
- data/app/views/compute_resources_vms/form/proxmox/server/_network.html.erb +2 -2
- data/app/views/compute_resources_vms/form/proxmox/server/_volume_hard_disk.html.erb +1 -1
- data/config/routes.rb +8 -4
- data/db/migrate/20210312105013_update_proxmox_uuid_host.rb +1 -2
- data/lib/foreman_fog_proxmox/engine.rb +5 -3
- data/lib/foreman_fog_proxmox/semver.rb +1 -4
- data/lib/foreman_fog_proxmox/version.rb +1 -1
- data/locale/en/foreman_fog_proxmox.po +140 -47
- data/locale/foreman_fog_proxmox.pot +300 -137
- data/locale/fr/foreman_fog_proxmox.po +145 -52
- data/test/factories/foreman_fog_proxmox/proxmox_container_mock_factory.rb +6 -7
- data/test/factories/foreman_fog_proxmox/proxmox_server_mock_factory.rb +6 -7
- data/test/functional/compute_resources_controller_test.rb +4 -2
- data/test/test_plugin_helper.rb +12 -7
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_container_helper_test.rb +38 -47
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_server_helper_test.rb +49 -34
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_helper_test.rb +29 -65
- data/test/unit/foreman_fog_proxmox/helpers/proxmox_vm_volumes_helper_test.rb +3 -3
- data/test/unit/foreman_fog_proxmox/proxmox_compute_attributes_test.rb +22 -13
- data/test/unit/foreman_fog_proxmox/proxmox_interfaces_test.rb +48 -37
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_container_test.rb +45 -35
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_create_test.rb +0 -4
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cdrom_test.rb +34 -22
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_cloudinit_test.rb +20 -14
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_hard_disk_test.rb +76 -54
- data/test/unit/foreman_fog_proxmox/proxmox_vm_commands_server_update_test.rb +26 -15
- data/test/unit/foreman_fog_proxmox/proxmox_vm_queries_test.rb +1 -1
- data/test/unit/foreman_fog_proxmox/semver_test.rb +2 -1
- metadata +36 -21
@@ -25,28 +25,20 @@ require 'foreman_fog_proxmox/hash_collection'
|
|
25
25
|
|
26
26
|
# Convert a foreman form server hash into a fog-proxmox server attributes hash
|
27
27
|
module ProxmoxVmConfigHelper
|
28
|
-
KILO = 1024
|
29
|
-
MEGA = KILO * KILO
|
30
|
-
GIGA = KILO * MEGA
|
31
|
-
|
32
28
|
def object_to_config_hash(vm, type)
|
33
29
|
vm_h = ActiveSupport::HashWithIndifferentAccess.new
|
34
30
|
main_a = ['vmid']
|
35
31
|
main = vm.attributes.select { |key, _value| main_a.include? key }
|
36
32
|
main_a += ['templated']
|
37
|
-
config = vm.config.attributes.reject
|
33
|
+
config = vm.config.attributes.reject do |key, _value|
|
34
|
+
main_a.include?(key) || Fog::Proxmox::DiskHelper.disk?(key) || Fog::Proxmox::NicHelper.nic?(key)
|
35
|
+
end
|
38
36
|
vm_h = vm_h.merge(main)
|
39
37
|
vm_h = vm_h.merge('config_attributes': config)
|
40
|
-
logger.debug(
|
38
|
+
logger.debug("object_to_config_hash(#{type}): vm_h=#{vm_h}")
|
41
39
|
vm_h
|
42
40
|
end
|
43
41
|
|
44
|
-
def convert_memory_size(config_hash, key)
|
45
|
-
# default unit memory size is Mb
|
46
|
-
memory = (config_hash[key].to_i / MEGA).to_s == '0' ? config_hash[key] : (config_hash[key].to_i / MEGA).to_s
|
47
|
-
config_hash.store(key, memory)
|
48
|
-
end
|
49
|
-
|
50
42
|
def general_a(type)
|
51
43
|
general_a = ['node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes']
|
52
44
|
general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create']
|
@@ -59,7 +51,7 @@ module ProxmoxVmConfigHelper
|
|
59
51
|
main_a = ['name', 'type', 'node_id', 'vmid', 'interfaces', 'mount_points', 'disks']
|
60
52
|
case type
|
61
53
|
when 'lxc'
|
62
|
-
cpu_a = ['arch', 'cpulimit', 'cpuunits'
|
54
|
+
cpu_a = ['arch', 'cpulimit', 'cpuunits']
|
63
55
|
memory_a = ['memory', 'swap']
|
64
56
|
ostemplate_a = ['ostemplate', 'ostemplate_storage', 'ostemplate_file']
|
65
57
|
keys.store(:ostemplate, ostemplate_a)
|
@@ -76,10 +68,6 @@ module ProxmoxVmConfigHelper
|
|
76
68
|
keys
|
77
69
|
end
|
78
70
|
|
79
|
-
def convert_memory_sizes(args)
|
80
|
-
['memory', 'balloon', 'shares', 'swap'].each { |key| convert_memory_size(args['config_attributes'], key) }
|
81
|
-
end
|
82
|
-
|
83
71
|
def config_general_or_ostemplate_key?(key)
|
84
72
|
config_typed_keys('lxc')[:general].include?(key) || config_typed_keys(type)[:ostemplate].include?(key)
|
85
73
|
end
|
@@ -125,7 +113,9 @@ module ProxmoxVmConfigHelper
|
|
125
113
|
logger.debug("parsed_typed_config(#{type}): config_cpu=#{config_cpu}")
|
126
114
|
cpu = parse_typed_cpu(config_cpu, type)
|
127
115
|
memory = parse_typed_memory(config.select { |key, _value| config_typed_keys(type)[:memory].include? key }, type)
|
128
|
-
parsed_config = config.reject
|
116
|
+
parsed_config = config.reject do |key, value|
|
117
|
+
config_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value)
|
118
|
+
end
|
129
119
|
parsed_vm = args.reject { |key, value| args_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) }
|
130
120
|
parsed_vm = parsed_vm.merge(config_options(config, args, type))
|
131
121
|
parsed_vm = parsed_vm.merge(parsed_config).merge(cpu).merge(memory)
|
@@ -134,26 +124,27 @@ module ProxmoxVmConfigHelper
|
|
134
124
|
end
|
135
125
|
|
136
126
|
def parse_typed_memory(args, type)
|
137
|
-
memory = {}
|
138
127
|
ForemanFogProxmox::HashCollection.remove_empty_values(args)
|
139
|
-
|
140
|
-
|
128
|
+
logger.debug("parse_typed_memory(#{type}): args=#{args}")
|
129
|
+
args
|
141
130
|
end
|
142
131
|
|
143
132
|
def parse_typed_cpu(args, type)
|
144
133
|
cpu = {}
|
145
134
|
ForemanFogProxmox::HashCollection.remove_empty_values(args)
|
146
|
-
|
135
|
+
case type
|
136
|
+
when 'qemu'
|
147
137
|
logger.debug("parse_typed_cpu(#{type}): args=#{args}")
|
148
138
|
cpu_flattened = Fog::Proxmox::CpuHelper.flatten(args)
|
149
139
|
cpu_flattened = args[:cpu] if cpu_flattened.empty?
|
150
140
|
logger.debug("parse_typed_cpu(#{type}): cpu_flattened=#{cpu_flattened}")
|
151
|
-
ForemanFogProxmox::HashCollection.remove_empty_values(args)
|
152
|
-
ForemanFogProxmox::HashCollection.remove_keys(args, config_typed_keys('qemu')[:cpu])
|
153
141
|
args.each_value(&:to_i)
|
154
142
|
cpu = { cpu: cpu_flattened }
|
143
|
+
when 'lxc'
|
144
|
+
config_typed_keys('lxc')[:cpu].each do |key|
|
145
|
+
ForemanFogProxmox::HashCollection.add_and_format_element(cpu, key.to_sym, args, key)
|
146
|
+
end
|
155
147
|
end
|
156
|
-
config_typed_keys('lxc')[:cpu].each { |key| ForemanFogProxmox::HashCollection.add_and_format_element(cpu, key.to_sym, args, key) } if type == 'lxc'
|
157
148
|
logger.debug("parse_typed_cpu(#{type}): cpu=#{cpu}")
|
158
149
|
cpu
|
159
150
|
end
|
@@ -35,8 +35,12 @@ module ProxmoxVmInterfacesHelper
|
|
35
35
|
interfaces_to_add = []
|
36
36
|
interfaces_to_delete = []
|
37
37
|
interfaces_attributes = args['interfaces_attributes']
|
38
|
-
|
39
|
-
|
38
|
+
unless ForemanFogProxmox::Value.empty?(args['config_attributes'])
|
39
|
+
interfaces_attributes ||= args['config_attributes']['interfaces_attributes']
|
40
|
+
end
|
41
|
+
interfaces_attributes&.each_value do |value|
|
42
|
+
add_or_delete_typed_interface(value, interfaces_to_delete, interfaces_to_add, type)
|
43
|
+
end
|
40
44
|
[interfaces_to_add, interfaces_to_delete]
|
41
45
|
end
|
42
46
|
|
@@ -65,7 +69,9 @@ module ProxmoxVmInterfacesHelper
|
|
65
69
|
def add_or_delete_typed_interface(interface_attributes, interfaces_to_delete, interfaces_to_add, type)
|
66
70
|
logger.debug("add_or_delete_typed_interface(#{type}): interface_attributes=#{interface_attributes}")
|
67
71
|
ForemanFogProxmox::HashCollection.remove_empty_values(interface_attributes)
|
68
|
-
|
72
|
+
if interface_attributes['compute_attributes']
|
73
|
+
ForemanFogProxmox::HashCollection.remove_empty_values(interface_attributes['compute_attributes'])
|
74
|
+
end
|
69
75
|
nic = {}
|
70
76
|
id = interface_attributes['id']
|
71
77
|
delete = interface_attributes['_delete'].to_i == 1
|
@@ -73,10 +79,17 @@ module ProxmoxVmInterfacesHelper
|
|
73
79
|
logger.debug("add_or_delete_typed_interface(#{type}): delete id=#{id}")
|
74
80
|
interfaces_to_delete.push(id.to_s)
|
75
81
|
else
|
76
|
-
interface_common_typed_keys(type).each
|
82
|
+
interface_common_typed_keys(type).each do |key|
|
83
|
+
ForemanFogProxmox::HashCollection.add_and_format_element(nic, key[:dest].to_sym, interface_attributes,
|
84
|
+
key[:origin])
|
85
|
+
end
|
77
86
|
interface_attributes_h = interface_attributes['compute_attributes']
|
78
|
-
|
79
|
-
|
87
|
+
if ForemanFogProxmox::Value.empty?(interface_attributes['compute_attributes'])
|
88
|
+
interface_attributes_h ||= interface_attributes
|
89
|
+
end
|
90
|
+
interface_compute_attributes_typed_keys(type).each do |key|
|
91
|
+
ForemanFogProxmox::HashCollection.add_and_format_element(nic, key.to_sym, interface_attributes_h, key)
|
92
|
+
end
|
80
93
|
compute_dhcps(interface_attributes_h)
|
81
94
|
logger.debug("add_or_delete_typed_interface(#{type}): add nic=#{nic}")
|
82
95
|
interfaces_to_add.push(Fog::Proxmox::NicHelper.flatten(nic))
|
@@ -38,10 +38,7 @@ module ProxmoxVmOsTemplateHelper
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def parse_container_ostemplate(args)
|
41
|
-
ostemplate = args['ostemplate']
|
42
|
-
|
43
|
-
ostemplate ||= ostemplate_file
|
44
|
-
parsed_ostemplate = { ostemplate: ostemplate }
|
45
|
-
parsed_ostemplate
|
41
|
+
ostemplate = args['ostemplate'] || args['ostemplate_file']
|
42
|
+
{ ostemplate: ostemplate }
|
46
43
|
end
|
47
44
|
end
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# along with ForemanFogProxmox. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
|
20
20
|
module ProxmoxVmUuidHelper
|
21
|
-
UUID_REGEXP = /(?<cluster_id>\d+)
|
21
|
+
UUID_REGEXP = /(?<cluster_id>\d+)_(?<vmid>\d+)/.freeze
|
22
22
|
def extract(uuid, name)
|
23
23
|
captures_h = uuid ? UUID_REGEXP.match(uuid.to_s) : { cluster_id: '', vmid: '' }
|
24
24
|
captures_h ? captures_h[name] : ''
|
@@ -26,33 +26,37 @@ require 'foreman_fog_proxmox/hash_collection'
|
|
26
26
|
module ProxmoxVmVolumesHelper
|
27
27
|
include ProxmoxVmCdromHelper
|
28
28
|
include ProxmoxVmCloudinitHelper
|
29
|
-
KILO = 1024
|
30
|
-
MEGA = KILO * KILO
|
31
|
-
GIGA = KILO * MEGA
|
32
29
|
|
33
30
|
def add_disk_options(disk, args)
|
34
|
-
options = ForemanFogProxmox::HashCollection.new_hash_reject_keys(args,
|
31
|
+
options = ForemanFogProxmox::HashCollection.new_hash_reject_keys(args,
|
32
|
+
['id', 'volid', 'controller', 'device', 'storage', 'size', '_delete', 'storage_type'])
|
35
33
|
ForemanFogProxmox::HashCollection.remove_empty_values(options)
|
36
34
|
disk[:options] = options
|
37
35
|
end
|
38
36
|
|
39
37
|
def parsed_typed_volumes(args, type, parsed_vm)
|
40
|
-
logger.debug(
|
38
|
+
logger.debug("parsed_typed_volumes(#{type}): args=#{args}")
|
41
39
|
volumes_attributes = args['volumes_attributes']
|
42
|
-
|
43
|
-
|
40
|
+
unless ForemanFogProxmox::Value.empty?(args['config_attributes'])
|
41
|
+
volumes_attributes ||= args['config_attributes']['volumes_attributes']
|
42
|
+
end
|
43
|
+
unless ForemanFogProxmox::Value.empty?(args['vm_attrs'])
|
44
|
+
volumes_attributes ||= args['vm_attrs']['volumes_attributes']
|
45
|
+
end
|
44
46
|
volumes = parse_typed_volumes(volumes_attributes, type)
|
45
47
|
volumes.each { |volume| parsed_vm = parsed_vm.merge(volume) }
|
46
48
|
parsed_vm
|
47
49
|
end
|
48
50
|
|
49
51
|
def parse_hard_disk_volume(args)
|
52
|
+
logger.debug(format(_('parse_hard_disk_volume(): args=%<args>s'), args: args))
|
50
53
|
disk = {}
|
51
54
|
disk[:id] = args['id'] if args.key?('id')
|
52
55
|
disk[:volid] = args['volid'] if args.key?('volid')
|
53
56
|
disk[:storage] = args['storage'].to_s if args.key?('storage')
|
54
57
|
disk[:size] = args['size'].to_i if args.key?('size')
|
55
|
-
add_disk_options(disk, args)
|
58
|
+
add_disk_options(disk, args) unless args.key?('options')
|
59
|
+
disk[:options] = args['options'] if args.key?('options')
|
56
60
|
disk.key?(:storage) ? disk : {}
|
57
61
|
end
|
58
62
|
|
@@ -67,11 +71,12 @@ module ProxmoxVmVolumesHelper
|
|
67
71
|
end
|
68
72
|
|
69
73
|
def parse_typed_volume(args, type)
|
70
|
-
logger.debug(
|
71
|
-
disk = parse_hard_disk_volume(args) if volume_type?(args,
|
74
|
+
logger.debug("parse_typed_volume(#{type}): args=#{args}")
|
75
|
+
disk = parse_hard_disk_volume(args) if volume_type?(args,
|
76
|
+
'hard_disk') || volume_type?(args, 'mp') || volume_type?(args, 'rootfs')
|
72
77
|
disk = parse_server_cloudinit(args) if volume_type?(args, 'cloud_init')
|
73
78
|
disk = parse_server_cdrom(args) if volume_type?(args, 'cdrom')
|
74
|
-
logger.debug(
|
79
|
+
logger.debug("parse_typed_volume(#{type}): disk=#{disk}")
|
75
80
|
Fog::Proxmox::DiskHelper.flatten(disk) unless disk.empty?
|
76
81
|
end
|
77
82
|
|
@@ -81,25 +86,17 @@ module ProxmoxVmVolumesHelper
|
|
81
86
|
end
|
82
87
|
|
83
88
|
def parse_typed_volumes(args, type)
|
84
|
-
logger.debug(
|
89
|
+
logger.debug("parse_typed_volumes(#{type}): args=#{args}")
|
85
90
|
volumes = []
|
86
91
|
args&.each_value { |value| add_typed_volume(volumes, value, type) }
|
87
92
|
volumes
|
88
93
|
end
|
89
94
|
|
90
|
-
def convert_volumes_size(args)
|
91
|
-
args['volumes_attributes'].each_value { |value| value['size'] = (value['size'].to_i / GIGA).to_s unless ForemanFogProxmox::Value.empty?(value['size']) }
|
92
|
-
end
|
93
|
-
|
94
|
-
def convert_sizes(args)
|
95
|
-
convert_memory_size(args['config_attributes'], 'memory')
|
96
|
-
convert_memory_size(args['config_attributes'], 'balloon')
|
97
|
-
convert_memory_size(args['config_attributes'], 'shares')
|
98
|
-
convert_memory_size(args['config_attributes'], 'swap')
|
99
|
-
args['volumes_attributes'].each_value { |value| value['size'] = (value['size'].to_i / GIGA).to_s unless ForemanFogProxmox::Value.empty?(value['size']) }
|
100
|
-
end
|
101
|
-
|
102
95
|
def remove_volume_keys(args)
|
103
|
-
|
96
|
+
if args.key?('volumes_attributes')
|
97
|
+
args['volumes_attributes'].each_value do |volume_attributes|
|
98
|
+
ForemanFogProxmox::HashCollection.remove_keys(volume_attributes, ['_delete'])
|
99
|
+
end
|
100
|
+
end
|
104
101
|
end
|
105
102
|
end
|
@@ -22,7 +22,7 @@ module FogExtensions
|
|
22
22
|
module Node
|
23
23
|
extend ActiveSupport::Concern
|
24
24
|
|
25
|
-
def each(collection_filters = {})
|
25
|
+
def each(collection_filters = {}, &block)
|
26
26
|
if block_given?
|
27
27
|
Kernel.loop do
|
28
28
|
break unless collection_filters[:marker]
|
@@ -31,7 +31,7 @@ module FogExtensions
|
|
31
31
|
# We need to explicitly use the base 'each' method here on the page,
|
32
32
|
# otherwise we get infinite recursion
|
33
33
|
base_each = Fog::Collection.instance_method(:each)
|
34
|
-
base_each.bind(page).call
|
34
|
+
base_each.bind(page).call(&block)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
self
|
@@ -24,7 +24,7 @@ module FogExtensions
|
|
24
24
|
attr_accessor :image_id, :templated, :ostemplate_storage, :ostemplate_file, :password, :start_after_create
|
25
25
|
|
26
26
|
def unique_cluster_identity(compute_resource)
|
27
|
-
compute_resource.id.to_s + '_' + identity
|
27
|
+
compute_resource.id.to_s + '_' + identity.to_s
|
28
28
|
end
|
29
29
|
|
30
30
|
def start
|
@@ -59,11 +59,12 @@ module FogExtensions
|
|
59
59
|
delegate :description, to: :config
|
60
60
|
|
61
61
|
def vm_description
|
62
|
-
format(_('Type %<type>s, node %<node>s, %<cpus>s CPUs and %<memory>s MB memory'),
|
62
|
+
format(_('Type %<type>s, node %<node>s, %<cpus>s CPUs and %<memory>s MB memory'),
|
63
|
+
type: type, node: node_id, cpus: config.cores || '0', memory: config.memory)
|
63
64
|
end
|
64
65
|
|
65
66
|
def select_nic(fog_nics, nic)
|
66
|
-
fog_nics.find { |fog_nic| fog_nic.identity.to_s == nic.
|
67
|
+
fog_nics.find { |fog_nic| fog_nic.identity.to_s == nic.compute_attributes[:id] }
|
67
68
|
end
|
68
69
|
|
69
70
|
delegate :interfaces, to: :config
|
@@ -84,11 +85,14 @@ module FogExtensions
|
|
84
85
|
delegate :pool, to: :config
|
85
86
|
delegate :cloud_init?, to: :config
|
86
87
|
|
87
|
-
def interfaces_attributes=(attrs)
|
88
|
+
def interfaces_attributes=(attrs)
|
89
|
+
end
|
88
90
|
|
89
|
-
def volumes_attributes=(attrs)
|
91
|
+
def volumes_attributes=(attrs)
|
92
|
+
end
|
90
93
|
|
91
|
-
def config_attributes=(attrs)
|
94
|
+
def config_attributes=(attrs)
|
95
|
+
end
|
92
96
|
|
93
97
|
def templated?
|
94
98
|
volumes.any?(&:template?)
|
@@ -33,13 +33,14 @@ module HostExt
|
|
33
33
|
|
34
34
|
def proxmox_vm_id(compute_resource, vm)
|
35
35
|
id = vm.identity
|
36
|
-
id = vm.unique_cluster_identity(compute_resource) if compute_resource.
|
36
|
+
id = vm.unique_cluster_identity(compute_resource) if compute_resource.instance_of?(ForemanFogProxmox::Proxmox)
|
37
37
|
id
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def for_vm_uuid(cr, vm)
|
42
|
-
where(:compute_resource_id => cr.id,
|
42
|
+
where(:compute_resource_id => cr.id,
|
43
|
+
:uuid => Array.wrap(vm).compact.map(cr.id.to_s + '_' + vm&.identity).map(&:to_s))
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -24,7 +24,7 @@ module HostExt
|
|
24
24
|
module ClassMethods
|
25
25
|
def for_vm_uuid(cr, vm)
|
26
26
|
uuid = vm&.identity
|
27
|
-
uuid = cr.id.to_s + '_' + vm&.identity if cr.
|
27
|
+
uuid = cr.id.to_s + '_' + vm&.identity.to_s if cr.instance_of?(ForemanFogProxmox::Proxmox)
|
28
28
|
where(:compute_resource_id => cr.id, :uuid => uuid)
|
29
29
|
end
|
30
30
|
end
|
@@ -24,14 +24,17 @@ module HostExt
|
|
24
24
|
module Interfaces
|
25
25
|
extend ActiveSupport::Concern
|
26
26
|
def update(attributes = {})
|
27
|
-
|
27
|
+
if provider == 'Proxmox' && !attributes.nil? && attributes.key?('compute_attributes')
|
28
|
+
add_interfaces_to_compute_attributes(attributes)
|
29
|
+
end
|
28
30
|
super(attributes)
|
29
31
|
end
|
30
32
|
|
31
33
|
def add_interfaces_to_compute_attributes(attributes)
|
32
34
|
attributes['compute_attributes'].store('interfaces_attributes', {})
|
33
35
|
attributes['interfaces_attributes'].each do |index, interface_attributes|
|
34
|
-
add_interface_to_compute_attributes(index, interface_attributes,
|
36
|
+
add_interface_to_compute_attributes(index, interface_attributes,
|
37
|
+
attributes['compute_attributes']['interfaces_attributes'])
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -40,7 +43,8 @@ module HostExt
|
|
40
43
|
key_ip += '6' if v == 6
|
41
44
|
key_cidr = 'cidr'
|
42
45
|
key_cidr += '6' if v == 6
|
43
|
-
Fog::Proxmox::IpHelper.to_cidr(interface_attributes[key_ip],
|
46
|
+
Fog::Proxmox::IpHelper.to_cidr(interface_attributes[key_ip],
|
47
|
+
interface_attributes['compute_attributes'][key_cidr])
|
44
48
|
end
|
45
49
|
|
46
50
|
def add_interface_to_compute_attributes(index, interface_attributes, compute_attributes)
|
@@ -32,7 +32,8 @@ module Orchestration
|
|
32
32
|
compute_resource.save_vm uuid, final_compute_attributes
|
33
33
|
end
|
34
34
|
rescue StandardError => e
|
35
|
-
failure format(_('Failed to update a compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e),
|
35
|
+
failure format(_('Failed to update a compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e),
|
36
|
+
e
|
36
37
|
end
|
37
38
|
|
38
39
|
def delComputeUpdate
|
@@ -44,7 +45,8 @@ module Orchestration
|
|
44
45
|
compute_resource.save_vm uuid, final_compute_attributes
|
45
46
|
end
|
46
47
|
rescue StandardError => e
|
47
|
-
failure format(_('Failed to undo update compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e),
|
48
|
+
failure format(_('Failed to undo update compute %<compute_resource>s instance %<name>s: %<e>s'), :compute_resource => compute_resource, :name => name, :e => e),
|
49
|
+
e
|
48
50
|
end
|
49
51
|
|
50
52
|
def empty_provided_ips?(ip, ip6)
|
@@ -62,7 +64,7 @@ module Orchestration
|
|
62
64
|
def computeValue(foreman_attr, fog_attr)
|
63
65
|
value = ''
|
64
66
|
value += compute_resource.id.to_s + '_' if foreman_attr == :uuid
|
65
|
-
value += vm.send(fog_attr)
|
67
|
+
value += vm.send(fog_attr).to_s
|
66
68
|
value
|
67
69
|
end
|
68
70
|
|
@@ -82,7 +84,12 @@ module Orchestration
|
|
82
84
|
result = false unless validate_required_foreman_attr(value, Host, foreman_attr)
|
83
85
|
end
|
84
86
|
end
|
85
|
-
|
87
|
+
if empty_provided_ips?(
|
88
|
+
ip, ip6
|
89
|
+
)
|
90
|
+
return failure(format(_('Failed to acquire IP addresses from compute resource for %<name>s'),
|
91
|
+
name: name))
|
92
|
+
end
|
86
93
|
|
87
94
|
result
|
88
95
|
end
|
@@ -36,11 +36,12 @@ module ForemanFogProxmox
|
|
36
36
|
include ProxmoxVersion
|
37
37
|
include ProxmoxConsole
|
38
38
|
validates :url, :format => { :with => URI::DEFAULT_PARSER.make_regexp }, :presence => true
|
39
|
-
validates :auth_method, :presence => true, inclusion
|
40
|
-
|
41
|
-
validates :
|
42
|
-
validates :
|
43
|
-
validates :
|
39
|
+
validates :auth_method, :presence => true, :inclusion => { in: ['access_ticket', 'user_token'],
|
40
|
+
message: ->(value) do format('%<value>s is not a valid authentication method', { value: value }) end }
|
41
|
+
validates :user, :format => { :with => /(\w+)@{1}(\w+)/ }, :presence => true
|
42
|
+
validates :password, :presence => true, :if => :access_ticket?
|
43
|
+
validates :token_id, :presence => true, :if => :user_token?
|
44
|
+
validates :token, :presence => true, :if => :user_token?
|
44
45
|
|
45
46
|
def provided_attributes
|
46
47
|
super.merge(
|
@@ -65,7 +66,8 @@ module ForemanFogProxmox
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def associate_by(name, attributes)
|
68
|
-
Host.authorized(:view_hosts,
|
69
|
+
Host.authorized(:view_hosts,
|
70
|
+
Host).joins(:primary_interface).where(:nics => { :primary => true }).where("nics.#{name}".downcase => attributes.downcase).readonly(false).first
|
69
71
|
end
|
70
72
|
|
71
73
|
def ssl_certs
|
@@ -128,7 +130,7 @@ module ForemanFogProxmox
|
|
128
130
|
hash = {
|
129
131
|
proxmox_url: url,
|
130
132
|
proxmox_auth_method: auth_method || 'access_ticket',
|
131
|
-
connection_options: connection_options
|
133
|
+
connection_options: connection_options,
|
132
134
|
}
|
133
135
|
if access_ticket?
|
134
136
|
hash[:proxmox_username] = user
|
@@ -151,7 +153,7 @@ module ForemanFogProxmox
|
|
151
153
|
rescue Excon::Errors::Unauthorized => e
|
152
154
|
raise ::Foreman::Exception, 'User token expired' if token_expired?(e)
|
153
155
|
rescue StandardError => e
|
154
|
-
logger.warn(
|
156
|
+
logger.warn("failed to create compute client: #{e}")
|
155
157
|
raise e
|
156
158
|
end
|
157
159
|
|
@@ -160,7 +162,7 @@ module ForemanFogProxmox
|
|
160
162
|
rescue Excon::Errors::Unauthorized => e
|
161
163
|
raise ::Foreman::Exception, 'User token expired' if token_expired?(e)
|
162
164
|
rescue StandardError => e
|
163
|
-
logger.warn(
|
165
|
+
logger.warn("failed to create identity client: #{e}")
|
164
166
|
raise e
|
165
167
|
end
|
166
168
|
|
@@ -169,7 +171,7 @@ module ForemanFogProxmox
|
|
169
171
|
rescue Excon::Errors::Unauthorized => e
|
170
172
|
raise ::Foreman::Exception, 'User token expired' if token_expired?(e)
|
171
173
|
rescue StandardError => e
|
172
|
-
logger.warn(
|
174
|
+
logger.warn("failed to create network client: #{e}")
|
173
175
|
raise e
|
174
176
|
end
|
175
177
|
|
@@ -27,7 +27,11 @@ module ForemanFogProxmox
|
|
27
27
|
host.compute_attributes['config_attributes'].store('hostname', host.name)
|
28
28
|
when 'qemu'
|
29
29
|
host.compute_attributes['config_attributes'].store('name', host.name)
|
30
|
-
|
30
|
+
unless compute_os_types(host).include?(ostype)
|
31
|
+
raise ::Foreman::Exception,
|
32
|
+
format(_('Operating system family %<type>s is not consistent with %<ostype>s'), type: host.operatingsystem.type,
|
33
|
+
ostype: ostype)
|
34
|
+
end
|
31
35
|
end
|
32
36
|
super
|
33
37
|
end
|
@@ -47,8 +51,16 @@ module ForemanFogProxmox
|
|
47
51
|
vm_attrs = {}
|
48
52
|
vm_attrs = vm_attrs.merge(vmid: vm.identity, node_id: vm.node_id, type: vm.type)
|
49
53
|
if vm.respond_to?(:config)
|
50
|
-
|
51
|
-
|
54
|
+
if vm.config.respond_to?(:disks)
|
55
|
+
vm_attrs[:volumes_attributes] = Hash[vm.config.disks.each_with_index.map do |disk, idx|
|
56
|
+
[idx.to_s, disk.attributes]
|
57
|
+
end ]
|
58
|
+
end
|
59
|
+
if vm.config.respond_to?(:interfaces)
|
60
|
+
vm_attrs[:interfaces_attributes] = Hash[vm.config.interfaces.each_with_index.map do |interface, idx|
|
61
|
+
[idx.to_s, interface_compute_attributes(interface.attributes)]
|
62
|
+
end ]
|
63
|
+
end
|
52
64
|
vm_attrs[:config_attributes] = vm.config.attributes.reject do |key, value|
|
53
65
|
not_config_key?(vm, key) || ForemanFogProxmox::Value.empty?(value.to_s) || Fog::Proxmox::DiskHelper.disk?(key.to_s) || Fog::Proxmox::NicHelper.nic?(key.to_s)
|
54
66
|
end
|
@@ -38,8 +38,12 @@ module ForemanFogProxmox
|
|
38
38
|
|
39
39
|
def credentials_valid?
|
40
40
|
errors[:url].empty? && errors[:auth_method].empty?
|
41
|
-
|
42
|
-
|
41
|
+
if access_ticket?
|
42
|
+
errors[:user].empty? && errors[:user].include?('@') && errors[:password].empty? && errors[:node_id].empty?
|
43
|
+
end
|
44
|
+
if user_token?
|
45
|
+
errors[:user].empty? && errors[:user].include?('@') && errors[:token_id].empty? && errors[:token].empty? && errors[:node_id].empty?
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
def current_user_token_expire
|
@@ -31,7 +31,9 @@ module ForemanFogProxmox
|
|
31
31
|
options.store(:websocket, 1) if type_console == 'vnc'
|
32
32
|
begin
|
33
33
|
vnc_console = vm.start_console(options)
|
34
|
-
WsProxy.start(:host => host, :host_port => vnc_console['port'], :password => vnc_console['ticket']).merge(
|
34
|
+
WsProxy.start(:host => host, :host_port => vnc_console['port'], :password => vnc_console['ticket']).merge(
|
35
|
+
:name => vm.name, :type => type_console
|
36
|
+
)
|
35
37
|
rescue StandardError => e
|
36
38
|
logger.error(e)
|
37
39
|
raise ::Foreman::Exception, _('%<s>s console is not supported at this time') % type_console
|
@@ -27,7 +27,7 @@ module ForemanFogProxmox
|
|
27
27
|
node = client.nodes.get node_id
|
28
28
|
node ||= default_node
|
29
29
|
storage = node.storages.get storage_id if storage_id
|
30
|
-
logger.debug(
|
30
|
+
logger.debug("images_by_storage(): node_id #{node_id} storage_id #{storage_id} type #{type}")
|
31
31
|
storage.volumes.list_by_content_type(type).sort_by(&:volid) if storage
|
32
32
|
end
|
33
33
|
|
@@ -58,7 +58,7 @@ module ForemanFogProxmox
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def clone_from_image(image_id, args, vmid)
|
61
|
-
logger.debug(
|
61
|
+
logger.debug("create_vm(): clone #{image_id} in #{vmid}")
|
62
62
|
image = find_vm_by_uuid(image_id)
|
63
63
|
image.clone(vmid)
|
64
64
|
clone = find_vm_by_uuid(id.to_s + '_' + vmid.to_s)
|