foreman_fog_proxmox 0.14.0 → 0.14.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.
- checksums.yaml +4 -4
- data/README.md +42 -29
- 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 +8 -3
- 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 +9 -5
- 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 +9 -5
- 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 +28 -6
- 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/views/compute_resources_vms/form/proxmox/container/_config.html.erb +2 -2
- 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/_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 +4 -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 +18 -9
- 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 +35 -21
@@ -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,7 +59,8 @@ 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)
|
@@ -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)
|
@@ -28,7 +28,11 @@ module ForemanFogProxmox
|
|
28
28
|
|
29
29
|
def set_nic_identifier(nic, index)
|
30
30
|
nic.compute_attributes[:id] = format('net%<index>s', index: index) if nic.compute_attributes[:id].empty?
|
31
|
-
|
31
|
+
unless Fog::Proxmox::NicHelper.nic?(nic.compute_attributes[:id])
|
32
|
+
raise ::Foreman::Exception,
|
33
|
+
_(format('Invalid proxmox NIC id on interface[%<index>s]. Must be net[n] with n integer >= 0',
|
34
|
+
index: index))
|
35
|
+
end
|
32
36
|
|
33
37
|
nic.identifier = nic.compute_attributes['id'] if nic.identifier.empty?
|
34
38
|
end
|
@@ -49,7 +53,11 @@ module ForemanFogProxmox
|
|
49
53
|
|
50
54
|
def set_container_interface_name(_host, nic, index)
|
51
55
|
nic.compute_attributes['name'] = format('eth%<index>s', index: index) if nic.compute_attributes['name'].empty?
|
52
|
-
|
56
|
+
unless container_nic_name_valid?(nic)
|
57
|
+
raise ::Foreman::Exception,
|
58
|
+
_(format('Invalid name interface[%<index>s]. Must be eth[n] with n integer >= 0',
|
59
|
+
index: index))
|
60
|
+
end
|
53
61
|
end
|
54
62
|
|
55
63
|
def cidr_prefix(nic_compute_attributes, v6 = false)
|
@@ -66,7 +74,9 @@ module ForemanFogProxmox
|
|
66
74
|
ipv = "IPv#{v6 ? '6' : '4'}"
|
67
75
|
max = v6 ? 128 : 32
|
68
76
|
checked = valid || ForemanFogProxmox::Value.empty?(ip)
|
69
|
-
message = format(
|
77
|
+
message = format(
|
78
|
+
'Invalid Interface Proxmox CIDR %<ip>s. If %<ip>s is not empty, Proxmox CIDR prefix must be an integer between 0 and %<max>i.', ip: ipv, max: max
|
79
|
+
)
|
70
80
|
raise ::Foreman::Exception, _(message) unless checked
|
71
81
|
end
|
72
82
|
|
@@ -89,7 +99,10 @@ module ForemanFogProxmox
|
|
89
99
|
ip = 'dhcp'
|
90
100
|
elsif !ForemanFogProxmox::Value.empty?(cidr_prefix(nic_compute_attributes, v6))
|
91
101
|
check_cidr(nic_compute_attributes, v6, ip)
|
92
|
-
|
102
|
+
if ip
|
103
|
+
ip = Fog::Proxmox::IpHelper.send(to_cidr_method(v6), nic.send(ip_s(v6).to_sym),
|
104
|
+
cidr_prefix(nic_compute_attributes, v6))
|
105
|
+
end
|
93
106
|
end
|
94
107
|
end
|
95
108
|
nic_compute_attributes[ip_s(v6).to_sym] = ip
|
@@ -118,8 +131,17 @@ module ForemanFogProxmox
|
|
118
131
|
mac = nic.mac
|
119
132
|
mac ||= nic.attributes['mac']
|
120
133
|
set_mac(nic.compute_attributes, mac, vm_type(host)) if mac.present?
|
121
|
-
interface_compute_attributes =
|
122
|
-
|
134
|
+
interface_compute_attributes = if host.compute_attributes['interfaces_attributes']
|
135
|
+
host.compute_attributes['interfaces_attributes'].select do |_k, v|
|
136
|
+
v['id'] == nic.compute_attributes[:id]
|
137
|
+
end
|
138
|
+
else
|
139
|
+
{}
|
140
|
+
end
|
141
|
+
unless interface_compute_attributes.empty?
|
142
|
+
nic.compute_attributes.store(:_delete,
|
143
|
+
interface_compute_attributes[interface_compute_attributes.keys[0]]['_delete'])
|
144
|
+
end
|
123
145
|
set_ip(host, nic, nic.compute_attributes)
|
124
146
|
set_ip(host, nic, nic.compute_attributes, true)
|
125
147
|
ForemanFogProxmox::HashCollection.remove_keys(nic.compute_attributes, ['dhcp', 'dhcp6', 'cidr', 'cidr6'])
|
@@ -39,7 +39,12 @@ module ForemanFogProxmox
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def os_linux_types_mapping(host)
|
42
|
-
['Debian', 'Redhat', 'Suse', 'Altlinux', 'Archlinux', 'Coreos', 'Rancheros',
|
42
|
+
if ['Debian', 'Redhat', 'Suse', 'Altlinux', 'Archlinux', 'Coreos', 'Rancheros',
|
43
|
+
'Gentoo'].include?(host.operatingsystem.type)
|
44
|
+
available_linux_operating_systems
|
45
|
+
else
|
46
|
+
[]
|
47
|
+
end
|
43
48
|
end
|
44
49
|
|
45
50
|
def os_windows_types_mapping(host)
|
@@ -25,21 +25,21 @@ module ForemanFogProxmox
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def pool_owner(vm)
|
28
|
-
logger.debug(
|
28
|
+
logger.debug("pool_owner(#{vm&.vmid})")
|
29
29
|
pools_owners = pools.select { |pool| pool.has_server?(vm&.vmid) }
|
30
30
|
pool = pools_owners.first
|
31
|
-
logger.debug(
|
31
|
+
logger.debug("found vm: #{vm&.vmid} member of pool: #{pool&.poolid}")
|
32
32
|
vm&.config&.pool = pool&.poolid
|
33
33
|
end
|
34
34
|
|
35
35
|
def add_vm_to_pool(poolid, vmid)
|
36
|
-
logger.debug(
|
36
|
+
logger.debug("add_vm_to_pool(#{poolid}, #{vmid})")
|
37
37
|
pool = identity_client.pools.get poolid
|
38
38
|
pool&.add_server vmid
|
39
39
|
end
|
40
40
|
|
41
41
|
def remove_vm_from_pool(poolid, vmid)
|
42
|
-
logger.debug(
|
42
|
+
logger.debug("remove_vm_from_pool(#{poolid}, #{vmid})")
|
43
43
|
pool = identity_client.pools.get poolid
|
44
44
|
pool&.remove_server vmid
|
45
45
|
end
|
@@ -22,8 +22,12 @@ require 'foreman_fog_proxmox/semver'
|
|
22
22
|
module ForemanFogProxmox
|
23
23
|
module ProxmoxVersion
|
24
24
|
def version_suitable?
|
25
|
-
logger.debug(
|
26
|
-
|
25
|
+
logger.debug("Proxmox compute resource version is #{version}")
|
26
|
+
unless ForemanFogProxmox::Semver.semver?(version)
|
27
|
+
raise ::Foreman::Exception,
|
28
|
+
format(_('Proxmox version %<version>s is not semver suitable'),
|
29
|
+
version: version)
|
30
|
+
end
|
27
31
|
|
28
32
|
ForemanFogProxmox::Semver.to_semver(version) >= ForemanFogProxmox::Semver.to_semver('5.3.0')
|
29
33
|
end
|
@@ -34,7 +38,7 @@ module ForemanFogProxmox
|
|
34
38
|
rescue ::Foreman::Exception => e
|
35
39
|
return 'Unkown' if e.message == 'User token expired'
|
36
40
|
rescue StandardError => e
|
37
|
-
logger.warn(
|
41
|
+
logger.warn("failed to get identity client version: #{e}")
|
38
42
|
raise e
|
39
43
|
end
|
40
44
|
end
|
@@ -42,14 +42,13 @@ module ForemanFogProxmox
|
|
42
42
|
if image_id
|
43
43
|
clone_from_image(image_id, args, vmid)
|
44
44
|
else
|
45
|
-
convert_sizes(args)
|
46
45
|
remove_volume_keys(args)
|
47
|
-
logger.warn(
|
46
|
+
logger.warn("create vm: args=#{args}")
|
48
47
|
vm = node.send(vm_collection(type)).create(parse_typed_vm(args, type))
|
49
48
|
start_on_boot(vm, args)
|
50
49
|
end
|
51
50
|
rescue StandardError => e
|
52
|
-
logger.warn(
|
51
|
+
logger.warn("failed to create vm: #{e}")
|
53
52
|
destroy_vm client.identity + '_' + vm.id if vm
|
54
53
|
raise e
|
55
54
|
end
|
@@ -74,7 +73,8 @@ module ForemanFogProxmox
|
|
74
73
|
end
|
75
74
|
|
76
75
|
def compute_config_attributes(parsed_attr)
|
77
|
-
excluded_keys = [:vmid, :templated, :ostemplate, :ostemplate_file, :ostemplate_storage, :volumes_attributes,
|
76
|
+
excluded_keys = [:vmid, :templated, :ostemplate, :ostemplate_file, :ostemplate_storage, :volumes_attributes,
|
77
|
+
:pool]
|
78
78
|
config_attributes = parsed_attr.reject { |key, _value| excluded_keys.include? key.to_sym }
|
79
79
|
ForemanFogProxmox::HashCollection.remove_empty_values(config_attributes)
|
80
80
|
config_attributes = config_attributes.reject { |key, _value| Fog::Proxmox::DiskHelper.disk?(key) }
|
@@ -90,11 +90,13 @@ module ForemanFogProxmox
|
|
90
90
|
elsif vm.node_id != node_id
|
91
91
|
vm.migrate(node_id)
|
92
92
|
else
|
93
|
-
|
94
|
-
|
93
|
+
parsed_attr = parse_typed_vm(
|
94
|
+
ForemanFogProxmox::HashCollection.new_hash_reject_keys(new_attributes,
|
95
|
+
['volumes_attributes']).merge(type: vm.type), vm.type
|
96
|
+
)
|
95
97
|
config_attributes = compute_config_attributes(parsed_attr)
|
96
98
|
volumes_attributes = new_attributes['volumes_attributes']
|
97
|
-
logger.debug(
|
99
|
+
logger.debug("save_vm(#{uuid}) volumes_attributes=#{volumes_attributes}")
|
98
100
|
volumes_attributes&.each_value { |volume_attributes| save_volume(vm, volume_attributes) }
|
99
101
|
vm.update(config_attributes[:config_attributes])
|
100
102
|
poolid = new_attributes['pool'] if new_attributes.key?('pool')
|