add toogle suspend actions in CronJob (#1010)

add toggleSuspend action and remove separate suspend/unsuspend

Allow to toggleSuspend on one resource only and update text

fix showSuspendDialog

Co-authored-by: Ludovico Russo <ludovico.russo@redcarbon.ai>
mine
Ludovico Russo 2021-03-19 14:03:09 +01:00 committed by GitHub
parent e8c371b1a7
commit b29e368cb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 0 deletions

View File

@ -107,6 +107,32 @@ func (c *CronJob) ScanSA(ctx context.Context, fqn string, wait bool) (Refs, erro
return refs, nil
}
// SetSuspend a CronJob.
func (c *CronJob) SetSuspend(ctx context.Context, path string, suspend bool) error {
ns, n := client.Namespaced(path)
auth, err := c.Client().CanI(ns, "batch/v1beta1/CronJob", []string{client.GetVerb, client.UpdateVerb})
if err != nil {
return err
}
if !auth {
return fmt.Errorf("user is not authorized to update a CronJob")
}
dial, err := c.Client().Dial()
if err != nil {
return err
}
cronjob, err := dial.BatchV1beta1().CronJobs(ns).Get(ctx, n, metav1.GetOptions{})
if err != nil {
return err
}
cronjob.Spec.Suspend = &suspend
_, err = dial.BatchV1beta1().CronJobs(ns).Update(ctx, cronjob, metav1.UpdateOptions{})
return err
}
// Scan scans for cluster resource refs.
func (c *CronJob) Scan(ctx context.Context, gvr, fqn string, wait bool) (Refs, error) {
ns, n := client.Namespaced(fqn)

View File

@ -3,12 +3,14 @@ package view
import (
"context"
"fmt"
"strings"
"github.com/derailed/k9s/internal"
"github.com/derailed/k9s/internal/client"
"github.com/derailed/k9s/internal/dao"
"github.com/derailed/k9s/internal/render"
"github.com/derailed/k9s/internal/ui"
"github.com/derailed/tview"
"github.com/gdamore/tcell/v2"
"github.com/rs/zerolog/log"
batchv1beta1 "k8s.io/api/batch/v1beta1"
@ -17,6 +19,8 @@ import (
"k8s.io/apimachinery/pkg/runtime"
)
const suspendDialogKey = "suspend"
// CronJob represents a cronjob viewer.
type CronJob struct {
ResourceViewer
@ -64,9 +68,99 @@ func jobCtx(path, uid string) ContextFunc {
func (c *CronJob) bindKeys(aa ui.KeyActions) {
aa.Add(ui.KeyActions{
tcell.KeyCtrlT: ui.NewKeyAction("Trigger", c.trigger, true),
ui.KeyShiftS: ui.NewKeyAction("ToggleSuspend", c.toggleSuspend, true),
})
}
func (c *CronJob) toggleSuspend(evt *tcell.EventKey) *tcell.EventKey {
sel := c.GetTable().GetSelectedItem()
if sel == "" {
return evt
}
c.Stop()
defer c.Start()
c.showSuspendDialog(sel)
return nil
}
func (c *CronJob) showSuspendDialog(sel string) {
cell := c.GetTable().GetCell(c.GetTable().GetSelectedRowIndex(), c.GetTable().NameColIndex() + 2)
if cell == nil {
return
}
suspended := strings.TrimSpace(cell.Text) == "true"
title := "Suspend"
if suspended {
title = "Unsuspend"
}
confirm := tview.NewModalForm(fmt.Sprintf("<%s>", title), c.makeSuspendForm(sel, !suspended))
confirm.SetText(fmt.Sprintf("%s CronJob %s", title, sel))
confirm.SetDoneFunc(func(int, string) {
c.dismissDialog()
})
c.App().Content.AddPage(suspendDialogKey, confirm, false, false)
c.App().Content.ShowPage(suspendDialogKey)
}
func (c *CronJob) makeSuspendForm(sel string, suspend bool) *tview.Form {
f := c.makeStyledForm()
action := "suspended"
if !suspend {
action ="unsuspended"
}
f.AddButton("OK", func() {
defer c.dismissDialog()
ctx, cancel := context.WithTimeout(context.Background(), c.App().Conn().Config().CallTimeout())
defer cancel()
if err := c.setSuspend(ctx, sel, suspend); err != nil {
log.Error().Err(err).Msgf("CronJOb %s %s failed", sel, action)
c.App().Flash().Err(err)
} else {
c.App().Flash().Infof("CronJOb %s %s successfully", sel, action)
}
})
f.AddButton("Cancel", func() {
c.dismissDialog()
})
return f
}
func (c *CronJob) setSuspend(ctx context.Context, path string, suspend bool) error {
res, err := dao.AccessorFor(c.App().factory, c.GVR())
if err != nil {
return nil
}
cronJob, ok := res.(*dao.CronJob)
if !ok {
return fmt.Errorf("expecting a scalable resource for %q", c.GVR())
}
return cronJob.SetSuspend(ctx, path, suspend)
}
func (c *CronJob) makeStyledForm() *tview.Form {
f := tview.NewForm()
f.SetItemPadding(0)
f.SetButtonsAlign(tview.AlignCenter).
SetButtonBackgroundColor(tview.Styles.PrimitiveBackgroundColor).
SetButtonTextColor(tview.Styles.PrimaryTextColor).
SetLabelColor(tcell.ColorAqua).
SetFieldTextColor(tcell.ColorOrange)
return f
}
func (c *CronJob) dismissDialog() {
c.App().Content.RemovePage(suspendDialogKey)
}
func (c *CronJob) trigger(evt *tcell.EventKey) *tcell.EventKey {
sel := c.GetTable().GetSelectedItem()
if sel == "" {