Class: Bolt::ApplyResult

Inherits:
Result
  • Object
show all
Defined in:
lib/bolt/apply_result.rb

Instance Attribute Summary

Attributes inherited from Result

#target, #value

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Result

#==, #[], #eql?, #error, #error_hash, for_command, for_task, for_upload, from_asserted_args, from_exception, #generic_value, #message, #ok?, #status_hash, #success?, #to_json, #to_s

Constructor Details

#initialize(target, error: nil, report: nil) ⇒ ApplyResult

Returns a new instance of ApplyResult.



65
66
67
68
69
70
71
# File 'lib/bolt/apply_result.rb', line 65

def initialize(target, error: nil, report: nil)
  @target = target
  @value = {}
  value['report'] = report if report
  value['_error'] = error if error
  value['_output'] = metrics_message if metrics_message
end

Class Method Details

.from_task_result(result) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/bolt/apply_result.rb', line 49

def self.from_task_result(result)
  if (puppet_missing = puppet_missing_error(result))
    new(result.target,
        error: puppet_missing,
        report: result.value.reject { |k| k == '_error' })
  elsif !result.ok?
    new(result.target, error: result.error_hash)
  elsif (resource_error = resource_error(result))
    new(result.target,
        error: resource_error,
        report: result.value.reject { |k| k == '_error' })
  else
    new(result.target, report: result.value)
  end
end

.puppet_missing_error(result) ⇒ Object



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
# File 'lib/bolt/apply_result.rb', line 9

def self.puppet_missing_error(result)
  error_hash = result.error_hash
  exit_code = error_hash['details']['exit_code'] if error_hash && error_hash['details']
  # If we get exit code 126 or 127 back, it means the shebang command wasn't found; Puppet isn't present
  if [126, 127].include?(exit_code)
    {
      'msg' => "Puppet is not installed on the target, please install it to enable 'apply'",
      'kind' => 'bolt/apply-error'
    }
  elsif exit_code == 1 &&
        (error_hash['msg'] =~ /Could not find executable 'ruby.exe'/ ||
         error_hash['msg'] =~ /The term 'ruby.exe' is not recognized as the name of a cmdlet/)
    # Windows does not have Ruby present
    {
      'msg' => "Puppet is not installed on the target in $env:ProgramFiles, please install it to enable 'apply'",
      'kind' => 'bolt/apply-error'
    }
  elsif exit_code == 1 && error_hash['msg'] =~ /cannot load such file -- puppet \(LoadError\)/
    # Windows uses a Ruby that doesn't have Puppet installed
    # TODO: fix so we don't find other Rubies, or point to a known issues URL for more info
    { 'msg' => 'Found a Ruby without Puppet present, please install Puppet ' \
               "or remove Ruby from $env:Path to enable 'apply'",
      'kind' => 'bolt/apply-error' }
  end
end

.resource_error(result) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/bolt/apply_result.rb', line 35

def self.resource_error(result)
  if result.value['status'] == 'failed'
    resources = result.value['resource_statuses']
    failed = resources.select { |_, r| r['failed'] }.flat_map do |key, resource|
      resource['events'].select { |e| e['status'] == 'failure' }.map do |event|
        "\n  #{key}: #{event['message']}"
      end
    end

    { 'msg' => "Resources failed to apply for #{result.target.name}#{failed.join}",
      'kind' => 'bolt/resource-failure' }
  end
end

Instance Method Details

#event_metricsObject



73
74
75
76
77
# File 'lib/bolt/apply_result.rb', line 73

def event_metrics
  if (events = value.dig('report', 'metrics', 'resources', 'values'))
    events.each_with_object({}) { |ev, h| h[ev[0]] = ev[2] }
  end
end

#log_eventsObject

TODO: We’ve gotten requests for this type of logging but I’m not sure what we shold do with it exactly.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/bolt/apply_result.rb', line 81

def log_events
  logger = Logging.logger[target.name]
  if (logs = value.dig('report', 'logs'))
    logs.each do |log|
      case log["level"]
      when 'err'
        logger.error(log['message'])
      when 'warn'
        logger.info(log['message'])
      when 'notice'
        logger.notice(log['message'])
      when 'info'
        logger.info(log['message'])
      else
        logger.debug(log["message"])
      end
    end
  end
end

#metrics_messageObject



101
102
103
104
105
106
107
108
109
110
# File 'lib/bolt/apply_result.rb', line 101

def metrics_message
  if (metrics = event_metrics)
    changed = metrics['changed']
    failed = metrics['failed']
    skipped = metrics['skipped']
    unchanged = metrics['total'] - changed - failed - skipped
    noop = metrics['out_of_sync'] - changed - failed
    "changed: #{changed}, failed: #{failed}, unchanged: #{unchanged} skipped: #{skipped}, noop: #{noop}"
  end
end

#reportObject



112
113
114
# File 'lib/bolt/apply_result.rb', line 112

def report
  @value['report']
end