# 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 def object_to_config_hash(vm, type) vm_h = ActiveSupport::HashWithIndifferentAccess.new main_a = ['vmid', 'type'] main = vm.attributes.select { |key, _value| main_a.include? key.to_s } main_a += ['templated'] config = vm.config.attributes.reject do |key, _value| main_a.include?(key.to_s) || Fog::Proxmox::DiskHelper.disk?(key) || Fog::Proxmox::NicHelper.nic?(key) end vm_h = vm_h.merge(main) vm_h = vm_h.merge('config_attributes': config) logger.debug("object_to_config_hash(#{type}): vm_h=#{vm_h}") vm_h end def general_a(type) general_a = ['node_id', 'type', 'config_attributes', 'volumes_attributes', 'interfaces_attributes', 'image_id'] general_a += ['firmware_type', 'provision_method', 'container_volumes', 'server_volumes', 'start_after_create'] general_a += ['name'] if type == 'lxc' general_a end def config_typed_keys(type) keys = { general: general_a(type) } main_a = ['name', 'type', 'node_id', 'vmid', 'interfaces', 'mount_points', 'disks'] case type when 'lxc' cpu_a = ['arch', 'cpulimit', 'cpuunits'] 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 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 do |key, value| config_a(type).include?(key) || ForemanFogProxmox::Value.empty?(value) end 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) ForemanFogProxmox::HashCollection.remove_empty_values(args) logger.debug("parse_typed_memory(#{type}): args=#{args}") # Convert balloon value from bytes to expected MiB if its not already if args.key?('balloon') mb = (args['balloon'].to_i / 1024**2).to_s args['balloon'] = (mb == '0') ? args['balloon'] : mb end args end def parse_typed_cpu(args, type) cpu = {} ForemanFogProxmox::HashCollection.remove_empty_values(args) case type when '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}") args.each_value(&:to_i) cpu = { cpu: cpu_flattened } when 'lxc' config_typed_keys('lxc')[:cpu].each do |key| ForemanFogProxmox::HashCollection.add_and_format_element(cpu, key.to_sym, args, key) end end logger.debug("parse_typed_cpu(#{type}): cpu=#{cpu}") cpu end end