Class: Facter::QueryParser

Inherits:
Object
  • Object
show all
Defined in:
lib/facter/framework/parsers/query_parser.rb

Class Method Summary collapse

Class Method Details

.construct_filter_tokens(query_tokens, query_token_range) ⇒ Object



108
109
110
111
112
# File 'lib/facter/framework/parsers/query_parser.rb', line 108

def construct_filter_tokens(query_tokens, query_token_range)
  (query_tokens - query_tokens[query_token_range]).map do |token|
    token =~ /^[0-9]+$/ ? token.to_i : token
  end
end

.construct_loaded_fact(query_tokens, query_token_range, loaded_fact) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/facter/framework/parsers/query_parser.rb', line 96

def construct_loaded_fact(query_tokens, query_token_range, loaded_fact)
  filter_tokens = construct_filter_tokens(query_tokens, query_token_range)
  user_query = @query_list.any? ? query_tokens.join('.') : ''
  fact_name = loaded_fact.name.to_s
  klass_name = loaded_fact.klass
  type = loaded_fact.type
  sf = SearchedFact.new(fact_name, klass_name, filter_tokens, user_query, type)
  sf.file = loaded_fact.file

  sf
end

.found_fact?(fact_name, query_fact) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
92
93
94
# File 'lib/facter/framework/parsers/query_parser.rb', line 84

def found_fact?(fact_name, query_fact)
  fact_with_wildcard = fact_name.include?('.*') && !query_fact.include?('.')

  processed_equery_fact = query_fact.gsub('\\', '\\\\\\\\')

  return false if fact_with_wildcard && !query_fact.match("^#{fact_name}$")

  return false unless fact_with_wildcard || fact_name.match("^#{processed_equery_fact}($|\\.)")

  true
end

.get_facts_matching_tokens(query_tokens, query_token_range, loaded_fact_hash) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/facter/framework/parsers/query_parser.rb', line 67

def get_facts_matching_tokens(query_tokens, query_token_range, loaded_fact_hash)
  @log.debug "Checking query tokens #{query_tokens[query_token_range].join('.')}"
  resolvable_fact_list = []

  loaded_fact_hash.each do |loaded_fact|
    query_fact = query_tokens[query_token_range].join('.')

    next unless found_fact?(loaded_fact.name, query_fact)

    searched_fact = construct_loaded_fact(query_tokens, query_token_range, loaded_fact)
    resolvable_fact_list << searched_fact
  end

  @log.debug "List of resolvable facts: #{resolvable_fact_list.inspect}"
  resolvable_fact_list
end

.no_user_query(loaded_facts) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/facter/framework/parsers/query_parser.rb', line 41

def no_user_query(loaded_facts)
  searched_facts = []
  loaded_facts.each do |loaded_fact|
    searched_facts << SearchedFact.new(loaded_fact.name, loaded_fact.klass, [], '', loaded_fact.type)
  end
  searched_facts
end

.parse(query_list, loaded_fact) ⇒ Object

Searches for facts that could resolve a user query. There are 4 types of facts:

root facts
  e.g. networking
child facts
  e.g. networking.dhcp
composite facts
  e.g. networking.interfaces.en0.bindings.address
regex facts (legacy)
  e.g. impaddress_end160

Because a root fact will always be resolved by a collection of child facts, we can return one or more child facts for each parent.

query - is the user input used to search for facts loaded_fact - is a list with all facts for the current operating system

Returns a list of SearchedFact objects that resolve the users query.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/facter/framework/parsers/query_parser.rb', line 25

def parse(query_list, loaded_fact)
  matched_facts = []
  @log.debug "User query is: #{query_list}"
  @query_list = query_list

  return no_user_query(loaded_fact) unless query_list.any?

  query_list.each do |query|
    @log.debug "Query is #{query}"
    found_facts = search_for_facts(query, loaded_fact)
    matched_facts << found_facts
  end

  matched_facts.flatten(1)
end

.search_for_facts(query, loaded_fact_hash) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/facter/framework/parsers/query_parser.rb', line 49

def search_for_facts(query, loaded_fact_hash)
  resolvable_fact_list = []
  query = query.to_s
  query_tokens = query.end_with?('.*') ? [query] : query.split('.')
  size = query_tokens.size

  size.times do |i|
    query_token_range = 0..size - i - 1
    resolvable_fact_list = get_facts_matching_tokens(query_tokens, query_token_range, loaded_fact_hash)

    return resolvable_fact_list if resolvable_fact_list.any?
  end

  resolvable_fact_list << SearchedFact.new(query, nil, [], query, :nil) if resolvable_fact_list.empty?

  resolvable_fact_list
end