From 94abb839634874ef2e7e8559d71f20f45b5bacdb Mon Sep 17 00:00:00 2001 From: Xiaodong Ye Date: Mon, 13 Nov 2023 09:38:43 +0800 Subject: [PATCH] Add key action for + to do kubectl apply -f Signed-off-by: Xiaodong Ye --- internal/ui/key.go | 2 ++ internal/view/browser.go | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/internal/ui/key.go b/internal/ui/key.go index fbf0028c0e..7cd62ef36c 100644 --- a/internal/ui/key.go +++ b/internal/ui/key.go @@ -10,6 +10,7 @@ func initKeys() { tcell.KeyNames[KeyHelp] = "?" tcell.KeyNames[KeySlash] = "/" tcell.KeyNames[KeySpace] = "space" + tcell.KeyNames[KeyPlus] = "+" initNumbKeys() initStdKeys() @@ -77,6 +78,7 @@ const ( KeySlash = 47 KeyColon = 58 KeySpace = 32 + KeyPlus = 43 ) // Define Shift Keys. diff --git a/internal/view/browser.go b/internal/view/browser.go index 0678bfacd3..19df636af6 100644 --- a/internal/view/browser.go +++ b/internal/view/browser.go @@ -1,8 +1,11 @@ package view import ( + "bytes" "context" + "errors" "fmt" + "os" "sort" "strconv" "strings" @@ -20,6 +23,7 @@ import ( "github.com/derailed/tcell/v2" "github.com/rs/zerolog/log" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubectl/pkg/cmd/util/editor" ) // Browser represents a generic resource browser. @@ -359,6 +363,52 @@ func (b *Browser) describeCmd(evt *tcell.EventKey) *tcell.EventKey { return nil } +func (b *Browser) applyCmd(evt *tcell.EventKey) *tcell.EventKey { + b.Stop() + defer b.Start() + { + a := b.app + a.Halt() + defer a.Resume() + + var data []byte + var path string + var err error + + if !a.Suspend(func() { + edit := editor.NewDefaultEditor([]string{}) + buf := &bytes.Buffer{} + data, path, err = edit.LaunchTempFile("kubectl-apply-", ".yaml", buf) + }) { + time.AfterFunc(200*time.Millisecond, func() { + a.Flash().Err(errors.New("failed to suspend the application")) + }) + return nil + } + + defer os.Remove(path) + if err != nil { + time.AfterFunc(200*time.Millisecond, func() { + a.Flash().Errf("failed to edit a temporary file: %s", err) + }) + } else if len(data) > 0 { + args := make([]string, 0, 10) + args = append(args, "apply", "-f", path) + if err := runK(a, shellOpts{clear: true, args: args}); err != nil { + time.AfterFunc(200*time.Millisecond, func() { + a.Flash().Errf("failed to apply resource: %s", err) + }) + } else { + time.AfterFunc(200*time.Millisecond, func() { + a.Flash().Info("Resource applied successfully!") + }) + } + } + } + + return evt +} + func (b *Browser) editCmd(evt *tcell.EventKey) *tcell.EventKey { path := b.GetSelectedItem() if path == "" { @@ -481,6 +531,7 @@ func (b *Browser) refreshActions() { if client.Can(b.meta.Verbs, "delete") { aa[tcell.KeyCtrlD] = ui.NewKeyAction("Delete", b.deleteCmd, true) } + aa[ui.KeyPlus] = ui.NewKeyAction("Apply", b.applyCmd, true) } }