Skip to content

Commit

Permalink
support for hiera datadir
Browse files Browse the repository at this point in the history
  • Loading branch information
h0tw1r3 committed Jan 20, 2024
1 parent b91c790 commit eb6d93d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 17 deletions.
27 changes: 20 additions & 7 deletions lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,26 @@ def load_data(path, content)
end

PuppetLint.new_check(:ghostbuster_hiera_files) do
def hiera
@hiera ||= YAML.load_file(ENV['HIERA_YAML_PATH'] || '/etc/puppetlabs/code/hiera.yaml')
end

def default_datadir
(hiera.dig('defaults', 'datadir') || 'hieradata')

Check failure on line 21 in lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb

View workflow job for this annotation

GitHub Actions / rubocop

Style/RedundantParentheses: Don't use parentheses around a logical expression.
end

def path_in_datadirs?(path)
@data_dirs ||= hiera['hierarchy'].map { |h| (h['datadir'] || default_datadir).chomp('/') }.uniq
return path.match?(%{\./#{Regexp.union(@data_dirs)}/})

Check failure on line 26 in lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb

View workflow job for this annotation

GitHub Actions / rubocop

Style/RedundantReturn: Redundant `return` detected. (https://rubystyle.guide#no-explicit-return)

Check failure on line 26 in lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb

View workflow job for this annotation

GitHub Actions / rubocop

Style/PercentLiteralDelimiters: `%`-literals should be delimited by `(` and `)`. (https://rubystyle.guide#percent-literal-braces)

Check failure on line 26 in lib/puppet-lint/plugins/check_ghostbuster_hiera_files.rb

View workflow job for this annotation

GitHub Actions / rubocop

Style/RedundantStringEscape: Redundant escape of . inside string literal.
end

def regexprs
hiera_yaml_file = ENV['HIERA_YAML_PATH'] || '/etc/puppetlabs/code/hiera.yaml'
hiera = YAML.load_file(hiera_yaml_file)
regs = {}
hiera['hierarchy'].each do |hierarchy|
path_datadir = Regexp.escape((hierarchy['datadir'] || default_datadir).chomp('/'))
([*hierarchy['path']] + [*hierarchy['paths']]).each do |level|
regex = level.gsub(/%\{(::)?(trusted|server_facts|facts)\.[^\}]+\}/, '(.+)').gsub(/%\{[^\}]+\}/, '.+')
level = File.join(path_datadir, level)
regex = Regexp.new(level.gsub(/%\{(::)?(trusted|server_facts|facts)\.[^\}]+\}/, '(.+)').gsub(/%\{[^\}]+\}/, '.+'))
facts = level.match(regex).captures.map { |f| f[/%{(::)?(trusted|server_facts|facts)\.(.+)}/, 3] }
regs[regex] = facts
end
Expand All @@ -28,14 +41,14 @@ def regexprs
end

def check
return if path.match(%r{./hieradata/.*\.yaml}).nil?
return unless path_in_datadirs? path

puppetdb = PuppetGhostbuster::PuppetDB.new
_path = path.gsub('./hieradata/', '')

regexprs.each do |k, v|
m = _path.match(Regexp.new(k))
m = path.match(k)
next if m.nil?

return if m.captures.size == 0

if m.captures.size > 1
Expand Down Expand Up @@ -68,7 +81,7 @@ def check
end

notify :warning, {
message: "Hiera File #{_path} seems unused",
message: "Hiera File #{path} seems unused",
line: 1,
column: 1,
}
Expand Down
6 changes: 6 additions & 0 deletions spec/fixtures/hiera.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
---
version: 5
defaults:
datadir: data
hierarchy:
- name: "Some other location"
datadir: private/
path: "nodes/%{trusted.certname}.eyaml"

- name: "Per-node data (yaml version)"
path: "nodes/%{trusted.certname}.yaml"

Expand Down
44 changes: 34 additions & 10 deletions spec/puppet-lint/plugins/ghostbuster_hiera_files_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,71 +9,95 @@

context 'with fix disabled' do
context 'when a certname file is NOT used' do
let(:path) { './hieradata/nodes/foo.example.com.yaml' }
let(:path) { './data/nodes/foo.example.com.yaml' }

it 'detects one problem' do
expect(problems.size).to eq(1)
end

it 'creates a warning' do
expect(problems).to contain_warning('Hiera File nodes/foo.example.com.yaml seems unused')
expect(problems).to contain_warning("Hiera File #{path} seems unused")
end
end

context 'when a certname file is used' do
let(:path) { './hieradata/nodes/bar.example.com.yaml' }
let(:path) { './data/nodes/bar.example.com.yaml' }

it 'does not detect any problem' do
expect(problems.size).to eq(0)
end
end

context 'when an environment file is NOT used' do
let(:path) { './hieradata/environment/foo.yaml' }
let(:path) { './data/environment/foo.yaml' }

it 'detects one problem' do
expect(problems.size).to eq(1)
end

it 'creates a warning' do
expect(problems).to contain_warning('Hiera File environment/foo.yaml seems unused')
expect(problems).to contain_warning("Hiera File #{path} seems unused")
end
end

context 'when an environment file is used' do
let(:path) { './hieradata/environment/production.yaml' }
let(:path) { './data/environment/production.yaml' }

it 'does not detect any problem' do
expect(problems.size).to eq(0)
end
end

context 'when an fact is NOT used' do
let(:path) { './hieradata/virtual/false.yaml' }
let(:path) { './data/virtual/false.yaml' }

it 'detects one problem' do
expect(problems.size).to eq(1)
end

it 'creates a warning' do
expect(problems).to contain_warning('Hiera File virtual/false.yaml seems unused')
expect(problems).to contain_warning("Hiera File #{path} seems unused")
end
end

context 'when an fact file is used' do
let(:path) { './hieradata/virtual/true.yaml' }
let(:path) { './data/virtual/true.yaml' }

it 'does not detect any problem' do
expect(problems.size).to eq(0)
end
end

context 'when an fact file is used with wrong extension' do
let(:path) { './data/virtual/true.eyaml' }

it 'detects one problem' do
expect(problems.size).to eq(1)
end

it 'creates a warning' do
expect(problems).to contain_warning("Hiera File #{path} seems unused")
end
end

context 'when using a variable in hierarchy' do
let(:path) { './hieradata/domain/example.com.yaml' }
let(:path) { './data/domain/example.com.yaml' }

it 'does not detect any problem' do
expect(problems.size).to eq(0)
end
end

context 'when hierarchy datadir is NOT default and NOT used' do
let(:path) { './private/nodes/privates.example.com.eyaml' }

it 'detects one problem' do
expect(problems.size).to eq(1)
end

it 'creates a warning' do
expect(problems).to contain_warning("Hiera File #{path} seems unused")
end
end
end
end

0 comments on commit eb6d93d

Please sign in to comment.