10
11
12
13
14
15
16
17
18
19
20
21
22
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
|
# File 'plans/agent_summary.pp', line 10
plan pe_status_check::agent_summary(
Array[String[1]] $indicator_exclusions = lookup('pe_status_check::indicator_exclusions', undef, undef, []),
Optional[TargetSpec] $targets = undef,
) {
# Query PuppetDB if $targets is not unspecified
$_targets = if $targets =~ Undef {
$certnames_or_error = catch_errors() || {
# NOTE: We use `pe_build` to identify all non-infrastructure nodes that could have `agent_status_check`
# This could be changed to `facts.agent_status_check` instead, but could miss some potential failure states
puppetdb_query('inventory[certname]{ ! certname in fact_contents[certname]{name ~ "pe_build"} }').map |$r| { $r['certname'] }
}
if $certnames_or_error =~ Error {
fail_plan("PuppetDB query failed: ${certnames_or_error}")
}
get_targets($certnames_or_error)
} else {
get_targets($targets)
}
# Trapping errors doesn't work here since the lookup will fail regardless
$checks = lookup('pe_status_check::checks', Hash)
# Get the facts from the Targets to use for processing
$results = without_default_logging() || {
run_task('facts', $_targets, '_catch_errors' => true)
}
# Report on failures while collecting facts
$fact_task_errors = $results.error_set.ok ? {
true => {},
default => $results.error_set.reduce({}) |$memo, $e| {
$memo + {
$e.target.name => $e.error.message
}
}
}
# Parse the results to identify nodes with the fact
$agent_status_check_results = $results.ok_set.filter |$r| { $r['agent_status_check'] =~ NotUndef and ! $r['agent_status_check'].empty }
$missing = $results.ok_set.filter |$r| { $r['agent_status_check'] =~ Undef or $r['agent_status_check'].empty }
$missing_errors = $missing.reduce({}) |$memo, $r| {
$memo + {
$r.target.name => $r['pe_build'] =~ Undef ? {
false => 'This plan does not check the status of agent nodes',
default => 'Missing the \'agent_status_check\' fact'
}
}
}
# Generate a summary of nodes with passing and failing
$output_format = {
'details' => {},
'passing' => [],
'failing' => [],
}
$node_summary = $agent_status_check_results.reduce($output_format) |$memo, $res| {
$failing = $res['agent_status_check'].filter |$k, $v| { ! $v and ! ($k in $indicator_exclusions) }
$passing = $res['agent_status_check'].filter |$k, $v| { $v and ! ($k in $indicator_exclusions) }
$state = $failing.empty ? {
true => 'passing',
default => 'failing'
}
$details = {
$res.target.name => {
'passing_tests_count' => $passing.length,
'failed_tests_count' => $failing.length,
'failed_tests_details' => $failing.keys.map |$key| { $checks[$key] },
},
}
$memo + {
$state => $memo[$state] + [$res.target.name],
'details' => $memo['details'] + $details,
}
}
$status = ( $node_summary['failing'].empty and $missing.empty and $fact_task_errors.empty ) ? {
true => 'passing',
default => 'failing'
}
# Build the output hash
$return = {
'nodes' => $node_summary,
'errors' => $missing_errors + $fact_task_errors,
'status' => $status,
'passing_node_count' => $node_summary['passing'].length,
'failing_node_count' => $node_summary['failing'].length + $missing.length,
}
return $return
}
|