Skip to content

Commit

Permalink
Fixes #36715 - Add methods to speed up host fact retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylenz committed Sep 1, 2023
1 parent e30c9d5 commit b2c0037
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 2 deletions.
29 changes: 29 additions & 0 deletions app/models/host/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class Base < ApplicationRecord

default_scope -> { where(taxonomy_conditions) }

def self.with_facts
includes(:fact_names, :fact_values)
end

def self.taxonomy_conditions
conditions = {}
if Organization.current.nil? && User.current.present? && !User.current.admin?
Expand Down Expand Up @@ -228,6 +232,31 @@ def facts_hash
end
alias_method :facts, :facts_hash

apipie :method, 'List only specific facts about the host.' do
desc 'Same as +facts+ macro, but only returns facts with given names.
If fact_names and fact_values are already loaded via :includes, this macro will not perform any additional queries.'
returns Hash, desc: 'A hash of facts, keys are fact names, values are fact values'
example '@host.facts_with_names([\'dmi::memory::size\', \'net::interface::eth0\']) # => { "dmi::memory::size"=>"16 GB", "net::interface::eth0"=>"00:50:56:8a:5c:3c" }', desc: 'Getting specific facts'
end
def facts_with_names(names_query = [])
filtered_names = Set.new(names_query)
result = {}
names = {} # { fact_name_id => fact_name_name}
fact_names.each do |fact_name|
next unless filtered_names.empty? || filtered_names.include?(fact_name.name)
names[fact_name.id] = fact_name.name
end
f_values = {} # { fact_name_id => fact_value_value}
fact_values.each do |fact_value|
next unless names[fact_value.fact_name_id]
f_values[fact_value.fact_name_id] = fact_value.value
end
names.each do |id, name|
result[name] = f_values[id]
end
result
end

def ==(comparison_object)
super ||
comparison_object.is_a?(Host::Base) &&
Expand Down
2 changes: 1 addition & 1 deletion app/models/host/managed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class Jail < ::Safemode::Jail
:model, :certname, :capabilities, :provider, :subnet, :subnet6, :token, :location, :organization, :provision_method,
:image_build?, :pxe_build?, :otp, :realm, :nil?, :indent, :primary_interface,
:provision_interface, :interfaces, :bond_interfaces, :bridge_interfaces, :interfaces_with_identifier,
:managed_interfaces, :facts, :facts_hash, :root_pass, :sp_name, :sp_ip, :sp_mac, :sp_subnet, :use_image,
:managed_interfaces, :facts, :facts_hash, :facts_with_names, :root_pass, :sp_name, :sp_ip, :sp_mac, :sp_subnet, :use_image,
:multiboot, :jumpstart_path, :install_path, :miniroot, :medium, :bmc_nic, :templates_used, :owner, :owner_type,
:ssh_authorized_keys, :pxe_loader, :global_status, :global_status_label, :get_status, :puppetca_token, :last_report, :build?, :smart_proxies, :host_param,
:virtual, :ram, :sockets, :cores, :params, :pxe_loader_efi?, :comment
Expand Down
5 changes: 5 additions & 0 deletions app/services/foreman/renderer/scope/macros/loaders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ module Loaders
end
end

def load_hosts_with_facts(fact_names:, search:, permission:, batch: 1_000, includes: nil, limit: nil, select: nil, joins: nil, where: nil, preload: nil)
incl = [:fact_values, :fact_names] + (includes || [])
load_hosts(search: search, permission: permission, batch: batch, includes: incl, limit: limit, select: select, joins: joins, where: where, preload: preload)
end

private

# returns a batched relation, use either
Expand Down
2 changes: 1 addition & 1 deletion test/models/host_jail_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def test_jail_should_include_these_methods
:organization, :url_for_boot, :hostgroup, :compute_resource, :domain, :ip, :mac, :shortname, :architecture,
:model, :certname, :capabilities, :provider, :subnet, :token, :location, :organization, :provision_method, :image_build?,
:pxe_build?, :otp, :realm, :nil?, :indent, :sp_name, :sp_ip, :sp_mac, :sp_subnet, :facts,
:facts_hash, :bmc_nic, :templates_used, :owner, :owner_type, :ssh_authorized_keys, :last_report]
:facts_with_names, :facts_hash, :bmc_nic, :templates_used, :owner, :owner_type, :ssh_authorized_keys, :last_report]

allowed.each do |m|
assert Host::Managed::Jail.allowed?(m), "Method #{m} is not available in Host::Managed::Jail while should be allowed."
Expand Down

0 comments on commit b2c0037

Please sign in to comment.