# frozen_string_literal: true
# Copyright 2018 Tristan Robert
# This file is part of ForemanFogProxmox.
# ForemanFogProxmox is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ForemanFogProxmox is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ForemanFogProxmox. If not, see .
require 'fog/proxmox/helpers/disk_helper'
require 'fog/proxmox/helpers/nic_helper'
require 'fog/proxmox/helpers/cpu_helper'
require 'foreman_fog_proxmox/value'
require 'foreman_fog_proxmox/hash_collection'
# Convert a foreman form server hash into a fog-proxmox server attributes hash
module ProxmoxVmConfigHelper
KILO = 1024
MEGA = KILO * KILO
GIGA = KILO * MEGA
def object_to_config_hash(vm, type)
vm_h = ActiveSupport::HashWithIndifferentAccess.new
main_a = ['hostname', 'name', 'vmid']
main = vm.attributes.select { |key, _value| main_a.include? key }
main_a += ['templated']
config = vm.config.attributes.reject { |key, _value| main_a.include?(key) || Fog::Proxmox::DiskHelper.disk?(key) || Fog::Proxmox::NicHelper.nic?(key) }
vm_h = vm_h.merge(main)
vm_h = vm_h.merge('config_attributes': config)
logger.debug(format(_('object_to_config_hash(%s): vm_h=%s'), type: type, vm_h: vm_h))
vm_h
end
def convert_memory_size(config_hash, key)
# default unit memory size is Mb
memory = (config_hash[key].to_i / MEGA).to_s == '0' ? config_hash[key] : (config_hash[key].to_i / MEGA).to_s
config_hash.store(key, memory)
end
def general_a
general_a = ['name', 'node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes']
general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create']
general_a
end
def config_typed_keys(type)
keys = { general: general_a }
main_a = ['name', 'type', 'node_id', 'vmid', 'interfaces', 'mount_points', 'disks']
case type
when 'lxc'
cpu_a = ['arch', 'cpulimit', 'cpuunits', 'cores', 'sockets']
memory_a = ['memory', 'swap']
ostemplate_a = ['ostemplate', 'ostemplate_storage', 'ostemplate_file']
keys.store(:ostemplate, ostemplate_a)
when 'qemu'
cpu_a = ['cpu_type', 'cpu']
cpu_a += ForemanFogProxmox::HashCollection.stringify_keys(Fog::Proxmox::CpuHelper.flags).keys
memory_a = ['memory', 'balloon', 'shares']
cloud_init_a = ['ciuser', 'cipassword', 'searchdomain', 'nameserver']
keys.store(:cloud_init, cloud_init_a)
end
keys.store(:main, main_a)
keys.store(:cpu, cpu_a)
keys.store(:memory, memory_a)
keys
end
def convert_memory_sizes(args)
['memory', 'balloon', 'shares', 'swap'].each { |key| convert_memory_size(args['config_attributes'], key) }
end
def config_general_or_ostemplate_key?(key)
config_typed_keys('lxc')[:general].include?(key) || config_typed_keys(type)[:ostemplate].include?(key)
end
def config_a(type)
config_a = []
case type
when 'qemu'
[:cpu, :memory, :general, :cloud_init].each { |key| config_a += config_typed_keys(type)[key] }
when 'lxc'
[:main].each { |key| config_a += config_typed_keys(type)[key] }
end
config_a
end
def args_a(type)
args_a = []
case type
when 'qemu'
[:general].each { |key| args_a += config_typed_keys(type)[key] }
when 'lxc'
[:general, :ostemplate].each { |key| args_a += config_typed_keys(type)[key] }
end
args_a
end
def config_options(config, args, type)
options = {}
case type
when 'qemu'
options = config.select { |key, _value| config_typed_keys(type)[:cloud_init].include? key }
when 'lxc'
options = parse_ostemplate(args, config)
end
options
end
def parsed_typed_config(args, type)
config = args['config_attributes']
config ||= ForemanFogProxmox::HashCollection.new_hash_reject_keys(args, config_typed_keys(type)[:main])
logger.debug("parsed_typed_config(#{type}): config=#{config}")
config_cpu = config.select { |key, _value| config_typed_keys(type)[:cpu].include? key }
logger.debug("parsed_typed_config(#{type}): config_cpu=#{config_cpu}")
cpu = parse_typed_cpu(config_cpu, type)
memory = parse_typed_memory(config.select { |key, _value| config_typed_keys(type)[:memory].include? key }, type)
parsed_config = config.reject { |key, value| config_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) }
parsed_vm = args.reject { |key, value| args_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) }
parsed_vm = parsed_vm.merge(config_options(config, args, type))
parsed_vm = parsed_vm.merge(parsed_config).merge(cpu).merge(memory)
logger.debug("parsed_typed_config(#{type}): parsed_vm=#{parsed_vm}")
parsed_vm
end
def parse_typed_memory(args, type)
memory = {}
ForemanFogProxmox::HashCollection.remove_empty_values(args)
config_typed_keys(type)[:memory].each { |key| ForemanFogProxmox::HashCollection.add_and_format_element(memory, key.to_sym, args, key, :to_i) }
memory
end
def parse_typed_cpu(args, type)
cpu = {}
ForemanFogProxmox::HashCollection.remove_empty_values(args)
if type == 'qemu'
logger.debug("parse_typed_cpu(#{type}): args=#{args}")
cpu_flattened = Fog::Proxmox::CpuHelper.flatten(args)
cpu_flattened = args[:cpu] if cpu_flattened.empty?
logger.debug("parse_typed_cpu(#{type}): cpu_flattened=#{cpu_flattened}")
ForemanFogProxmox::HashCollection.remove_empty_values(args)
ForemanFogProxmox::HashCollection.remove_keys(args, config_typed_keys('qemu')[:cpu])
args.each_value(&:to_i)
cpu = { cpu: cpu_flattened }
end
config_typed_keys('lxc')[:cpu].each { |key| ForemanFogProxmox::HashCollection.add_and_format_element(cpu, key.to_sym, args, key) } if type == 'lxc'
logger.debug("parse_typed_cpu(#{type}): cpu=#{cpu}")
cpu
end
end