Skip to content

Commit 2340d1b

Browse files
committed
Add Hiera overrides
It is possible to explode the Hiera overrides and generate a table in the reference.
1 parent 8a4a87e commit 2340d1b

File tree

8 files changed

+215
-0
lines changed

8 files changed

+215
-0
lines changed

lib/puppet-strings/hiera.rb

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
module PuppetStrings
4+
module Hiera
5+
require_relative 'hiera/hierarchy_data_path'
6+
require_relative 'hiera/data'
7+
8+
def self.load_config
9+
PuppetStrings::Hiera::Data.new('hiera.yaml')
10+
end
11+
end
12+
end

lib/puppet-strings/hiera/data.rb

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# frozen_string_literal: true
2+
3+
module PuppetStrings::Hiera
4+
class Data
5+
attr_reader :config_path, :data_paths
6+
7+
def initialize(config_path)
8+
@config_path = config_path
9+
@data_paths = []
10+
11+
load_config
12+
end
13+
14+
def files
15+
@files ||= begin
16+
result = {}
17+
18+
data_paths.each do |dp|
19+
dp.matches.each do |file, interpolations|
20+
unless result.key?(file)
21+
result[file] = interpolations
22+
end
23+
end
24+
end
25+
26+
result
27+
end
28+
end
29+
30+
# @return [Hash[String, Hash[String, Any]]]
31+
# Full variable (class::var) -> filename: value
32+
def overrides
33+
@overrides ||= begin
34+
overrides = {}
35+
36+
files.each_key do |file|
37+
data = YAML.load(File.read(file))
38+
data.each do |key, value|
39+
overrides[key] ||= {}
40+
overrides[key][file] = value
41+
end
42+
end
43+
44+
overrides
45+
end
46+
end
47+
48+
# @return [Hash[String, Hash[String, Any]]]
49+
# variable -> filename: value
50+
def for_class(class_name)
51+
result = {}
52+
overrides.each do |key, value|
53+
override_class_name, _, variable = key.rpartition('::')
54+
if override_class_name == class_name
55+
result[variable] = value
56+
end
57+
end
58+
result
59+
end
60+
61+
def to_s
62+
config_path
63+
end
64+
65+
private
66+
67+
def load_config
68+
return unless File.exist?(config_path)
69+
70+
config = YAML.load(File.read(config_path))
71+
72+
unless config['version'] == 5
73+
raise "Unsupported version '#{config['version']}'"
74+
end
75+
76+
hierarchy = config['hierarchy']
77+
return unless hierarchy
78+
79+
hierarchy.each do |level|
80+
data_hash = level['data_hash'] || config['defaults']['data_hash']
81+
next unless data_hash == 'yaml_data'
82+
83+
datadir = level['datadir'] || config['defaults']['datadir']
84+
85+
if level['path']
86+
data_paths << PuppetStrings::Hiera::HierarchyDataPath.new(datadir, level['path'])
87+
elsif level['paths']
88+
level['paths'].each do |path|
89+
data_paths << PuppetStrings::Hiera::HierarchyDataPath.new(datadir, path)
90+
end
91+
end
92+
end
93+
end
94+
end
95+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
module PuppetStrings::Hiera
4+
class HierarchyDataPath
5+
attr_reader :datadir, :path, :regex, :mapping
6+
7+
def initialize(datadir, path)
8+
@datadir = datadir
9+
@path = path
10+
@regex, @mapping = HierarchyDataPath.path2regex(path)
11+
end
12+
13+
def matches
14+
result = {}
15+
16+
Dir.chdir(datadir) do
17+
Dir['**'].each do |entry|
18+
next unless File.file?(entry)
19+
20+
regex.match(entry) do |match|
21+
full_path = File.join(datadir, entry)
22+
interpolations = {}
23+
24+
mapping.each do |name, interpolation|
25+
interpolations[interpolation] = match.named_captures[name]
26+
end
27+
28+
result[full_path] = interpolations
29+
end
30+
end
31+
end
32+
33+
result
34+
end
35+
36+
def self.path2regex(path)
37+
mapping = {}
38+
39+
intermediate_result = path
40+
41+
# First pass - intermediate replacements
42+
path.scan(/%{[^}]+}/).each_with_index do |interpolation, i|
43+
replacement = "X_INTERPOLATION_#{i}_X"
44+
mapping[replacement] = interpolation[2..-2]
45+
intermediate_result = intermediate_result.sub(interpolation, replacement)
46+
end
47+
48+
# Second pass - escape any special chars
49+
escaped = Regexp.escape(intermediate_result)
50+
51+
# Third pass - replacement intermediates with regex
52+
mapping.each_key do |replacement|
53+
escaped = escaped.sub(replacement, "(?<#{replacement}>.+)")
54+
end
55+
56+
[Regexp.new(escaped), mapping]
57+
end
58+
59+
def to_s
60+
File.join(datadir, path)
61+
end
62+
end
63+
end

lib/puppet-strings/markdown/base.rb

+12
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ def defaults
139139
@registry[:defaults] unless @registry[:defaults].nil?
140140
end
141141

142+
# Overrides from Hiera
143+
#
144+
# Hiera overrides only apply to classes. Each entry is a tuple of the
145+
# filename it's defined in, a mapping of interpolations that were applied
146+
# in the filename and the value inside the file.
147+
#
148+
# @return [Array[Tuple[String, Hash[String, String], Any]]]
149+
# Any overrides from Hiera.
150+
def hiera_overrides
151+
[]
152+
end
153+
142154
# @return [Hash] information needed for the table of contents
143155
def toc_info
144156
{

lib/puppet-strings/markdown/puppet_class.rb

+18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ def initialize(registry)
99
super(registry, 'class')
1010
end
1111

12+
def hiera_overrides
13+
@hiera_overrides ||= begin
14+
hiera = PuppetStrings::Hiera.load_config
15+
overrides = hiera.for_class(name)
16+
17+
result = {}
18+
19+
overrides.each do |variable, files|
20+
result[variable] = files.map do |filename, value|
21+
interpolations = hiera.files[filename]
22+
[filename, interpolations, value]
23+
end
24+
end
25+
26+
result
27+
end
28+
end
29+
1230
def render
1331
super(@template)
1432
end

lib/puppet-strings/markdown/templates/classes_and_defines.erb

+13
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ Options:
8181
<% if defaults && defaults[param[:name]] -%>
8282
Default value: `<%= value_string(defaults[param[:name]]) %>`
8383

84+
<% end -%>
85+
<% if hiera_overrides[param[:name]] -%>
86+
<details>
87+
<summary>Hiera overrides in a detailed table</summary>
88+
89+
| Filename | Interpolations | Value |
90+
|----------|----------------|-------|
91+
<% hiera_overrides[param[:name]].each do |filename, interpolations, value| -%>
92+
| `<%= filename %>` | <%= interpolations.map { |i, v| "`#{i}`: `#{v}`" }.join("<br>") %> | `<%= value %>` |
93+
<% end -%>
94+
95+
</details>
96+
8497
<% end -%>
8598
<% end -%>
8699
<% end -%>

lib/puppet-strings/yard.rb

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module PuppetStrings::Yard
88
require 'puppet-strings/yard/handlers'
99
require 'puppet-strings/yard/tags'
1010
require 'puppet-strings/yard/parsers'
11+
require 'puppet-strings/hiera'
1112
require 'puppet-strings/monkey_patches/display_object_command'
1213

1314
# Sets up YARD for use with puppet-strings.

lib/puppet-strings/yard/code_objects/class.rb

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def to_hash
5555
hash[:docstring] = PuppetStrings::Yard::Util.docstring_to_hash(docstring)
5656
defaults = Hash[*parameters.reject{ |p| p[1].nil? }.flatten]
5757
hash[:defaults] = defaults unless defaults.nil? || defaults.empty?
58+
#hash[:hiera_overrides] = hiera_overrides if hiera_overrides.any?
5859
hash[:source] = source unless source.nil? || source.empty?
5960
hash
6061
end

0 commit comments

Comments
 (0)