Skip to content

Commit 24ebb1f

Browse files
andrewyuntjohnSchnake
authored andcommitted
Add readable mode to results command
Signed-off-by: Andrew Yunt <[email protected]> Error message fixes for results command Signed-off-by: Andrew Yunt <[email protected]> Update text module Signed-off-by: Andrew Yunt <[email protected]>
1 parent 1c31007 commit 24ebb1f

File tree

4 files changed

+126
-3
lines changed

4 files changed

+126
-3
lines changed

cmd/sonobuoy/app/results.go

+36-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package app
1818

1919
import (
20+
"bytes"
2021
"compress/gzip"
2122
"encoding/json"
2223
"fmt"
@@ -47,6 +48,9 @@ const (
4748
// resultModeDump will just copy the post-processed yaml file to stdout.
4849
resultModeDump = "dump"
4950

51+
//resultModeReadable will copy the post-processed yaml file to stdout and replace \n and \t with new lines and tabs respectively.
52+
resultModeReadable = "readable"
53+
5054
windowsSeperator = `\`
5155

5256
//Name of the "fake" plugin used to enable printing the health summary.
@@ -83,7 +87,7 @@ func NewCmdResults() *cobra.Command {
8387
)
8488
cmd.Flags().StringVarP(
8589
&data.mode, "mode", "m", resultModeReport,
86-
`Modifies the format of the output. Valid options are report, detailed, or dump.`,
90+
`Modifies the format of the output. Valid options are report, detailed, readable, or dump.`,
8791
)
8892
cmd.Flags().StringVarP(
8993
&data.node, "node", "n", "",
@@ -217,6 +221,15 @@ func printHealthSummary(input resultsInput, r *results.Reader) error {
217221
return err
218222
}
219223
fmt.Println(string(data))
224+
case resultModeReadable:
225+
data, err = yaml.Marshal(clusterHealthSummary)
226+
if err != nil {
227+
return err
228+
}
229+
str := string(data)
230+
str = strings.ReplaceAll(str, `\n`, "\n")
231+
str = strings.ReplaceAll(str, `\t`, " ")
232+
fmt.Println(str)
220233
default:
221234
err = printClusterHealthResultsSummary(clusterHealthSummary)
222235
if err != nil {
@@ -226,6 +239,17 @@ func printHealthSummary(input resultsInput, r *results.Reader) error {
226239
return nil
227240
}
228241

242+
type humanReadableWriter struct {
243+
w io.Writer
244+
}
245+
246+
func (hw *humanReadableWriter) Write(b []byte) (int, error) {
247+
newb := bytes.Replace(b, []byte(`\n`), []byte("\n"), -1)
248+
newb = bytes.Replace(newb, []byte(`\t`), []byte("\t"), -1)
249+
_, err := hw.w.Write(newb)
250+
return len(b), err
251+
}
252+
229253
func printSinglePlugin(input resultsInput, r *results.Reader) error {
230254
// If we want to dump the whole file, don't decode to an Item object first.
231255
if input.mode == resultModeDump {
@@ -235,6 +259,17 @@ func printSinglePlugin(input resultsInput, r *results.Reader) error {
235259
}
236260
_, err = io.Copy(os.Stdout, fReader)
237261
return err
262+
} else if input.mode == resultModeReadable {
263+
fReader, err := r.PluginResultsReader(input.plugin)
264+
if err != nil {
265+
return errors.Wrapf(err, "failed to get results reader for plugin %v", input.plugin)
266+
}
267+
writer := &humanReadableWriter{os.Stdout}
268+
_, err = io.Copy(writer, fReader)
269+
if err != nil {
270+
return errors.Wrapf(err, "failed to copy data for plugin %v", input.plugin)
271+
}
272+
return err
238273
}
239274

240275
// For summary and detailed views, get the item as an object to iterate over.

cmd/sonobuoy/app/results_test.go

+87
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,97 @@ limitations under the License.
1616
package app
1717

1818
import (
19+
"bytes"
20+
"fmt"
1921
"path/filepath"
22+
"strings"
2023
"testing"
2124
)
2225

26+
func TestHumanReadableWriter(t *testing.T) {
27+
tcs := []struct {
28+
desc string
29+
input string
30+
contains []string
31+
expected bool
32+
}{
33+
{
34+
desc: "String with \\n does not contain `\\n`",
35+
input: "\nHello world",
36+
contains: []string{`\n`},
37+
expected: false,
38+
},
39+
{
40+
desc: "String with \\t does not contain `\\t`",
41+
input: "\tHello world",
42+
contains: []string{`\t`},
43+
expected: false,
44+
},
45+
{
46+
desc: "String with \\t and \n does not contain `\\n`",
47+
input: "\tHello\nworld",
48+
contains: []string{`\n`},
49+
expected: false,
50+
},
51+
{
52+
desc: "String with \\t and \\n does not contain `\\t`",
53+
input: "\tHello\nworld",
54+
contains: []string{`\t`},
55+
expected: false,
56+
},
57+
{
58+
desc: "String with \\t and \\n does not contain `\\n` or `\\t`",
59+
input: "\tHello\nworld",
60+
contains: []string{`\n`, `\t`},
61+
expected: false,
62+
},
63+
{
64+
desc: `String with \n contains "\n"`,
65+
input: "\nHello world",
66+
contains: []string{"\n"},
67+
expected: true,
68+
},
69+
{
70+
desc: `String with \t contains "\t"`,
71+
input: "\tHello world",
72+
contains: []string{"\t"},
73+
expected: true,
74+
},
75+
{
76+
desc: `String with \t and \n contains "\n"`,
77+
input: "\tHello\nworld",
78+
contains: []string{"\n"},
79+
expected: true,
80+
},
81+
{
82+
desc: `String with \t and \n contains "\t"`,
83+
input: "\tHello\nworld",
84+
contains: []string{"\t"},
85+
expected: true,
86+
},
87+
{
88+
desc: `String with \t and \n contains "\n" and "\t"`,
89+
input: "\tHello\nworld",
90+
contains: []string{"\n", "\t"},
91+
expected: true,
92+
},
93+
}
94+
95+
for _, tc := range tcs {
96+
t.Run(tc.desc, func(t *testing.T) {
97+
buffer := bytes.Buffer{}
98+
writer := humanReadableWriter{&buffer}
99+
fmt.Fprintf(&writer, tc.input)
100+
for _, contains := range tc.contains {
101+
out := strings.Contains(buffer.String(), contains)
102+
if out != tc.expected {
103+
t.Errorf("Expected output: %v", tc.expected)
104+
}
105+
}
106+
})
107+
}
108+
}
109+
23110
func TestGetFileFromMeta(t *testing.T) {
24111
tcs := []struct {
25112
desc string

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
2626
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
2727
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
28-
golang.org/x/text v0.3.6
28+
golang.org/x/text v0.3.7
2929
gopkg.in/yaml.v2 v2.4.0
3030
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c
3131
k8s.io/api v0.21.3

go.sum

+2-1
Original file line numberDiff line numberDiff line change
@@ -444,8 +444,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
444444
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
445445
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
446446
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
447-
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
448447
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
448+
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
449+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
449450
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
450451
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
451452
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

0 commit comments

Comments
 (0)