Skip to content

Commit

Permalink
Add support for cursors to minder history list. (#3925)
Browse files Browse the repository at this point in the history
This change addes two flags to `minder history list` command, namely
`--cursor`, which lets the user specify the cursor to a specific page
of the list, and `--size`, which lets the user specify the number of
items to retrieve. The two flags can be used independently from one
another.

For obvious reasons, code was also added to print the cursors. I
picked an arbitrary position, but reviewed the style with James to
ensure some degree of uniformity with the rest of the product.

Fixes #3913
  • Loading branch information
blkt authored Jul 18, 2024
1 parent 189bd21 commit 3518a0c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
69 changes: 65 additions & 4 deletions cmd/cli/app/history/history_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package history
import (
"context"
"fmt"
"io"
"slices"
"strings"
"time"
Expand All @@ -42,6 +43,10 @@ var listCmd = &cobra.Command{
RunE: cli.GRPCClientWrapRunE(listCommand),
}

const (
defaultPageSize = 25
)

// listCommand is the profile "list" subcommand
func listCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc.ClientConn) error {
client := minderv1.NewEvalResultsServiceClient(conn)
Expand All @@ -54,6 +59,10 @@ func listCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc
remediationStatus := viper.GetStringSlice("remediation-status")
alertStatus := viper.GetStringSlice("alert-status")

// page options
cursorStr := viper.GetString("cursor")
size := viper.GetUint64("size")

format := viper.GetString("output")

// Ensure the output format is supported
Expand Down Expand Up @@ -89,7 +98,7 @@ func listCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc
Alert: alertStatus,
From: nil,
To: nil,
Cursor: nil,
Cursor: cursorFromOptions(cursorStr, size),
})
if err != nil {
return cli.MessageAndError("Error getting profile status", err)
Expand All @@ -109,11 +118,61 @@ func listCommand(ctx context.Context, cmd *cobra.Command, _ []string, conn *grpc
}
cmd.Println(out)
case app.Table:
historyTable := table.New(table.Simple, layouts.EvaluationHistory, nil)
renderRuleEvaluationStatusTable(resp.Data, historyTable)
historyTable.Render()
printTable(cmd.OutOrStderr(), resp)
}

return nil
}

func cursorFromOptions(cursorStr string, size uint64) *minderv1.Cursor {
var cursor *minderv1.Cursor
if cursorStr != "" || size != 0 {
cursor = &minderv1.Cursor{}
}
if cursorStr != "" {
cursor.Cursor = cursorStr
}
if size != 0 {
cursor.Size = size
}
return cursor
}

func printTable(w io.Writer, resp *minderv1.ListEvaluationHistoryResponse) {
historyTable := table.New(table.Simple, layouts.EvaluationHistory, nil)
renderRuleEvaluationStatusTable(resp.Data, historyTable)
historyTable.Render()
if next := getNext(resp); next != nil {
// Ordering is fixed for evaluation history
// log and the next page points to older
// records.
msg := fmt.Sprintf("Older records: %s",
cli.CursorStyle.Render(next.Cursor),
)
fmt.Fprintln(w, msg)
}
if prev := getPrev(resp); prev != nil {
// Ordering is fixed for evaluation history
// log and the previous page points to newer
// records.
msg := fmt.Sprintf("Newer records: %s",
cli.CursorStyle.Render(prev.Cursor),
)
fmt.Fprintln(w, msg)
}
}

func getNext(resp *minderv1.ListEvaluationHistoryResponse) *minderv1.Cursor {
if resp.Page != nil && resp.Page.Next != nil {
return resp.Page.Next
}
return nil
}

func getPrev(resp *minderv1.ListEvaluationHistoryResponse) *minderv1.Cursor {
if resp.Page != nil && resp.Page.Prev != nil {
return resp.Page.Prev
}
return nil
}

Expand Down Expand Up @@ -158,6 +217,8 @@ func init() {
listCmd.Flags().String("eval-status", "", evalFilterMsg)
listCmd.Flags().String("remediation-status", "", remediationFilterMsg)
listCmd.Flags().String("alert-status", "", alertFilterMsg)
listCmd.Flags().StringP("cursor", "c", "", "Fetch previous or next page from the list")
listCmd.Flags().Uint64P("size", "s", defaultPageSize, "Change the number of items fetched")
}

// TODO: we should have a common set of enums and validators in `internal`
Expand Down
7 changes: 6 additions & 1 deletion internal/util/cli/banners.go → internal/util/cli/styles.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ var (
BlackColor = lipgloss.Color("#000000")
)

// Styles
// Common styles
var (
CursorStyle = lipgloss.NewStyle().Foreground(SecondaryColor)
)

// Banner styles
var (
// DefaultBannerWidth is the default width for a banner
DefaultBannerWidth = 80
Expand Down

0 comments on commit 3518a0c

Please sign in to comment.