foreman_fog_proxmox 0.14.0 → 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 +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')
|