Class: OctofactsUpdater::FactIndex

Inherits:
Object
  • Object
show all
Defined in:
lib/octofacts_updater/fact_index.rb

Constant Summary collapse

TOP_LEVEL_NODES_KEY =

We will create a pseudo-fact that simply lists all of the nodes that were considered in the index. Define the name of that pseudo-fact here.

"_nodes".freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data = {}, filename: nil) ⇒ FactIndex

Constructor.

data - A Hash of existing index data. filename - Optionally, a String with a file name to write the index to



47
48
49
50
# File 'lib/octofacts_updater/fact_index.rb', line 47

def initialize(data = {}, filename: nil)
  @index_data = data
  @filename = filename
end

Instance Attribute Details

#index_dataObject (readonly)

Returns the value of attribute index_data.



27
28
29
# File 'lib/octofacts_updater/fact_index.rb', line 27

def index_data
  @index_data
end

Class Method Details

.load_file(filename) ⇒ Object

Load an index from the YAML file.

filename - A String with the file to be loaded.

Returns a OctofactsUpdater::FactIndex object.



34
35
36
37
38
39
40
41
# File 'lib/octofacts_updater/fact_index.rb', line 34

def self.load_file(filename)
  unless File.file?(filename)
    raise Errno::ENOENT, "load_index cannot load #{filename.inspect}"
  end

  data = YAML.safe_load(File.read(filename))
  new(data, filename: filename)
end

Instance Method Details

#add(fact_name, fixtures) ⇒ Object

Add a fact to the index. If the fact already exists in the index, this will overwrite it.

fact_name - A String with the name of the fact fixtures - An Array with fact fixtures (must respond to .facts and .hostname)



56
57
58
59
60
61
62
63
64
# File 'lib/octofacts_updater/fact_index.rb', line 56

def add(fact_name, fixtures)
  @index_data[fact_name] ||= {}
  fixtures.each do |fixture|
    fact_value = get_fact(fixture, fact_name)
    next if fact_value.nil?
    @index_data[fact_name][fact_value] ||= []
    @index_data[fact_name][fact_value] << fixture.hostname
  end
end

#nodes(quick_mode = true) ⇒ Object

Get a list of all of the nodes in the index. This supports a quick mode (default) where the TOP_LEVEL_NODES_KEY key is used, and a more detailed mode where this digs through each indexed fact and value to build a list of nodes.

quick_mode - Boolean whether to use quick mode (default=true)

Returns an Array of nodes whose facts are indexed.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/octofacts_updater/fact_index.rb', line 73

def nodes(quick_mode = true)
  if quick_mode && @index_data.key?(TOP_LEVEL_NODES_KEY)
    return @index_data[TOP_LEVEL_NODES_KEY]
  end

  seen_hosts = Set.new
  @index_data.each do |fact_name, fact_values|
    next if fact_name == TOP_LEVEL_NODES_KEY
    fact_values.each do |_fact_value, nodes|
      seen_hosts.merge(nodes)
    end
  end
  seen_hosts.to_a.sort
end

#recursive_sort(object_in) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/octofacts_updater/fact_index.rb', line 112

def recursive_sort(object_in)
  if object_in.is_a?(Hash)
    object_out = {}
    object_in.keys.sort.each { |k| object_out[k] = recursive_sort(object_in[k]) }
    object_out
  elsif object_in.is_a?(Array)
    object_in.sort.map { |v| recursive_sort(v) }
  else
    object_in
  end
end

#reindex(facts_to_index, fixtures) ⇒ Object

Rebuild an index with a specified list of facts. This will remove any indexed facts that are not on the list of facts to use.

facts_to_index - An Array of Strings with facts to index fixtures - An Array with fact fixtures (must respond to .facts and .hostname)



93
94
95
96
97
# File 'lib/octofacts_updater/fact_index.rb', line 93

def reindex(facts_to_index, fixtures)
  @index_data = {}
  facts_to_index.each { |fact| add(fact, fixtures) }
  set_top_level_nodes_fact(fixtures)
end

#set_top_level_nodes_fact(fixtures) ⇒ Object

Create the top level nodes pseudo-fact.

fixtures - An Array with fact fixtures (must respond to .hostname)



102
103
104
# File 'lib/octofacts_updater/fact_index.rb', line 102

def set_top_level_nodes_fact(fixtures)
  @index_data[TOP_LEVEL_NODES_KEY] = fixtures.map { |f| f.hostname }.sort
end

#to_yamlObject

Get YAML representation of the index. This sorts the hash and any arrays without modifying the object.



108
109
110
# File 'lib/octofacts_updater/fact_index.rb', line 108

def to_yaml
  YAML.dump(recursive_sort(index_data))
end

#write_file(filename = nil) ⇒ Object

Write the fact index out to a YAML file.

filename - A String with the file to write (defaults to filename from constructor if available)



127
128
129
130
131
132
133
# File 'lib/octofacts_updater/fact_index.rb', line 127

def write_file(filename = nil)
  filename ||= @filename
  unless filename.is_a?(String)
    raise ArgumentError, "Called write_file() for fact_index without a filename"
  end
  File.open(filename, "w") { |f| f.write(to_yaml) }
end