<commit_before>module ManageIQ::Providers::Redhat::InfraManager::RefreshParser
  #
  # EMS Inventory Parsing
  #

  def self.ems_inv_to_hashes(inv)
    uids = {}
    result = {:uid_lookup => uids}

    result[:storages], uids[:storages] = storage_inv_to_hashes(inv[:storage])
    result[:clusters], uids[:clusters], result[:resource_pools] = cluster_inv_to_hashes(inv[:cluster])
    result[:hosts], uids[:hosts], uids[:lans], uids[:switches], uids[:guest_devices], uids[:scsi_luns] = host_inv_to_hashes(inv[:host], inv, uids[:clusters], uids[:storages])
    result[:vms], uids[:vms] = vm_inv_to_hashes(inv[:vm] + inv[:template], inv[:storage], uids[:storages], uids[:clusters], uids[:hosts], uids[:lans])
    result[:folders] = datacenter_inv_to_hashes(inv[:datacenter], uids[:clusters], uids[:vms], uids[:storages], uids[:hosts])

    # Link up the root folder
    result[:ems_root] = result[:folders].first

    # Clean up the temporary cluster-datacenter references
    result[:clusters].each { |c| c.delete(:datacenter_id) }

    result
  end

  def self.storage_inv_to_hashes(inv)
    result = []
    result_uids = {:storage_id => {}}
    return result, result_uids if inv.nil?

    inv.each do |storage_inv|
      mor = storage_inv[:id]

      storage_type = storage_inv[:storage][:type].to_s.upcase
      location = if storage_type == 'NFS' || storage_type == 'GLUSTERFS'
                   "#{storage_inv[:storage][:address]}:#{storage_inv[:storage][:path]}"
                 else
                   storage_inv.attributes.fetch_path(:storage, :volume_group, :logical_unit, :id)
                 end

      free        = storage_inv[:available].to_i
      used        = storage_inv[:used].to_i
      total       = free + used
      committed   = storage_inv[:committed].to_i
      uncommitted = total - committed

      ems_ref = ManageIQ::Providers::Redhat::InfraManager.make_ems_ref(storage_inv[:href])

      new_result = {
        :ems_ref             => ems_ref,
        :ems_ref_obj         => ems_ref,
        :name                => storage_inv[:name],
        :store_type          => storage_type,
        :storage_domain_type => storage_inv[:type].try(:downcase),
        :total_space         => total,
        :free_space          => free,
        :uncommitted         => uncommitted,
        :multiplehostaccess  => true,
        :location            => location,
        :master              => storage_inv[:master]
      }

      result << new_result
      result_uids[mor] = new_result
      result_uids[:storage_id][storage_inv[:id]] = new_result
    end
    return result, result_uids
  end

  def self.host_inv_to_hashes(inv, ems_inv, cluster_uids, _storage_uids)
    result = []
    result_uids = {}
    lan_uids = {}
    switch_uids = {}
    guest_device_uids = {}
    scsi_lun_uids = {}
    return result, result_uids, lan_uids, switch_uids, guest_device_uids, scsi_lun_uids if inv.nil?

    inv.each do |host_inv|
      mor = host_inv[:id]

      hostname = host_inv[:address]

      # Check connection state and log potential issues
      power_state = host_inv.attributes.fetch_path(:status, :state)
      if ['down', nil, ''].include?(power_state)
        _log.warn "Host [#{mor}] connection state is [#{power_state.inspect}].  Inventory data may be missing."
      end

      power_state, connection_state = case power_state
                                      when 'up'             then ['on',         'connected']
                                      when 'maintenance'    then [power_state,  'connected']
                                      when 'down'           then ['off',        'disconnected']
                                      when 'non_responsive' then ['unknown',    'connected']
                                      else [power_state, 'disconnected']
                                      end

      # Remove the domain suffix if it is included in the hostname
      hostname = hostname.split(',').first
      # Get the IP address
      ipaddress = host_inv_to_ip(host_inv, hostname) || host_inv[:address]

      # Collect the hardware, networking, and scsi inventories
      switches, switch_uids[mor], lan_uids[mor] = host_inv_to_switch_hashes(host_inv, ems_inv)

      hardware = host_inv_to_hardware_hash(host_inv)
      hardware[:guest_devices], guest_device_uids[mor] = host_inv_to_guest_device_hashes(host_inv, switch_uids[mor], ems_inv)
      hardware[:networks] = host_inv_to_network_hashes(host_inv, guest_device_uids[mor])

      ipmi_address = nil
      if host_inv.attributes.fetch_path(:power_management, :type).to_s.include?('ipmi')
        ipmi_address = host_inv.attributes.fetch_path(:power_management, :address)
      end

      ems_ref = ManageIQ::Providers::Redhat::InfraManager.make_ems_ref(host_inv[:href])

      new_result = {
        :type             => 'ManageIQ::Providers::Redhat::InfraManager::Host',
        :ems_ref          => ems_ref,
        :ems_ref_obj      => ems_ref,
        :name             => host_inv[:name] || hostname,
        :hostname         => hostname,
        :ipaddress        => ipaddress,
        :uid_ems          => host_inv[:id],
        :vmm_vendor       => 'redhat',
        :vmm_product      => host_inv[:type],
        :connection_state => connection_state,
        :power_state      => power_state,

        :operating_system => host_inv_to_os_hash(host_inv, hostname),

        :ems_cluster      => cluster_uids[host_inv.attributes.fetch_path(:cluster, :id)],
        :hardware         => hardware,
        :switches         => switches,

      }
      new_result[:ipmi_address] = ipmi_address unless ipmi_address.blank?

      result << new_result
      result_uids[mor] = new_result
    end
    return result, result_uids, lan_uids, switch_uids, guest_device_uids, scsi_lun_uids
  end

  def self.host_inv_to_ip(inv, hostname = nil)
    _log.debug("IP lookup for host in VIM inventory data...")
    ipaddress = nil
<commit_msg>Reports Host OS version and exact type for RHEV-M<commit_after>module ManageIQ::Providers::Redhat::InfraManager::RefreshParser
  #
  # EMS Inventory Parsing
  #

  def self.ems_inv_to_hashes(inv)
    uids = {}
    result = {:uid_lookup => uids}

    result[:storages], uids[:storages] = storage_inv_to_hashes(inv[:storage])
    result[:clusters], uids[:clusters], result[:resource_pools] = cluster_inv_to_hashes(inv[:cluster])
    result[:hosts], uids[:hosts], uids[:lans], uids[:switches], uids[:guest_devices], uids[:scsi_luns] = host_inv_to_hashes(inv[:host], inv, uids[:clusters], uids[:storages])
    result[:vms], uids[:vms] = vm_inv_to_hashes(inv[:vm] + inv[:template], inv[:storage], uids[:storages], uids[:clusters], uids[:hosts], uids[:lans])
    result[:folders] = datacenter_inv_to_hashes(inv[:datacenter], uids[:clusters], uids[:vms], uids[:storages], uids[:hosts])

    # Link up the root folder
    result[:ems_root] = result[:folders].first

    # Clean up the temporary cluster-datacenter references
    result[:clusters].each { |c| c.delete(:datacenter_id) }

    result
  end

  def self.storage_inv_to_hashes(inv)
    result = []
    result_uids = {:storage_id => {}}
    return result, result_uids if inv.nil?

    inv.each do |storage_inv|
      mor = storage_inv[:id]

      storage_type = storage_inv[:storage][:type].to_s.upcase
      location = if storage_type == 'NFS' || storage_type == 'GLUSTERFS'
                   "#{storage_inv[:storage][:address]}:#{storage_inv[:storage][:path]}"
                 else
                   storage_inv.attributes.fetch_path(:storage, :volume_group, :logical_unit, :id)
                 end

      free        = storage_inv[:available].to_i
      used        = storage_inv[:used].to_i
      total       = free + used
      committed   = storage_inv[:committed].to_i
      uncommitted = total - committed

      ems_ref = ManageIQ::Providers::Redhat::InfraManager.make_ems_ref(storage_inv[:href])

      new_result = {
        :ems_ref             => ems_ref,
        :ems_ref_obj         => ems_ref,
        :name                => storage_inv[:name],
        :store_type          => storage_type,
        :storage_domain_type => storage_inv[:type].try(:downcase),
        :total_space         => total,
        :free_space          => free,
        :uncommitted         => uncommitted,
        :multiplehostaccess  => true,
        :location            => location,
        :master              => storage_inv[:master]
      }

      result << new_result
      result_uids[mor] = new_result
      result_uids[:storage_id][storage_inv[:id]] = new_result
    end
    return result, result_uids
  end

  def self.host_inv_to_hashes(inv, ems_inv, cluster_uids, _storage_uids)
    result = []
    result_uids = {}
    lan_uids = {}
    switch_uids = {}
    guest_device_uids = {}
    scsi_lun_uids = {}
    return result, result_uids, lan_uids, switch_uids, guest_device_uids, scsi_lun_uids if inv.nil?

    inv.each do |host_inv|
      mor = host_inv[:id]

      hostname = host_inv[:address]

      # Check connection state and log potential issues
      power_state = host_inv.attributes.fetch_path(:status, :state)
      if ['down', nil, ''].include?(power_state)
        _log.warn "Host [#{mor}] connection state is [#{power_state.inspect}].  Inventory data may be missing."
      end

      power_state, connection_state = case power_state
                                      when 'up'             then ['on',         'connected']
                                      when 'maintenance'    then [power_state,  'connected']
                                      when 'down'           then ['off',        'disconnected']
                                      when 'non_responsive' then ['unknown',    'connected']
                                      else [power_state, 'disconnected']
                                      end

      # Remove the domain suffix if it is included in the hostname
      hostname = hostname.split(',').first
      # Get the IP address
      ipaddress = host_inv_to_ip(host_inv, hostname) || host_inv[:address]

      # Collect the hardware, networking, and scsi inventories
      switches, switch_uids[mor], lan_uids[mor] = host_inv_to_switch_hashes(host_inv, ems_inv)

      hardware = host_inv_to_hardware_hash(host_inv)
      hardware[:guest_devices], guest_device_uids[mor] = host_inv_to_guest_device_hashes(host_inv, switch_uids[mor], ems_inv)
      hardware[:networks] = host_inv_to_network_hashes(host_inv, guest_device_uids[mor])

      ipmi_address = nil
      if host_inv.attributes.fetch_path(:power_management, :type).to_s.include?('ipmi')
        ipmi_address = host_inv.attributes.fetch_path(:power_management, :address)
      end

      host_os_version = host_inv[:os][:version] if host_inv[:os]
      ems_ref = ManageIQ::Providers::Redhat::InfraManager.make_ems_ref(host_inv[:href])
      new_result = {
        :type             => 'ManageIQ::Providers::Redhat::InfraManager::Host',
        :ems_ref          => ems_ref,
        :ems_ref_obj      => ems_ref,
        :name             => host_inv[:name] || hostname,
        :hostname         => hostname,
        :ipaddress        => ipaddress,
        :uid_ems          => host_inv[:id],
        :vmm_vendor       => 'redhat',
        :vmm_product      => host_inv[:type],
        :vmm_version      => extract_host_version(host_os_version),
        :vmm_buildnumber  => (host_os_version[:build] if host_os_version),
        :connection_state => connection_state,
        :power_state      => power_state,

        :operating_system => host_inv_to_os_hash(host_inv, hostname),

        :ems_cluster      => cluster_uids[host_inv.attributes.fetch_path(:cluster, :id)],
        :hardware         => hardware,
        :switches         => switches,

      }
      new_result[:ipmi_address] = ipmi_address unless ipmi_address.blank?

      result << new_result
      result_uids[mor] = new_result
    end
    return result, result_uids, lan_uids, switch_uids, guest_device_uids, scsi_lun_uids
  end

  def self.extract_host_version(host_os_version)
    return unless host_os_version && host_os_version[:major]

    version = host_os_version[:major]
    version = "#{version}.#{host_os_version[:minor]}" if host_os_version[:minor]
    version
  end

  def self.host_inv_to_ip(inv, hostname = nil)
    _log.debug("IP lookup for host in VIM inventory data...")
    ipaddress = nil

{'fraction_non_alphanumeric': 0.11765655261459006, 'fraction_numerical': 0.0, 'mean_word_length': 2.5932154247608, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3316451', 'n_tokens_mistral': 3990, 'n_tokens_neox': 3897, 'n_words': 712}