Skip to content

Commit

Permalink
added --match flag to allow filtering before table output to screen
Browse files Browse the repository at this point in the history
  • Loading branch information
NimbleArchitect committed Mar 18, 2022
1 parent cb40e55 commit ed70fc2
Show file tree
Hide file tree
Showing 11 changed files with 306 additions and 33 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ With ice you can peer inside a pod and easily see volume, image, port and exec c
supports all the standard kubectl flags in addition to:
```
Flags:
-A, --all-namespaces list containers form pods in all namespaces
-A, --all-namespaces List containers form pods in all namespaces
-c, --container string Container name. If set shows only the named containers containers in the pod
--context string The name of the kubeconfig context to use
--match string Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and !=
-n, --namespace string If present, the namespace scope for this CLI request
-l, --selector string Selector (label query) to filter on
```
Expand Down
7 changes: 7 additions & 0 deletions pkg/plugin/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ func Commands(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args
"T", "PODNAME", "CONTAINER", "COMMAND", "ARGUMENTS",
)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
// we need to hide the pod name in the table
table.HideColumn(1)
Expand Down
7 changes: 7 additions & 0 deletions pkg/plugin/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ func Image(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args []
"T", "PODNAME", "CONTAINER", "PULL", "IMAGE",
)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
// we need to hide the pod name in the table
table.HideColumn(1)
Expand Down
81 changes: 54 additions & 27 deletions pkg/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (
)

type commonFlags struct {
allNamespaces bool
labels string
container string
sortList []string
outputAs string
allNamespaces bool // should we search all namespaces
container string // name of the container to search for
filterList []string // used to filter out rows form the table during Print function
labels string // k8s pod labels
outputAs string // how to output the table, currently only accepts json
sortList []string //column names to sort on when table.Print() is called
}

func InitSubCommands(rootCmd *cobra.Command) {
Expand Down Expand Up @@ -236,10 +237,12 @@ 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, only json is supported`)

cmdObj.Flags().StringP("match", "", "", `Filters out results, comma seperated list of COLUMN OP VALUE, where OP can be one of ==,<,>,<=,>= and != `)
}

func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
var err error

f := commonFlags{}

if cmd.Flag("all-namespaces").Value.String() == "true" {
Expand Down Expand Up @@ -278,30 +281,54 @@ func processCommonFlags(cmd *cobra.Command) (commonFlags, error) {
// we cant check header names as we dont know them at this point
if len(cmd.Flag("sort").Value.String()) > 0 {
rawSortString := cmd.Flag("sort").Value.String()
rawSortList := strings.Split(rawSortString, ",")
for i := 0; i < len(rawSortList); i++ {
safeStr := ""
rawItem := strings.TrimSpace(rawSortList[i])
if len(rawItem) <= 0 {
continue
}

// current used chars in headers are A-Z ! and % nothing else is needed
// so pointless using regex
rawUpper := strings.ToUpper(rawItem)
for _, v := range strings.Split(rawUpper, "") {
if strings.Contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ!%-", v) {
safeStr += v
}
}

if len(safeStr) != len(rawItem) {
return commonFlags{}, errors.New("invalid characters in column name")
}
f.sortList = append(f.sortList, safeStr)
f.sortList, err = splitAndFilterList(rawSortString, "ABCDEFGHIJKLMNOPQRSTUVWXYZ!%-")
if err != nil {
return commonFlags{}, err
}
}
}

if cmd.Flag("match") != nil {
if len(cmd.Flag("match").Value.String()) > 0 {
rawMatchString := cmd.Flag("match").Value.String()
f.filterList, err = splitAndFilterList(rawMatchString, "ABCDEFGHIJKLMNOPQRSTUVWXYZ!%-0123456789<>=")
if err != nil {
return commonFlags{}, err
}
}
}

return f, nil
}

func splitAndFilterList(rawSortString string, filterString string) ([]string, error) {
// based on a whitelist approach sort just removes invalid chars,
// we cant check header names as we dont know them at this point
var sortList []string
var rawCase string

rawSortList := strings.Split(rawSortString, ",")
for i := 0; i < len(rawSortList); i++ {
safeStr := ""
rawItem := strings.TrimSpace(rawSortList[i])
if len(rawItem) <= 0 {
continue
}

// current used chars in headers are A-Z ! and % nothing else is needed
// so pointless using regex
rawCase = strings.ToUpper(rawItem)
for _, v := range strings.Split(rawCase, "") {
if strings.Contains(filterString, v) {
safeStr += v
}
}

if len(safeStr) != len(rawItem) {
return []string{}, errors.New("invalid characters in column name")
}
sortList = append(sortList, safeStr)
}

return sortList, nil
}
7 changes: 7 additions & 0 deletions pkg/plugin/ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,14 @@ func Ports(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args []
table.SetHeader(
"T", "PODNAME", "CONTAINER", "PORTNAME", "PORT", "PROTO", "HOSTPORT",
)
table.SetColumnTypeInt(4, 6)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}
if !showPodName {
// we need to hide the pod name in the table
table.HideColumn(1)
Expand Down
8 changes: 8 additions & 0 deletions pkg/plugin/probes.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ func Probes(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args [
table.SetHeader(
"PODNAME", "CONTAINER", "PROBE", "DELAY", "PERIOD", "TIMEOUT", "SUCCESS", "FAILURE", "CHECK", "ACTION",
)
table.SetColumnTypeInt(3, 4, 5)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
// we need to hide the pod name in the table
Expand Down
10 changes: 9 additions & 1 deletion pkg/plugin/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ func Resources(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, arg
table.SetHeader(
"T", "PODNAME", "CONTAINER", "USED", "REQUEST", "LIMIT", "%REQ", "%LIMIT",
)
table.SetColumnTypeInt(3, 4, 5, 6, 7)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
// we need to hide the pod name in the table
Expand Down Expand Up @@ -150,7 +158,7 @@ func statsProcessTableRow(container v1.Container, metrics v1.ResourceList, podNa
if showRaw {
displayValue = metrics.Cpu().String()
} else {
displayValue = fmt.Sprintf("%dm", metrics.Cpu().MilliValue())
displayValue = fmt.Sprintf("%d", metrics.Cpu().MilliValue())
floatfmt = "%.2f"
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/plugin/restarts.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ func Restarts(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args
table.SetHeader(
"T", "PODNAME", "CONTAINER", "RESTARTS",
)
table.SetColumnTypeInt(3)

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
// we need to hide the pod name in the table
Expand Down
9 changes: 9 additions & 0 deletions pkg/plugin/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,19 @@ func Status(cmd *cobra.Command, kubeFlags *genericclioptions.ConfigFlags, args [
table.SetHeader(
"T", "PODNAME", "CONTAINER", "READY", "STARTED", "RESTARTS", "STATE", "REASON", "EXIT-CODE", "SIGNAL", "TIMESTAMP", "MESSAGE",
)
table.SetColumnTypeInt(5, 8, 9)
} else {
table.SetHeader(
"T", "PODNAME", "CONTAINER", "STATE", "REASON", "EXIT-CODE", "SIGNAL", "TIMESTAMP", "MESSAGE",
)
table.SetColumnTypeInt(5, 6)
}

if len(commonFlagList.filterList) >= 1 {
err = table.SetFilter(commonFlagList.filterList)
if err != nil {
return err
}
}

if !showPodName {
Expand Down
Loading

0 comments on commit ed70fc2

Please sign in to comment.