cli: improve output of eval commands (#13581)

Use the same output format when listing multiple evals in the `eval
list` command and when `eval status <prefix>` matches more than one
eval.

Include the eval namespace in all output formats and always include the
job ID in `eval status` since, even `node-update` evals are related to a
job.

Add Node ID to the evals table output to help differentiate
`node-update` evals.

Co-authored-by: James Rasell <jrasell@hashicorp.com>
This commit is contained in:
Luiz Aoqui 2022-07-07 13:13:34 -04:00 committed by GitHub
parent 6a032a54d2
commit 03433dd8af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 54 deletions

7
.changelog/13581.txt Normal file
View File

@ -0,0 +1,7 @@
```release-note:improvement
cli: display namespace and node ID in the `eval list` command and when `eval status` matches multiple evals
```
```release-note:improvement
cli: always display job ID and namespace in the `eval status` command
```

View File

@ -1,10 +1,8 @@
package command package command
import ( import (
"fmt"
"strings" "strings"
"github.com/hashicorp/nomad/api"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -46,23 +44,3 @@ func (f *EvalCommand) Synopsis() string {
func (f *EvalCommand) Name() string { return "eval" } func (f *EvalCommand) Name() string { return "eval" }
func (f *EvalCommand) Run(_ []string) int { return cli.RunResultHelp } func (f *EvalCommand) Run(_ []string) int { return cli.RunResultHelp }
// outputEvalList is a helper which outputs an array of evaluations as a list
// to the UI with key information such as ID and status.
func outputEvalList(ui cli.Ui, evals []*api.Evaluation, length int) {
out := make([]string, len(evals)+1)
out[0] = "ID|Priority|Triggered By|Job ID|Status|Placement Failures"
for i, eval := range evals {
failures, _ := evalFailureStatus(eval)
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s|%s",
limit(eval.ID, length),
eval.Priority,
eval.TriggeredBy,
eval.JobID,
eval.Status,
failures,
)
}
ui.Output(formatList(out))
}

View File

@ -334,7 +334,7 @@ func (e *EvalDeleteCommand) batchDelete(evals []*api.Evaluation) (int, bool, err
// avoided when deleting large quantities of evals. // avoided when deleting large quantities of evals.
if listEvals { if listEvals {
e.Ui.Output("") e.Ui.Output("")
outputEvalList(e.Ui, evals, shortId) e.Ui.Output(formatEvalList(evals, false))
e.Ui.Output("") e.Ui.Output("")
} }
} }

View File

@ -161,13 +161,7 @@ func (c *EvalListCommand) Run(args []string) int {
return 0 return 0
} }
// Truncate the id unless full length is requested c.Ui.Output(formatEvalList(evals, verbose))
length := shortId
if verbose {
length = fullId
}
outputEvalList(c.Ui, evals, length)
if qm.NextToken != "" { if qm.NextToken != "" {
c.Ui.Output(fmt.Sprintf(` c.Ui.Output(fmt.Sprintf(`
@ -204,3 +198,29 @@ func argsWithoutPageToken(osArgs []string) string {
} }
return strings.Join(args, " ") return strings.Join(args, " ")
} }
func formatEvalList(evals []*api.Evaluation, verbose bool) string {
// Truncate IDs unless full length is requested
length := shortId
if verbose {
length = fullId
}
out := make([]string, len(evals)+1)
out[0] = "ID|Priority|Triggered By|Job ID|Namespace|Node ID|Status|Placement Failures"
for i, eval := range evals {
failures, _ := evalFailureStatus(eval)
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s|%s|%s|%s",
limit(eval.ID, length),
eval.Priority,
eval.TriggeredBy,
eval.JobID,
eval.Namespace,
limit(eval.NodeID, length),
eval.Status,
failures,
)
}
return formatList(out)
}

View File

@ -155,20 +155,7 @@ func (c *EvalStatusCommand) Run(args []string) int {
} }
if len(evals) > 1 { if len(evals) > 1 {
// Format the evals c.Ui.Error(fmt.Sprintf("Prefix matched multiple evaluations\n\n%s", formatEvalList(evals, verbose)))
out := make([]string, len(evals)+1)
out[0] = "ID|Priority|Triggered By|Status|Placement Failures"
for i, eval := range evals {
failures, _ := evalFailureStatus(eval)
out[i+1] = fmt.Sprintf("%s|%d|%s|%s|%s",
limit(eval.ID, length),
eval.Priority,
eval.TriggeredBy,
eval.Status,
failures,
)
}
c.Ui.Error(fmt.Sprintf("Prefix matched multiple evaluations\n\n%s", formatList(out)))
return 1 return 1
} }
@ -223,6 +210,8 @@ func (c *EvalStatusCommand) Run(args []string) int {
fmt.Sprintf("Status Description|%s", statusDesc), fmt.Sprintf("Status Description|%s", statusDesc),
fmt.Sprintf("Type|%s", eval.Type), fmt.Sprintf("Type|%s", eval.Type),
fmt.Sprintf("TriggeredBy|%s", eval.TriggeredBy), fmt.Sprintf("TriggeredBy|%s", eval.TriggeredBy),
fmt.Sprintf("Job ID|%s", eval.JobID),
fmt.Sprintf("Namespace|%s", eval.Namespace),
} }
if triggerNoun != "" && triggerSubj != "" { if triggerNoun != "" && triggerSubj != "" {
@ -282,8 +271,6 @@ func sortedTaskGroupFromMetrics(groups map[string]*api.AllocationMetric) []strin
func getTriggerDetails(eval *api.Evaluation) (noun, subject string) { func getTriggerDetails(eval *api.Evaluation) (noun, subject string) {
switch eval.TriggeredBy { switch eval.TriggeredBy {
case "job-register", "job-deregister", "periodic-job", "rolling-update", "deployment-watcher":
return "Job ID", eval.JobID
case "node-update": case "node-update":
return "Node ID", eval.NodeID return "Node ID", eval.NodeID
case "max-plan-attempts": case "max-plan-attempts":

View File

@ -54,10 +54,10 @@ Delete all evaluations with status `pending` for the `example` job:
$ nomad eval delete -filter='Stauts == "pending" and JobID == "example"' $ nomad eval delete -filter='Stauts == "pending" and JobID == "example"'
Do you want to list evals (3) before deletion? [y/N] y Do you want to list evals (3) before deletion? [y/N] y
ID Priority Triggered By Job ID Status Placement Failures ID Priority Triggered By Job ID Namespace Node ID Status Placement Failures
cef92121 50 job-register example pending false cef92121 50 job-register example default <none> pending false
1c905ca0 50 job-register example pending false 1c905ca0 50 job-register example default <none> pending false
b9e77692 50 job-register example pending false b9e77692 50 job-register example default <none> pending false
Are you sure you want to delete 3 evals? [y/N] y Are you sure you want to delete 3 evals? [y/N] y

View File

@ -41,10 +41,10 @@ List all tracked evaluations:
```shell-session ```shell-session
$ nomad eval list -per-page 3 -status complete $ nomad eval list -per-page 3 -status complete
ID Priority Triggered By Job ID Status Placement Failures ID Priority Triggered By Job ID Namespace Node ID Status Placement Failures
456e37aa 50 deployment-watcher example complete false 456e37aa 50 deployment-watcher example default <none> complete false
1a1eafe6 50 alloc-stop example complete false 1a1eafe6 50 alloc-stop example default <node> complete false
3411e37b 50 job-register example complete false 3411e37b 50 job-register example default <node> complete false
Results have been paginated. To get the next page run: Results have been paginated. To get the next page run:

View File

@ -63,6 +63,7 @@ Status Description = complete
Type = service Type = service
TriggeredBy = job-register TriggeredBy = job-register
Job ID = example Job ID = example
Namespace = default
Priority = 50 Priority = 50
Placement Failures = true Placement Failures = true