-
Notifications
You must be signed in to change notification settings - Fork 3
/
plugin_helper.rb
64 lines (62 loc) · 2.02 KB
/
plugin_helper.rb
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
module RubyPluginHelper
# 'template' is the value of `target_mapping` from the inventory
# Returns an array of strings which are the lookups from the template
def required_data(template)
lookups = []
postwalk_vals(template) do |value|
# First collect the lookups to make
lookups << value if value.is_a?(String)
value
end
lookups.uniq.map { |lookup| lookup.split('.') }
end
# 'template' is the value of `target_mapping` from the inventory
# 'lookup' is a hash of lookups to their resolved values for a single record
# Returns an array of hashes to be sent to the inventory
def apply_mapping(template, lookup, accept_nil = false)
postwalk_vals(template) do |value|
if value.is_a?(String)
segments = value.split('.').map do |segment|
begin
# Turn it into an integer if we can
Integer(segment)
rescue ArgumentError
# Otherwise return the value
segment
end
end
answer = lookup.dig(*segments)
if answer.nil? && !accept_nil
msg = "Could not resolve lookup for #{value}"
raise StandardError, msg
end
answer
elsif value.is_a?(Array) || value.is_a?(Hash)
value
else
msg = 'target_mapping values must be a string, array, or hash. ' \
"Got #{value.class}"
raise StandardError, msg
end
end
end
# Accepts a Data object and returns a copy with all hash and array values
# modified by the given block. Descendants are modified before their
# parents.
def postwalk_vals(data, skip_top = false, &block)
new_data = if data.is_a? Hash
data.each_with_object({}) do |(k, v), acc|
acc[k] = postwalk_vals(v, &block)
end
elsif data.is_a? Array
data.map { |v| postwalk_vals(v, &block) }
else
data
end
if skip_top
new_data
else
yield(new_data)
end
end
end