feat: add support for renaming contexts. (#2006)
* feat: add support for renaming contexts. * chore: try to reduce ABC * test: account for the `rename` hintmine
parent
2955e2251f
commit
c851277e33
|
|
@ -133,6 +133,26 @@ func (c *Config) DelContext(n string) error {
|
|||
return clientcmd.ModifyConfig(acc, cfg, true)
|
||||
}
|
||||
|
||||
// RenameContext renames a context.
|
||||
func (c *Config) RenameContext(old string, new string) error {
|
||||
cfg, err := c.RawConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := cfg.Contexts[new]; ok {
|
||||
return fmt.Errorf("context with name %s already exists", new)
|
||||
}
|
||||
cfg.Contexts[new] = cfg.Contexts[old]
|
||||
delete(cfg.Contexts, old)
|
||||
acc, err := c.ConfigAccess()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientcmd.ModifyConfig(acc, cfg, true)
|
||||
}
|
||||
|
||||
// ContextNames fetch all available contexts.
|
||||
func (c *Config) ContextNames() ([]string, error) {
|
||||
cfg, err := c.RawConfig()
|
||||
|
|
|
|||
|
|
@ -7,9 +7,15 @@ import (
|
|||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tcell/v2"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
renamePage = "rename"
|
||||
inputField = "New name:"
|
||||
)
|
||||
|
||||
// Context presents a context viewer.
|
||||
type Context struct {
|
||||
ResourceViewer
|
||||
|
|
@ -28,6 +34,63 @@ func NewContext(gvr client.GVR) ResourceViewer {
|
|||
|
||||
func (c *Context) bindKeys(aa ui.KeyActions) {
|
||||
aa.Delete(ui.KeyShiftA, tcell.KeyCtrlSpace, ui.KeySpace)
|
||||
aa.Add(ui.KeyActions{
|
||||
ui.KeyR: ui.NewKeyAction("Rename", c.renameCmd, true),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Context) renameCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
contextName := c.GetTable().GetSelectedItem()
|
||||
if contextName == "" {
|
||||
return evt
|
||||
}
|
||||
|
||||
app := c.App()
|
||||
c.showRenameModal(app, contextName, c.renameDialogCallback)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) renameDialogCallback(form *tview.Form, contextName string) error {
|
||||
app := c.App()
|
||||
input := form.GetFormItemByLabel(inputField).(*tview.InputField)
|
||||
if err := app.factory.Client().Config().RenameContext(contextName, input.GetText()); err != nil {
|
||||
c.App().Flash().Err(err)
|
||||
return nil
|
||||
}
|
||||
c.Refresh()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) showRenameModal(a *App, name string, ok func(form *tview.Form, contextName string)(error)) {
|
||||
p := a.Content.Pages
|
||||
f := c.makeStyledForm()
|
||||
f.AddInputField(inputField, name, 0, nil, nil).
|
||||
AddButton("OK", func() {
|
||||
if err := ok(f, name); err != nil {
|
||||
c.App().Flash().Err(err)
|
||||
return
|
||||
}
|
||||
p.RemovePage(renamePage)
|
||||
}).
|
||||
AddButton("Cancel", func() {
|
||||
p.RemovePage(renamePage)
|
||||
})
|
||||
m := tview.NewModalForm("<Rename>", f)
|
||||
p.AddPage(renamePage, m, false, false)
|
||||
p.ShowPage(renamePage)
|
||||
}
|
||||
|
||||
func (c *Context) 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 *Context) useCtx(app *App, model ui.Tabular, gvr, path string) {
|
||||
|
|
|
|||
|
|
@ -13,5 +13,5 @@ func TestContext(t *testing.T) {
|
|||
|
||||
assert.Nil(t, ctx.Init(makeCtx()))
|
||||
assert.Equal(t, "Contexts", ctx.Name())
|
||||
assert.Equal(t, 4, len(ctx.Hints()))
|
||||
assert.Equal(t, 5, len(ctx.Hints()))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue