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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/puppet/functions/easy_type/yaml_with_include.rb', line 23
Puppet::Functions.create_function('easy_type::yaml_with_include') do
dispatch :yaml_with_include do
param 'Hash', :options
param 'Any', :context
end
argument_mismatch :missing_path do
param 'Hash', :options
param 'Puppet::LookupContext', :context
end
def yaml_with_include(options, context)
path = options['path']
include_path = [File.dirname(path)] context.cached_file_data(path) do |content|
while contains_include?(content) do
replace_include_with_content(path, content, include_path, context)
end
begin
data = Puppet::Util::Yaml.safe_load(content, [Symbol], path)
if data.is_a?(Hash)
Puppet::Pops::Lookup::HieraConfig.symkeys_to_string(data)
else
msg = _("%{path}: file does not contain a valid yaml hash" % { path: path })
raise Puppet::DataBinding::LookupError, msg if Puppet[:strict] == :error && data != false
Puppet.warning(msg)
{}
end
rescue Puppet::Util::Yaml::YamlLoadError => ex
raise Puppet::DataBinding::LookupError, _("Unable to parse %{message}") % { message: ex.message }
end
end
end
def include_regexp
/^#\s?@include\s?'(\S+)'.*$/.freeze
end
def replace_include_regexp(file)
/^#\s?@include\s+'#{file}'.*$/
end
def contains_include?(content)
content =~ include_regexp
end
def included_files(content)
content.scan(include_regexp).flatten
end
def replace_include_with_content(path, content, include_path, context)
included_files(content).each do | file|
interpolated_file = context.interpolate(file)
context.explain { "Interpolated file '#{file}' to '#{interpolated_file}'"} if file != interpolated_file
include_file = File.expand_path("#{include_path.last}/#{file}")
context.explain { "Including file '#{include_file}' into contents of '#{path}'" }
content.gsub!(replace_include_regexp(file), include_contents(file, include_path.last, context) )
include_path << File.dirname(include_file)
end
end
def include_contents(include_file, include_path, context)
full_path = "#{include_path}/#{include_file}"
if File.exist?(full_path) && File.file?(full_path)
data = context.cached_file_data(full_path)
data.gsub!(/^---$/m,'') data.gsub!(/^\.\.\.$/m,'') data
else
context.explain { "Included file '#{include_path}/#{include_file}' not found or not a file." }
'' end
end
def missing_path(options, context)
"one of 'path', 'paths' 'glob', 'globs' or 'mapped_paths' must be declared in hiera.yaml when using this data_hash function"
end
end
|