Skip to content

Commit 6207701

Browse files
authored
Merge pull request #1656 from simonbaird/text-output-group-by-result
Rework validate image human readable text output
2 parents 150e55d + 3641f75 commit 6207701

File tree

6 files changed

+143
-63
lines changed

6 files changed

+143
-63
lines changed

features/__snapshots__/validate_image.snap

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,52 +1722,58 @@ Error: success criteria not met
17221722

17231723
---
17241724
[detailed failures output:${TMPDIR}/output.txt - 1]
1725-
Name: Unnamed
1726-
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1727-
Summary: Violations: 3, Warnings: 0, Successes: 4
1728-
Violations:
1729-
✕ main.reject_with_term
1730-
Fails always (term1)
1731-
Reject with term rule
1732-
Description: This rule will always fail. To exclude this rule add
1733-
"main.reject_with_term:term1" to the `exclude` section of the policy
1734-
configuration.
1725+
Success: false
1726+
Result: FAILURE
1727+
Violations: 3, Warnings: 0, Successes: 4
1728+
Component: Unnamed
1729+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1730+
1731+
Results:
1732+
✕ [Violation] main.reject_with_term
1733+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1734+
Reason: Fails always (term1)
1735+
Title: Reject with term rule
1736+
Description: This rule will always fail. To exclude this rule add "main.reject_with_term:term1" to the `exclude` section of the
1737+
policy configuration.
17351738
Solution: None
17361739

1737-
[31m✕[0m [31mmain.reject_with_term[0m
1738-
Fails always (term2)
1739-
Reject with term rule
1740-
Description: This rule will always fail. To exclude this rule add
1741-
"main.reject_with_term:term2" to the `exclude` section of the policy
1742-
configuration.
1740+
[31m✕[0m [31m[Violation] main.reject_with_term[0m
1741+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1742+
Reason: Fails always (term2)
1743+
Title: Reject with term rule
1744+
Description: This rule will always fail. To exclude this rule add "main.reject_with_term:term2" to the `exclude` section of the
1745+
policy configuration.
17431746
Solution: None
17441747

1745-
✕ main.rejector
1746-
Fails always
1747-
Reject rule
1748-
Description: This rule will always fail. To exclude this rule add
1749-
"main.rejector" to the `exclude` section of the policy configuration.
1748+
✕ [Violation] main.rejector
1749+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1750+
Reason: Fails always
1751+
Title: Reject rule
1752+
Description: This rule will always fail. To exclude this rule add "main.rejector" to the `exclude` section of the policy
1753+
configuration.
17501754
Solution: None
17511755

1752-
Successes:
1753-
[32m✓[0m [32mbuiltin.attestation.signature_check[0m
1754-
Attestation signature check passed
1756+
[32m✓[0m [32m[Success] builtin.attestation.signature_check[0m
1757+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1758+
Title: Attestation signature check passed
17551759
Description: The attestation signature matches available signing materials.
17561760

1757-
✓ builtin.attestation.syntax_check
1758-
Attestation syntax check passed
1761+
✓ [Success] builtin.attestation.syntax_check
1762+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1763+
Title: Attestation syntax check passed
17591764
Description: The attestation has correct syntax.
17601765

1761-
✓ builtin.image.signature_check
1762-
Image signature check passed
1766+
✓ [Success] builtin.image.signature_check
1767+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1768+
Title: Image signature check passed
17631769
Description: The image signature matches available signing materials.
17641770

1765-
✓ main.acceptor
1766-
Allow rule
1771+
✓ [Success] main.acceptor
1772+
ImageRef: ${REGISTRY}/acceptance/image@sha256:${REGISTRY_acceptance/image:latest_DIGEST}
1773+
Title: Allow rule
17671774
Description: This rule will never fail
17681775

17691776

1770-
17711777
---
17721778
[future failure is a deny when using effective-date flag:stdout - 1]
17731779
{

internal/applicationsnapshot/report.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,19 @@ func generateMarkdownSummary(r *Report) ([]byte, error) {
310310
var efs embed.FS
311311

312312
func generateTextReport(r *Report) ([]byte, error) {
313-
return utils.RenderFromTemplatesWithMain(r, "text_report.tmpl", efs)
313+
// Prepare some template input
314+
input := struct {
315+
Report *Report
316+
TestReport TestReport
317+
}{
318+
// This includes everything in the yaml/json output
319+
Report: r,
320+
// This has useful stuff we want to output, so let's reuse it
321+
// even though this is not what it was originally designed for
322+
TestReport: r.toAppstudioReport(),
323+
}
324+
325+
return utils.RenderFromTemplatesWithMain(input, "text_report.tmpl", efs)
314326
}
315327

316328
func writeMarkdownField(buffer *bytes.Buffer, name string, value any, icon string) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{{- if gt (len .) 1 -}}
2+
{{/*
3+
When there are multiple components we provide totals for each
4+
component and change the format to make it more readable as a list
5+
*/}}
6+
Components:
7+
{{ range . -}}
8+
- Name: {{ .Name }}
9+
ImageRef: {{ .ContainerImage }}
10+
Violations: {{ len .Violations }}, Warnings: {{ len .Warnings }}, Successes: {{ .SuccessCount }}
11+
12+
{{ end -}}
13+
14+
{{- else -}}
15+
{{/*
16+
When there is only one component the summary counts are the same
17+
as the overall counts, so we don't need to repeat them.
18+
(Using range here even though we know there is only one item.)
19+
*/}}
20+
{{- range . -}}
21+
Component: {{ .Name }}
22+
ImageRef: {{ .ContainerImage }}
23+
24+
{{ end -}}
25+
{{- end -}}
Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,42 @@
1-
{{- $color := .Color -}}
1+
{{- $type := .Type -}}
2+
{{- $wrap := 130 -}}
23
{{- $indent := 2 -}}
3-
{{- $wrap := 78 -}}
4-
{{- range .Results -}}
5-
{{- colorIndicator $color }} {{ colorText $color .Metadata.code }}
6-
{{ if and (ne .Message "Pass") .Message -}}
7-
{{- indentWrap $indent $wrap .Message }}
8-
{{ end -}}
9-
{{ if .Metadata.title -}}
10-
{{- indentWrap $indent $wrap .Metadata.title }}
11-
{{ end -}}
12-
{{ if .Metadata.description -}}
13-
{{- indentWrap $indent $wrap (printf "Description: %s" .Metadata.description) }}
14-
{{ end -}}
15-
{{ if and (ne .Message "Pass") .Metadata.solution -}}
16-
{{- indentWrap $indent $wrap (printf "Solution: %s" .Metadata.solution) }}
17-
{{ end }}
18-
{{ end -}}
4+
5+
{{- range .Components -}}
6+
{{- $imageRef := .ContainerImage -}}
7+
8+
{{ $results := "" }}
9+
{{- if eq $type "Violation" -}}{{- $results = .Violations -}}
10+
{{- else if eq $type "Warning" -}}{{- $results = .Warnings -}}
11+
{{- else if eq $type "Success" -}}{{- $results = .Successes -}}
12+
{{- end -}}
13+
14+
{{- range $results -}}
15+
{{/* Assume .Metadata.code is always present */}}
16+
{{- colorIndicator $type }} {{ colorText $type (printf "[%s] %s" $type .Metadata.code) }}{{ nl -}}
17+
18+
{{- if $imageRef -}}
19+
{{- indentWrap $indent $wrap (printf "ImageRef: %s" $imageRef ) }}{{ nl -}}
20+
{{- end -}}
21+
22+
{{/* For a success the message is generally just "Pass" so don't show it */}}
23+
{{- if and (ne $type "Success") .Message -}}
24+
{{- indentWrap $indent $wrap (printf "Reason: %s" .Message) }}{{ nl -}}
25+
{{- end -}}
26+
27+
{{- if .Metadata.title }}
28+
{{- indentWrap $indent $wrap (printf "Title: %s" .Metadata.title) }}{{ nl -}}
29+
{{- end -}}
30+
31+
{{- if .Metadata.description -}}
32+
{{- indentWrap $indent $wrap (printf "Description: %s" .Metadata.description) -}}{{ nl -}}
33+
{{- end -}}
34+
35+
{{/* Don't show the solution text for a success either */}}
36+
{{- if and (ne $type "Success") .Metadata.solution -}}
37+
{{- indentWrap $indent $wrap (printf "Solution: %s" .Metadata.solution) -}}{{ nl -}}
38+
{{- end -}}
39+
40+
{{- nl -}}
41+
{{- end -}}
42+
{{- end -}}

internal/applicationsnapshot/templates/text_report.tmpl

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
1-
{{ range .Components -}}
2-
Name: {{ .Name }}
3-
ImageRef: {{ .ContainerImage }}
4-
Summary: Violations: {{ len .Violations }}, Warnings: {{ len .Warnings }}, Successes: {{ .SuccessCount }}
5-
{{ if gt (len .Violations) 0 -}}
6-
Violations:
7-
{{ template "_results.tmpl" (toMap "Results" .Violations "Color" "red") }}
1+
{{- $t := .TestReport -}}
2+
{{- $r := .Report -}}
3+
{{- $c := $r.Components -}}
4+
5+
{{- $showSuccesses := (index $c 0).Successes -}}
6+
7+
Success: {{ $r.Success }}
8+
Result: {{ $t.Result }}
9+
Violations: {{ $t.Failures }}, Warnings: {{ $t.Warnings }}, Successes: {{ $t.Successes }}{{ nl -}}
10+
11+
{{- template "_components.tmpl" $c -}}
12+
13+
Results:{{ nl -}}
14+
{{- if gt $t.Failures 0 -}}
15+
{{- template "_results.tmpl" (toMap "Components" $c "Type" "Violation") -}}
816
{{- end -}}
9-
{{ if gt (len .Warnings) 0 -}}
10-
Warnings:
11-
{{ template "_results.tmpl" (toMap "Results" .Warnings "Color" "yellow") }}
17+
18+
{{- if gt $t.Warnings 0 -}}
19+
{{- template "_results.tmpl" (toMap "Components" $c "Type" "Warning") -}}
1220
{{- end -}}
13-
{{ if and (gt .SuccessCount 0) (.Successes) -}}
14-
Successes:
15-
{{ template "_results.tmpl" (toMap "Results" .Successes "Color" "green") }}
21+
22+
{{- if and (gt $t.Successes 0) $showSuccesses -}}
23+
{{- template "_results.tmpl" (toMap "Components" $c "Type" "Success") -}}
1624
{{- end -}}
17-
{{- end }}

internal/utils/templates.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ func toMap(values ...interface{}) (map[string]interface{}, error) {
147147
return m, nil
148148
}
149149

150+
// Can make it easier to get the right number of line breaks
151+
func nl() (string, error) {
152+
return "\n", nil
153+
}
154+
150155
// For use in template.Funcs above
151156
// Todo maybe: Use reflect to find the functions and make this dynamic
152157
var templateHelpers = template.FuncMap{
@@ -156,4 +161,5 @@ var templateHelpers = template.FuncMap{
156161
"wrap": wrap,
157162
"indentWrap": indentWrap,
158163
"toMap": toMap,
164+
"nl": nl,
159165
}

0 commit comments

Comments
 (0)