Skip to content

Commit 5827fb9

Browse files
committed
add a footer to tables
1 parent eb59ed7 commit 5827fb9

File tree

1 file changed

+80
-18
lines changed

1 file changed

+80
-18
lines changed

cmd/sshproxyctl/sshproxyctl.go

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/cea-hpc/sshproxy/pkg/utils"
3030

3131
"github.com/olekukonko/tablewriter"
32+
"github.com/olekukonko/tablewriter/tw"
3233
)
3334

3435
var (
@@ -76,12 +77,23 @@ func displayJSON(objs interface{}) {
7677
}
7778
}
7879

79-
func displayTable(headers []string, rows [][]string) {
80+
func displayTable(headers []string, rows [][]string, footers []string) {
8081
table := tablewriter.NewTable(os.Stdout,
8182
tablewriter.WithConfig(tablewriter.Config{
8283
MaxWidth: 200,
84+
Row: tw.CellConfig{
85+
Formatting: tw.CellFormatting{
86+
Alignment: tw.AlignRight,
87+
},
88+
},
89+
Footer: tw.CellConfig{
90+
Formatting: tw.CellFormatting{
91+
MergeMode: tw.MergeHorizontal,
92+
},
93+
},
8394
}))
8495
table.Header(headers)
96+
table.Footer(footers)
8597
table.Bulk(rows)
8698
table.Render()
8799
}
@@ -98,28 +110,42 @@ type aggConnection struct {
98110

99111
type aggregatedConnections []*aggConnection
100112

101-
func (ac aggregatedConnections) toRows(passthrough bool) [][]string {
113+
func (ac aggregatedConnections) toRows(passthrough bool) ([][]string, map[string]string) {
102114
rows := make([][]string, len(ac))
115+
totalConnections := 0
116+
totalIn := 0
117+
totalOut := 0
103118

104119
for i, c := range ac {
105120
rows[i] = []string{
106121
c.User,
107122
c.Service,
108123
c.Dest,
109-
strconv.Itoa(c.N),
124+
fmt.Sprintf("%d", c.N),
110125
c.Last.Format("2006-01-02 15:04:05"),
111126
byteToHuman(c.BwIn, passthrough),
112127
byteToHuman(c.BwOut, passthrough),
113128
}
129+
totalConnections += c.N
130+
totalIn += c.BwIn
131+
totalOut += c.BwOut
132+
}
133+
footer := map[string]string{
134+
"connections": fmt.Sprintf("%d", totalConnections),
135+
"in": byteToHuman(totalIn, passthrough),
136+
"out": byteToHuman(totalOut, passthrough),
114137
}
115138

116-
return rows
139+
return rows, footer
117140
}
118141

119142
type flatConnections []*utils.FlatConnection
120143

121-
func (fc flatConnections) getAllConnections(passthrough bool) [][]string {
144+
func (fc flatConnections) getAllConnections(passthrough bool) ([][]string, map[string]string) {
122145
rows := make([][]string, len(fc))
146+
totalConnections := 0
147+
totalIn := 0
148+
totalOut := 0
123149

124150
for i, c := range fc {
125151
rows[i] = []string{
@@ -131,9 +157,17 @@ func (fc flatConnections) getAllConnections(passthrough bool) [][]string {
131157
byteToHuman(c.BwIn, passthrough),
132158
byteToHuman(c.BwOut, passthrough),
133159
}
160+
totalConnections += 1
161+
totalIn += c.BwIn
162+
totalOut += c.BwOut
163+
}
164+
footer := map[string]string{
165+
"connections": fmt.Sprintf("%d", totalConnections),
166+
"in": byteToHuman(totalIn, passthrough),
167+
"out": byteToHuman(totalOut, passthrough),
134168
}
135169

136-
return rows
170+
return rows, footer
137171
}
138172

139173
func (fc flatConnections) getAggregatedConnections() aggregatedConnections {
@@ -203,9 +237,9 @@ func (fc flatConnections) displayCSV(allFlag bool) {
203237
var rows [][]string
204238

205239
if allFlag {
206-
rows = fc.getAllConnections(true)
240+
rows, _ = fc.getAllConnections(true)
207241
} else {
208-
rows = fc.getAggregatedConnections().toRows(true)
242+
rows, _ = fc.getAggregatedConnections().toRows(true)
209243
}
210244

211245
displayCSV(rows)
@@ -225,21 +259,25 @@ func (fc flatConnections) displayJSON(allFlag bool) {
225259

226260
func (fc flatConnections) displayTable(allFlag bool) {
227261
var rows [][]string
262+
var footer map[string]string
228263

229264
if allFlag {
230-
rows = fc.getAllConnections(false)
265+
rows, footer = fc.getAllConnections(false)
231266
} else {
232-
rows = fc.getAggregatedConnections().toRows(false)
267+
rows, footer = fc.getAggregatedConnections().toRows(false)
233268
}
234269

235270
var headers []string
271+
var footers []string
236272
if allFlag {
237273
headers = []string{"User", "Service", "From", "Destination", "Start time", "Bw in", "Bw out"}
274+
footers = []string{"Totals", "Totals", "Totals", "Totals", footer["connections"], footer["in"], footer["out"]}
238275
} else {
239276
headers = []string{"User", "Service", "Destination", "# of conns", "Last connection", "Bw in", "Bw out"}
277+
footers = []string{"Totals", "Totals", "Totals", footer["connections"], "", footer["in"], footer["out"]}
240278
}
241279

242-
displayTable(headers, rows)
280+
displayTable(headers, rows, footers)
243281
}
244282

245283
func showConnections(configFile string, csvFlag bool, jsonFlag bool, allFlag bool) {
@@ -271,8 +309,12 @@ type flatUserLight struct {
271309

272310
type flatUsers []*utils.FlatUser
273311

274-
func (fu flatUsers) getAllUsers(allFlag bool, passthrough bool) [][]string {
312+
func (fu flatUsers) getAllUsers(allFlag bool, passthrough bool) ([][]string, map[string]string) {
275313
rows := make([][]string, len(fu))
314+
totalConnections := 0
315+
totalIn := 0
316+
totalOut := 0
317+
276318
for i, v := range fu {
277319
if allFlag {
278320
rows[i] = []string{
@@ -294,6 +336,9 @@ func (fu flatUsers) getAllUsers(allFlag bool, passthrough bool) [][]string {
294336
byteToHuman(v.BwOut, passthrough),
295337
}
296338
}
339+
totalConnections += v.N
340+
totalIn += v.BwIn
341+
totalOut += v.BwOut
297342
}
298343

299344
sort.Slice(rows, func(i, j int) bool {
@@ -303,8 +348,13 @@ func (fu flatUsers) getAllUsers(allFlag bool, passthrough bool) [][]string {
303348
return rows[i][0] < rows[j][0]
304349
}
305350
})
351+
footer := map[string]string{
352+
"connections": fmt.Sprintf("%d", totalConnections),
353+
"in": byteToHuman(totalIn, passthrough),
354+
"out": byteToHuman(totalOut, passthrough),
355+
}
306356

307-
return rows
357+
return rows, footer
308358
}
309359

310360
func (fu flatUsers) displayJSON(allFlag bool) {
@@ -326,22 +376,25 @@ func (fu flatUsers) displayJSON(allFlag bool) {
326376
}
327377

328378
func (fu flatUsers) displayCSV(allFlag bool) {
329-
rows := fu.getAllUsers(allFlag, true)
379+
rows, _ := fu.getAllUsers(allFlag, true)
330380

331381
displayCSV(rows)
332382
}
333383

334384
func (fu flatUsers) displayTable(allFlag bool) {
335-
rows := fu.getAllUsers(allFlag, false)
385+
rows, footer := fu.getAllUsers(allFlag, false)
336386

337387
var headers []string
388+
var footers []string
338389
if allFlag {
339390
headers = []string{"User", "Service", "Groups", "# of conns", "Bw in", "Bw out", "Persist to", "Persist TTL"}
391+
footers = []string{"Totals", "Totals", "Totals", footer["connections"], footer["in"], footer["out"], "", ""}
340392
} else {
341393
headers = []string{"User", "Groups", "# of conns", "Bw in", "Bw out"}
394+
footers = []string{"Totals", "Totals", footer["connections"], footer["in"], footer["out"]}
342395
}
343396

344-
displayTable(headers, rows)
397+
displayTable(headers, rows, footers)
345398
}
346399

347400
func showUsers(configFile string, csvFlag bool, jsonFlag bool, allFlag bool) {
@@ -431,13 +484,14 @@ func (fg flatGroups) displayTable(allFlag bool) {
431484
rows := fg.getAllGroups(allFlag, false)
432485

433486
var headers []string
487+
var footers []string
434488
if allFlag {
435489
headers = []string{"Group", "Service", "Users", "# of conns", "Bw in", "Bw out"}
436490
} else {
437491
headers = []string{"Group", "Users", "# of conns", "Bw in", "Bw out"}
438492
}
439493

440-
displayTable(headers, rows)
494+
displayTable(headers, rows, footers)
441495
}
442496

443497
func showGroups(configFile string, csvFlag bool, jsonFlag bool, allFlag bool) {
@@ -474,6 +528,10 @@ func showHosts(configFile string, csvFlag bool, jsonFlag bool) {
474528
}
475529

476530
rows := make([][]string, len(hosts))
531+
totalConns := 0
532+
totalIn := 0
533+
totalOut := 0
534+
totalPersist := 0
477535

478536
for i, h := range hosts {
479537
rows[i] = []string{
@@ -485,12 +543,16 @@ func showHosts(configFile string, csvFlag bool, jsonFlag bool) {
485543
byteToHuman(h.BwOut, csvFlag),
486544
fmt.Sprintf("%d", h.HistoryN),
487545
}
546+
totalConns += h.N
547+
totalIn += h.BwIn
548+
totalOut += h.BwOut
549+
totalPersist += h.HistoryN
488550
}
489551

490552
if csvFlag {
491553
displayCSV(rows)
492554
} else {
493-
displayTable([]string{"Host", "State", "Last check", "# of conns", "Bw in", "Bw out", "# persist"}, rows)
555+
displayTable([]string{"Host", "State", "Last check", "# of conns", "Bw in", "Bw out", "# persist"}, rows, []string{"Totals", "Totals", "Totals", fmt.Sprintf("%d", totalConns), byteToHuman(totalIn, false), byteToHuman(totalOut, false), fmt.Sprintf("%d", totalPersist)})
494556
}
495557
}
496558

0 commit comments

Comments
 (0)