diff --git a/internal/ui/dialog/delete.go b/internal/ui/dialog/delete.go index bd1bb675b3..65e985d99d 100644 --- a/internal/ui/dialog/delete.go +++ b/internal/ui/dialog/delete.go @@ -1,6 +1,8 @@ package dialog import ( + "fmt" + "github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/ui" "github.com/derailed/tview" @@ -25,7 +27,7 @@ var propagationOptions []string = []string{ } // ShowDelete pops a resource deletion dialog. -func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, cancel cancelFunc) { +func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, cancel cancelFunc, challenge string) { propagation, force := "", false f := tview.NewForm() f.SetItemPadding(0) @@ -45,11 +47,25 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca f.AddCheckbox("Force:", force, func(_ string, checked bool) { force = checked }) + + confirmCheck := "" + if challenge != "" { + f.AddInputField(fmt.Sprintf("Confirm with: \"%s\":", challenge), confirmCheck, 30, nil, func(text string) { + confirmCheck = text + }) + } + f.AddButton("Cancel", func() { dismiss(pages) cancel() }) + f.AddButton("OK", func() { + if challenge != "" && confirmCheck != challenge { + cancel() + return + } + switch propagation { case noDeletePropagation: ok(nil, force) diff --git a/internal/ui/dialog/delete_test.go b/internal/ui/dialog/delete_test.go index a4c141668e..830bf8c183 100644 --- a/internal/ui/dialog/delete_test.go +++ b/internal/ui/dialog/delete_test.go @@ -20,7 +20,7 @@ func TestDeleteDialog(t *testing.T) { caFunc := func() { assert.True(t, true) } - ShowDelete(config.Dialog{}, p, "Yo", okFunc, caFunc) + ShowDelete(config.Dialog{}, p, "Yo", okFunc, caFunc, "") d := p.GetPrimitive(dialogKey).(*tview.ModalForm) assert.NotNil(t, d) diff --git a/internal/view/browser.go b/internal/view/browser.go index ab9f46f8c7..73b1e345f0 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -344,7 +344,13 @@ func (b *Browser) deleteCmd(evt *tcell.EventKey) *tcell.EventKey { b.simpleDelete(selections, msg) return nil } - b.resourceDelete(selections, msg) + + challenge := "" + if b.GVR().R() == "nodes" { + challenge = "delete!" + } + + b.resourceDelete(selections, msg, challenge) } return nil @@ -542,7 +548,7 @@ func (b *Browser) simpleDelete(selections []string, msg string) { }, func() {}) } -func (b *Browser) resourceDelete(selections []string, msg string) { +func (b *Browser) resourceDelete(selections []string, msg string, challenge string ) { dialog.ShowDelete(b.app.Styles.Dialog(), b.app.Content.Pages, msg, func(propagation *metav1.DeletionPropagation, force bool) { b.ShowDeleted() if len(selections) > 1 { @@ -563,5 +569,5 @@ func (b *Browser) resourceDelete(selections []string, msg string) { b.GetTable().DeleteMark(sel) } b.refresh() - }, func() {}) + }, func() {}, challenge) } diff --git a/internal/view/xray.go b/internal/view/xray.go index 87a05b38c5..e1278b2ab6 100644 --- a/internal/view/xray.go +++ b/internal/view/xray.go @@ -683,7 +683,7 @@ func (x *Xray) resourceDelete(gvr client.GVR, spec *xray.NodeSpec, msg string) { x.app.factory.DeleteForwarder(spec.Path()) } x.Refresh() - }, func() {}) + }, func() {}, "") } // ----------------------------------------------------------------------------