diff --git a/docs/pages/reference/cli/tctl.mdx b/docs/pages/reference/cli/tctl.mdx index e0bdd3823f7c0..e562c81818624 100644 --- a/docs/pages/reference/cli/tctl.mdx +++ b/docs/pages/reference/cli/tctl.mdx @@ -242,6 +242,15 @@ Lists cluster alerts. This command can also be invoked as `tctl alerts ls`. | `--verbose` (`-v`) | false |boolean | If set, display detailed alert info (including acknowledged alerts) | | `--labels` | none | Comma-separated strings | A list of labels to filter by | +### Examples + +```code +$ tctl alerts list +ID Severity Expires In Message +------------------------------------ -------- ---------- ---------------------------------------------------------------- +da36b401-5688-426f-95b8-d0dd1ef27785 LOW 57m0s "The system is under maintenance, functionality may be limited." +``` + ## tctl auth export Exports public cluster CA certificates. This is useful for configuring diff --git a/tool/tctl/common/alert_command.go b/tool/tctl/common/alert_command.go index 163ca10569ae1..30638816b49a5 100644 --- a/tool/tctl/common/alert_command.go +++ b/tool/tctl/common/alert_command.go @@ -205,7 +205,7 @@ func (c *AlertCommand) List(ctx context.Context, client *authclient.Client) erro func displayAlertsText(alerts []types.ClusterAlert, verbose bool) { if verbose { - table := asciitable.MakeTable([]string{"ID", "Severity", "Message", "Created", "Labels"}) + table := asciitable.MakeTable([]string{"ID", "Severity", "Expires In", "Message", "Created", "Labels"}) for _, alert := range alerts { var labelPairs []string for key, val := range alert.Metadata.Labels { @@ -216,6 +216,7 @@ func displayAlertsText(alerts []types.ClusterAlert, verbose bool) { table.AddRow([]string{ alert.GetName(), alert.Spec.Severity.String(), + calculateTTL(alert.GetMetadata().Expires).String(), fmt.Sprintf("%q", alert.Spec.Message), alert.Spec.Created.Format(time.RFC822), strings.Join(labelPairs, ", "), @@ -223,14 +224,32 @@ func displayAlertsText(alerts []types.ClusterAlert, verbose bool) { } fmt.Println(table.AsBuffer().String()) } else { - table := asciitable.MakeTable([]string{"ID", "Severity", "Message"}) + table := asciitable.MakeTable([]string{"ID", "Severity", "Expires In", "Message"}) for _, alert := range alerts { - table.AddRow([]string{alert.GetName(), alert.Spec.Severity.String(), fmt.Sprintf("%q", alert.Spec.Message)}) + table.AddRow([]string{ + alert.GetName(), + alert.Spec.Severity.String(), + calculateTTL(alert.GetMetadata().Expires).String(), + fmt.Sprintf("%q", alert.Spec.Message), + }) } fmt.Println(table.AsBuffer().String()) } } +// calculateTTL returns the remaining TTL of the alert. +func calculateTTL(expiration *time.Time) time.Duration { + if expiration == nil { + return time.Duration(0) + } + remainingDuration := time.Until(*expiration) + if remainingDuration < 0 { + return time.Duration(0) + } + + return remainingDuration.Round(time.Minute) +} + func displayAlertsJSON(alerts []types.ClusterAlert) error { out, err := json.MarshalIndent(alerts, "", " ") if err != nil {