Class: Bolt::Plugin::Puppetdb

Inherits:
Object
  • Object
show all
Defined in:
lib/bolt/plugin/puppetdb.rb

Defined Under Namespace

Classes: FactLookupError

Constant Summary collapse

TARGET_OPTS =
%w[uri name config].freeze

Instance Method Summary collapse

Constructor Details

#initialize(pdb_client) ⇒ Puppetdb

Returns a new instance of Puppetdb.



16
17
18
19
# File 'lib/bolt/plugin/puppetdb.rb', line 16

def initialize(pdb_client)
  @puppetdb_client = pdb_client
  @logger = Logging.logger[self]
end

Instance Method Details

#fact_path(raw_fact) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/bolt/plugin/puppetdb.rb', line 33

def fact_path(raw_fact)
  fact_path = raw_fact.split(".")
  if fact_path[0] == 'facts'
    fact_path.drop(1)
  elsif fact_path == ['certname']
    fact_path
  else
    raise FactLookupError.new(raw_fact, "fact lookups must start with 'facts.'")
  end
end

#hooksObject



25
26
27
# File 'lib/bolt/plugin/puppetdb.rb', line 25

def hooks
  [:resolve_reference]
end

#nameObject



21
22
23
# File 'lib/bolt/plugin/puppetdb.rb', line 21

def name
  'puppetdb'
end

#resolve_facts(config, certname, target_data) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/bolt/plugin/puppetdb.rb', line 71

def resolve_facts(config, certname, target_data)
  Bolt::Util.walk_vals(config) do |value|
    if value.is_a?(String)
      data = target_data&.detect { |d| d['path'] == fact_path(value) }
      warn_missing_fact(certname, value) if data.nil?
      # If there's no fact data this will be nil
      data&.fetch('value', nil)
    elsif value.is_a?(Array) || value.is_a?(Hash)
      value
    else
      raise FactLookupError.new(value, "fact lookups must be a string")
    end
  end
end

#resolve_reference(opts) ⇒ Object



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
# File 'lib/bolt/plugin/puppetdb.rb', line 44

def resolve_reference(opts)
  targets = @puppetdb_client.query_certnames(opts['query'])
  facts = []

  target_opts = opts.select { |k, _| TARGET_OPTS.include?(k) }
  Bolt::Util.walk_vals(target_opts) do |value|
    # This is done in parts instead of in place so that we only need to
    # make one puppetDB query
    if value.is_a?(String)
      facts << fact_path(value)
    end
    value
  end

  facts.uniq!
  # Returns {'mycertname' => [{'path' => ['nested', 'fact'], 'value' => val'}], ... }
  fact_values = @puppetdb_client.fact_values(targets, facts)

  targets.map do |certname|
    target_data = fact_values[certname]
    target = resolve_facts(target_opts, certname, target_data) || {}
    target['uri'] = certname unless target['uri'] || target['name']

    target
  end
end

#warn_missing_fact(certname, fact) ⇒ Object



29
30
31
# File 'lib/bolt/plugin/puppetdb.rb', line 29

def warn_missing_fact(certname, fact)
  @logger.warn("Could not find fact #{fact} for node #{certname}")
end