Skip to content

Commit

Permalink
added --match-only flag to calculate up only the matched rows
Browse files Browse the repository at this point in the history
  • Loading branch information
NimbleArchitect committed Aug 5, 2022
1 parent bce1790 commit 9d83650
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 29 deletions.
8 changes: 8 additions & 0 deletions pkg/plugin/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type RowBuilder struct {
ShowContainerType bool
ShowNodeTree bool // show the tree view with the nodes at the root level rather than just the resource sets at root
FilterList map[string]matchValue // used to filter out rows from the table during Print function
CalcFiltered bool // the filterd out rows are included in the branch calculations
DefaultHeaderLen int

annotationLabel map[string]map[string]map[string]map[string]string
Expand Down Expand Up @@ -79,6 +80,7 @@ func (b *RowBuilder) SetFlagsFrom(commonFlagList commonFlags) {
b.LabelPodName = commonFlagList.labelPodName
b.AnnotationPodName = commonFlagList.annotationPodName
b.FilterList = b.CommonFlags.filterList
b.CalcFiltered = b.CommonFlags.calcMatchOnly

// we always show the pod name by default
b.ShowPodName = true
Expand Down Expand Up @@ -209,6 +211,12 @@ func (b *RowBuilder) walkTreeCreateRow(loop Looper, info *BuilderInformation, pa
b.Table.HidePlaceHolderRow(rowid)
} else {
b.Table.UpdatePlaceHolderRow(rowid, tblOut)
if b.CalcFiltered {
totals = append(totals, tblBranch)
}
}
if !b.CalcFiltered {
//dont add up the filtered out rows
totals = append(totals, tblBranch)
}
}
Expand Down
22 changes: 16 additions & 6 deletions pkg/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type commonFlags struct {
outputAs string // how to output the table, currently only accepts json
sortList []string // column names to sort on when table.Print() is called
matchSpecList map[string]matchValue // filter pods based on matches to the v1.Pods.Spec fields
calcMatchOnly bool // should we calculate up only the rows that match
labelNodeName string
labelPodName string
annotationPodName string
Expand Down Expand Up @@ -367,7 +368,8 @@ func addCommonFlags(cmdObj *cobra.Command) {
cmdObj.Flags().StringP("container", "c", "", `Container name. If omitted show all containers in the pod`)
cmdObj.Flags().StringP("sort", "", "", `Sort by column`)
cmdObj.Flags().StringP("output", "o", "", `Output format, currently csv, list, json and yaml are supported`)
cmdObj.Flags().StringP("match", "", "", `Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and != `)
cmdObj.Flags().StringP("match", "m", "", `Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and != `)
cmdObj.Flags().StringP("match-only", "M", "", `Filters out results but only calculates up visible rows`)
cmdObj.Flags().StringP("select", "", "", `Filters pods based on their spec field, comma seperated list of FIELD OP VALUE, where OP can be one of ==, = and != `)
cmdObj.Flags().BoolP("show-namespace", "", false, `Show the namespace column`)
cmdObj.Flags().BoolP("show-node", "", false, `Show the node name column`)
Expand Down Expand Up @@ -451,13 +453,21 @@ func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
}
}

rawMatchString := ""
if cmd.Flag("match") != nil {
if len(cmd.Flag("match").Value.String()) > 0 {
rawMatchString := cmd.Flag("match").Value.String()
f.filterList, err = splitAndFilterMatchList(rawMatchString, "ABCDEFGHIJKLMNOPQRSTUVWXYZ!%-.0123456789<>=*?", []string{"<=", ">=", "!=", "==", "=", "<", ">"})
if err != nil {
return commonFlags{}, err
}
rawMatchString = cmd.Flag("match").Value.String()
}
} else if cmd.Flag("match-only") != nil {
if len(cmd.Flag("match-only").Value.String()) > 0 {
rawMatchString = cmd.Flag("match-only").Value.String()
f.calcMatchOnly = true
}
}
if len(rawMatchString) > 0 {
f.filterList, err = splitAndFilterMatchList(rawMatchString, "ABCDEFGHIJKLMNOPQRSTUVWXYZ!%-.0123456789<>=*?", []string{"<=", ">=", "!=", "==", "=", "<", ">"})
if err != nil {
return commonFlags{}, err
}
}

Expand Down
49 changes: 26 additions & 23 deletions pkg/plugin/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type Table struct {
placeHolderID int
}

// sets the header row to the specified array of strings
// SetHeader sets the header row to the specified array of strings
// headerRow is always reinitilized to empty before headers are added
func (t *Table) SetHeader(headItem ...string) {

Expand All @@ -62,7 +62,7 @@ func (t *Table) SetHeader(headItem ...string) {
t.headCount = len(headItem)
}

// Adds a new row to the end of the table, accepts an array of strings
// AddRow Adds a new row to the end of the table, accepts an array of strings
func (t *Table) AddRow(row ...Cell) {
log := logger{location: "Table:AddRow"}
log.Debug("Start")
Expand Down Expand Up @@ -98,7 +98,7 @@ func (t *Table) AddRow(row ...Cell) {

}

// changes the order of columns displayed in the table, specifying a subset of the column
// Order changes the order of columns displayed in the table, specifying a subset of the column
// numbers will place those at the front in the order specified all other columns remain untouched
func (t *Table) Order(items ...int) {
// rather then reordering all columns we have an order array that we can loop through
Expand All @@ -122,7 +122,7 @@ func (t *Table) Order(items ...int) {

}

// select the column number to hide, columns numbers are the unsorted column number
// HideColumn select the column number to hide, columns numbers are the unsorted column number
func (t *Table) HideColumn(columnNumber int) {
log := logger{location: "Table:HideColumn"}
log.Debug("Start")
Expand All @@ -137,7 +137,7 @@ func (t *Table) HideColumn(columnNumber int) {
}
}

// prints the table on the terminal, taking the column order and visibiliy into account
// Print outputs the table on the terminal, taking the column order and visibiliy into account
func (t *Table) Print() {
headLine := ""
// loop through all headers and make a single line properly spaced
Expand Down Expand Up @@ -204,7 +204,7 @@ func (t *Table) Print() {

}

// Prints the table on the terminal as json, all fileds are shown and all are unsorted as
// PrintJson outputs the table on the terminal as json, all fileds are shown and all are unsorted as
// programs like jq can be used to filter and sort
func (t *Table) PrintJson() {
// loop through each row
Expand Down Expand Up @@ -237,7 +237,7 @@ func (t *Table) PrintJson() {

}

// Prints the table on the terminal as yaml, all fileds are shown and all are unsorted as
// PrintYaml outputs the table on the terminal as yaml, all fileds are shown and all are unsorted as
// other programs can be used to filter and sort
func (t *Table) PrintYaml() {
// loop through each row
Expand All @@ -261,7 +261,7 @@ func (t *Table) PrintYaml() {

}

// prints the key and value on a single line by its self. all fileds are shown and all are unsorted as
// PrintList outputs the key and value on a single line by its self. all fileds are shown and all are unsorted as
// other programs can be used to filter and sort
func (t *Table) PrintList() {
// loop through each row
Expand All @@ -278,7 +278,7 @@ func (t *Table) PrintList() {
}
}

// prints the table as a csv including the header row. all fileds are shown and all are unsorted as
// PrintCsv outputs the table as a csv including the header row. all fileds are shown and all are unsorted as
// other programs can be used to filter and sort
func (t *Table) PrintCsv() {

Expand Down Expand Up @@ -323,8 +323,8 @@ func (t *Table) PrintCsv() {
}
}

// Sort via the column number, uses the full column count including hidden columns
// sort function can be run multiple times and is cumalitive
// sort Sorts via the column number, uses the full column count including hidden columns
// function can be run multiple times and is cumalitive
func (t *Table) sort(list []int, columnNumber int, ascending bool) {
// rather then reordering all rows we have an order array that we can loop through
// sort contains the actual row number to use next
Expand Down Expand Up @@ -398,7 +398,7 @@ func (t *Table) sort(list []int, columnNumber int, ascending bool) {

}

// given a , seperated list of names match them to actual headers and sort each one in order
// SortByNames given a , seperated list of names match them to actual headers and sort each one in order
// by default sorts in ascending to revers use ! in front of the header name
// returns error on fail and nil otherwise
func (t *Table) SortByNames(name ...string) error {
Expand Down Expand Up @@ -452,9 +452,9 @@ func (t *Table) SortByNames(name ...string) error {
return nil
}

// run a pattten match, accepts * and ?
// strMatch run a pattten match, accepts * and ?
func strMatch(str string, pattern string) bool {
// shamelessly converted from c++ code on web as I was too laszy to work it out myself
// shamelessly converted from c++ code on web as I was too lazy to work it out myself
// source: https://www.geeksforgeeks.org/wildcard-pattern-matching/

n := len(str)
Expand Down Expand Up @@ -494,7 +494,7 @@ func strMatch(str string, pattern string) bool {
return lookup[n][m]
}

// quick wrapper to return a cell object containing the given string
// NewCellText quick wrapper to return a cell object containing the given string
func NewCellText(text string) Cell {

temp := strings.Replace(text, "\r", "\\r", -1)
Expand All @@ -507,6 +507,8 @@ func NewCellText(text string) Cell {
}
}

// NewCellTextIndent creates a text cell with an indentation indicator, this dosen't actually indent the cell it just
// tells table.go Print to indent it for us
func NewCellTextIndent(text string, indentLevel int) Cell {

temp := strings.Replace(text, "\r", "\\r", -1)
Expand All @@ -520,7 +522,7 @@ func NewCellTextIndent(text string, indentLevel int) Cell {
}
}

// quick wrapper to return a cell object containing the given string and int
// NewCellInt quick wrapper to return a cell object containing the given string and int
func NewCellInt(text string, value int64) Cell {
return Cell{
text: text,
Expand All @@ -529,7 +531,7 @@ func NewCellInt(text string, value int64) Cell {
}
}

// quick wrapper to return a cell object containing the given string float
// NewCellFloat quick wrapper to return a cell object containing the given string float
func NewCellFloat(text string, value float64) Cell {
return Cell{
text: text,
Expand All @@ -538,7 +540,7 @@ func NewCellFloat(text string, value float64) Cell {
}
}

// when given a columnID to work with it will calculate a range and
// ListOutOfRange when given a columnID to work with it will calculate a range and
// returns a list of rows with values outside that range
func (t *Table) ListOutOfRange(columnID int) ([]int, error) {
var upperFenceInt, lowerFenceInt int64
Expand Down Expand Up @@ -603,31 +605,31 @@ func (t *Table) ListOutOfRange(columnID int) ([]int, error) {
return out, nil
}

// does what it says on the tin
// GetRows does what it says on the tin
func (t *Table) GetRows() [][]Cell {
return t.data
}

// just sets the hide row flag, used by the print function to exclude the row from the output
// HideRows just sets the hide row flag, used by the print function to exclude the row from the output
func (t *Table) HideRows(rowID []int) {
for _, v := range rowID {
t.hideRow[v] = true
}
}

// given the current order and a list of rows caluclate the upper and lower boundy exclusion limit for the selected columnID
// getFencesInt given the current order and a list of rows caluclate the upper and lower boundy exclusion limit for the selected columnID
func (t *Table) getFencesInt(orderList []int, columnID int, rows [][]Cell) (int64, int64) {
upper, lower := t.getFencesBoundarys(orderList, columnID, rows, 1)
return upper.(int64), lower.(int64)
}

// given the current order and a list of rows caluclate the upper and lower boundy exclusion limit for the selected columnID
// getFencesFloat given the current order and a list of rows caluclate the upper and lower boundy exclusion limit for the selected columnID
func (t *Table) getFencesFloat(orderList []int, columnID int, rows [][]Cell) (float64, float64) {
upper, lower := t.getFencesBoundarys(orderList, columnID, rows, 2)
return upper.(float64), lower.(float64)
}

// the actual function to caluclate the upper and lower boundy exclusion limit
// getFencesBoundarys the actual function to caluclate the upper and lower boundy exclusion limit
func (t *Table) getFencesBoundarys(orderList []int, columnID int, rows [][]Cell, cellType int) (interface{}, interface{}) {
// find middle of the list
var q1Int, q3Int, iqrInt int64
Expand Down Expand Up @@ -741,6 +743,7 @@ func (t *Table) UpdatePlaceHolderRow(id int, cellList []Cell) {
t.placeHolder[id] = cellList
}

// HidePlaceHolderRow matches the placeholder id to an actual row number and calls HideRows to hide the row
func (t *Table) HidePlaceHolderRow(id int) {
for r := 0; r < len(t.data); r++ {
rowNum := t.rowOrder[r]
Expand Down

0 comments on commit 9d83650

Please sign in to comment.