1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
# The module that handles actually searching for nodes. This is only included
# in the Node class, but it's completely stand-alone functionality, so it's
# worth making it a separate module to simplify testing.
module Puppet::Node::Searching
# Retrieve a node from the node source, with some additional munging
# thrown in for kicks.
def search(key)
return nil unless key
if node = cached?(key)
return node
end
facts = node_facts(key)
node = nil
names = node_names(key, facts)
names.each do |name|
name = name.to_s if name.is_a?(Symbol)
if node = get(name)
#Puppet.info "Found %s in %s" % [name, @source]
break
end
end
# If they made it this far, we haven't found anything, so look for a
# default node.
unless node or names.include?("default")
if node = get("default")
Puppet.notice "Using default node for %s" % key
end
end
if node
node.names = names
cache(node)
return node
else
return nil
end
end
private
# Store the node to make things a bit faster.
def cache(node)
@node_cache ||= {}
@node_cache[node.name] = node
end
# If the node is cached, return it.
def cached?(name)
# Don't use cache when the filetimeout is set to 0
return false if [0, "0"].include?(Puppet[:filetimeout])
@node_cache ||= {}
if node = @node_cache[name] and Time.now - node.time < Puppet[:filetimeout]
return node
else
return false
end
end
# Look up the node facts from our fact handler.
def node_facts(key)
if facts = Puppet::Node::Facts.get(key)
facts.values
else
{}
end
end
# Calculate the list of node names we should use for looking
# up our node.
def node_names(key, facts = nil)
facts ||= node_facts(key)
names = []
if hostname = facts["hostname"]
unless hostname == key
names << hostname
end
else
hostname = key
end
if fqdn = facts["fqdn"]
hostname = fqdn
names << fqdn
end
# Make sure both the fqdn and the short name of the
# host can be used in the manifest
if hostname =~ /\./
names << hostname.sub(/\..+/,'')
elsif domain = facts['domain']
names << hostname + "." + domain
end
# Sort the names inversely by name length.
names.sort! { |a,b| b.length <=> a.length }
# And make sure the key is first, since that's the most
# likely usage.
([key] + names).uniq
end
end
|