Allow all deletion propagation policies (#1553)
* Allow all deletion propagation policies * Add "none" deletion propagation policymine
parent
74d3d6ac23
commit
8e8f874b1e
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/derailed/k9s/internal"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ type Benchmark struct {
|
|||
}
|
||||
|
||||
// Delete nukes a resource.
|
||||
func (b *Benchmark) Delete(path string, cascade, force bool) error {
|
||||
func (b *Benchmark) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ func (g *Generic) ToYAML(path string, showManaged bool) (string, error) {
|
|||
}
|
||||
|
||||
// Delete deletes a resource.
|
||||
func (g *Generic) Delete(path string, cascade, force bool) error {
|
||||
func (g *Generic) Delete(path string, propagation *metav1.DeletionPropagation, force bool) error {
|
||||
ns, n := client.Namespaced(path)
|
||||
auth, err := g.Client().CanI(ns, g.gvr.String(), []string{client.DeleteVerb})
|
||||
if err != nil {
|
||||
|
|
@ -100,16 +100,12 @@ func (g *Generic) Delete(path string, cascade, force bool) error {
|
|||
return fmt.Errorf("user is not authorized to delete %s", path)
|
||||
}
|
||||
|
||||
p := metav1.DeletePropagationOrphan
|
||||
if cascade {
|
||||
p = metav1.DeletePropagationBackground
|
||||
}
|
||||
var grace *int64
|
||||
if force {
|
||||
grace = &defaultKillGrace
|
||||
}
|
||||
opts := metav1.DeleteOptions{
|
||||
PropagationPolicy: &p,
|
||||
PropagationPolicy: propagation,
|
||||
GracePeriodSeconds: grace,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/yaml.v2"
|
||||
"helm.sh/helm/v3/pkg/action"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ func (c *Helm) ToYAML(path string, showManaged bool) (string, error) {
|
|||
}
|
||||
|
||||
// Delete uninstall a Helm.
|
||||
func (c *Helm) Delete(path string, cascade, force bool) error {
|
||||
func (c *Helm) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := c.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/rs/zerolog/log"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ type PortForward struct {
|
|||
}
|
||||
|
||||
// Delete a portforward.
|
||||
func (p *PortForward) Delete(path string, cascade, force bool) error {
|
||||
func (p *PortForward) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
p.Factory.DeleteForwarder(path)
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/derailed/k9s/internal"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ type ScreenDump struct {
|
|||
}
|
||||
|
||||
// Delete a ScreenDump.
|
||||
func (d *ScreenDump) Delete(path string, cascade, force bool) error {
|
||||
func (d *ScreenDump) Delete(path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ type Controller interface {
|
|||
// Nuker represents a resource deleter.
|
||||
type Nuker interface {
|
||||
// Delete removes a resource from the api server.
|
||||
Delete(path string, cascade, force bool) error
|
||||
Delete(path string, propagation *metav1.DeletionPropagation, force bool) error
|
||||
}
|
||||
|
||||
// Switchable represents a switchable resource.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/rs/zerolog/log"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
|
@ -110,7 +111,7 @@ func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) {
|
|||
}
|
||||
|
||||
// Delete deletes a resource.
|
||||
func (t *Table) Delete(ctx context.Context, path string, cascade, force bool) error {
|
||||
func (t *Table) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error {
|
||||
meta, err := getMeta(ctx, t.gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -121,7 +122,7 @@ func (t *Table) Delete(ctx context.Context, path string, cascade, force bool) er
|
|||
return fmt.Errorf("no nuker for %q", meta.DAO.GVR())
|
||||
}
|
||||
|
||||
return nuker.Delete(path, cascade, force)
|
||||
return nuker.Delete(path, propagation, force)
|
||||
}
|
||||
|
||||
// GetNamespace returns the model namespace.
|
||||
|
|
|
|||
|
|
@ -4,18 +4,30 @@ import (
|
|||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const deleteKey = "delete"
|
||||
|
||||
const noDeletePropagation = "None"
|
||||
|
||||
const defaultPropagationIdx = 0
|
||||
|
||||
var propagationOptions []string = []string{
|
||||
string(metav1.DeletePropagationBackground),
|
||||
string(metav1.DeletePropagationForeground),
|
||||
string(metav1.DeletePropagationOrphan),
|
||||
noDeletePropagation,
|
||||
}
|
||||
|
||||
type (
|
||||
okFunc func(cascade, force bool)
|
||||
okFunc func(propagation *metav1.DeletionPropagation, force bool)
|
||||
cancelFunc func()
|
||||
)
|
||||
|
||||
// ShowDelete pops a resource deletion dialog.
|
||||
func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, cancel cancelFunc) {
|
||||
cascade, force := true, false
|
||||
propagation, force := "", false
|
||||
f := tview.NewForm()
|
||||
f.SetItemPadding(0)
|
||||
f.SetButtonsAlign(tview.AlignCenter).
|
||||
|
|
@ -23,8 +35,8 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca
|
|||
SetButtonTextColor(styles.ButtonFgColor.Color()).
|
||||
SetLabelColor(styles.LabelFgColor.Color()).
|
||||
SetFieldTextColor(styles.FieldFgColor.Color())
|
||||
f.AddCheckbox("Cascade:", cascade, func(_ string, checked bool) {
|
||||
cascade = checked
|
||||
f.AddDropDown("Propagation:", propagationOptions, defaultPropagationIdx, func(_ string, optionIndex int) {
|
||||
propagation = propagationOptions[optionIndex]
|
||||
})
|
||||
f.AddCheckbox("Force:", force, func(_ string, checked bool) {
|
||||
force = checked
|
||||
|
|
@ -34,7 +46,13 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca
|
|||
cancel()
|
||||
})
|
||||
f.AddButton("OK", func() {
|
||||
ok(cascade, force)
|
||||
switch propagation {
|
||||
case noDeletePropagation:
|
||||
ok(nil, force)
|
||||
default:
|
||||
p := metav1.DeletionPropagation(propagation)
|
||||
ok(&p, force)
|
||||
}
|
||||
dismissDelete(pages)
|
||||
cancel()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -7,13 +7,14 @@ import (
|
|||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestDeleteDialog(t *testing.T) {
|
||||
p := ui.NewPages()
|
||||
|
||||
okFunc := func(c, f bool) {
|
||||
assert.True(t, c)
|
||||
okFunc := func(p *metav1.DeletionPropagation, f bool) {
|
||||
assert.Equal(t, propagationOptions[defaultPropagationIdx], p)
|
||||
assert.True(t, f)
|
||||
}
|
||||
caFunc := func() {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ func (t *mockModel) Get(ctx context.Context, path string) (runtime.Object, error
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockModel) Delete(ctx context.Context, path string, c, f bool) error {
|
||||
func (t *mockModel) Delete(ctx context.Context, path string, p *metav1.DeletionPropagation, f bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -77,5 +78,5 @@ type Tabular interface {
|
|||
RemoveListener(model.TableListener)
|
||||
|
||||
// Delete a resource.
|
||||
Delete(ctx context.Context, path string, cascade, force bool) error
|
||||
Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ func (t *mockModel) Get(context.Context, string) (runtime.Object, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockModel) Delete(context.Context, string, bool, bool) error {
|
||||
func (t *mockModel) Delete(context.Context, string, *metav1.DeletionPropagation, bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ func (b *Browser) simpleDelete(selections []string, msg string) {
|
|||
b.app.Flash().Errf("Invalid nuker %T", b.accessor)
|
||||
continue
|
||||
}
|
||||
if err := nuker.Delete(sel, true, true); err != nil {
|
||||
if err := nuker.Delete(sel, nil, true); err != nil {
|
||||
b.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
b.app.factory.DeleteForwarder(sel)
|
||||
|
|
@ -535,7 +535,7 @@ func (b *Browser) simpleDelete(selections []string, msg string) {
|
|||
}
|
||||
|
||||
func (b *Browser) resourceDelete(selections []string, msg string) {
|
||||
dialog.ShowDelete(b.app.Styles.Dialog(), b.app.Content.Pages, msg, func(cascade, force bool) {
|
||||
dialog.ShowDelete(b.app.Styles.Dialog(), b.app.Content.Pages, msg, func(propagation *metav1.DeletionPropagation, force bool) {
|
||||
b.ShowDeleted()
|
||||
if len(selections) > 1 {
|
||||
b.app.Flash().Infof("Delete %d marked %s", len(selections), b.GVR())
|
||||
|
|
@ -543,7 +543,7 @@ func (b *Browser) resourceDelete(selections []string, msg string) {
|
|||
b.app.Flash().Infof("Delete resource %s %s", b.GVR(), selections[0])
|
||||
}
|
||||
for _, sel := range selections {
|
||||
if err := b.GetModel().Delete(b.defaultContext(), sel, cascade, force); err != nil {
|
||||
if err := b.GetModel().Delete(b.defaultContext(), sel, propagation, force); err != nil {
|
||||
b.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
b.app.factory.DeleteForwarder(sel)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ func (p *PortForward) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
for _, s := range selections {
|
||||
var pf dao.PortForward
|
||||
pf.Init(p.App().factory, client.NewGVR("portforwards"))
|
||||
if err := pf.Delete(s, true, true); err != nil {
|
||||
if err := pf.Delete(s, nil, true); err != nil {
|
||||
p.App().Flash().Err(err)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ func (p *Pod) killCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
p.GetTable().ShowDeleted()
|
||||
for _, path := range selections {
|
||||
if err := nuker.Delete(path, true, true); err != nil {
|
||||
if err := nuker.Delete(path, nil, true); err != nil {
|
||||
p.App().Flash().Errf("Delete failed with %s", err)
|
||||
} else {
|
||||
p.App().factory.DeleteForwarder(path)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/derailed/tview"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
|
|
@ -110,7 +111,7 @@ func (t *mockTableModel) Get(context.Context, string) (runtime.Object, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockTableModel) Delete(context.Context, string, bool, bool) error {
|
||||
func (t *mockTableModel) Delete(context.Context, string, *metav1.DeletionPropagation, bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ func (x *Xray) styleTitle() string {
|
|||
}
|
||||
|
||||
func (x *Xray) resourceDelete(gvr client.GVR, spec *xray.NodeSpec, msg string) {
|
||||
dialog.ShowDelete(x.app.Styles.Dialog(), x.app.Content.Pages, msg, func(cascade, force bool) {
|
||||
dialog.ShowDelete(x.app.Styles.Dialog(), x.app.Content.Pages, msg, func(propagation *metav1.DeletionPropagation, force bool) {
|
||||
x.app.Flash().Infof("Delete resource %s %s", spec.GVR(), spec.Path())
|
||||
accessor, err := dao.AccessorFor(x.app.factory, gvr)
|
||||
if err != nil {
|
||||
|
|
@ -670,7 +670,7 @@ func (x *Xray) resourceDelete(gvr client.GVR, spec *xray.NodeSpec, msg string) {
|
|||
x.app.Flash().Errf("Invalid nuker %T", accessor)
|
||||
return
|
||||
}
|
||||
if err := nuker.Delete(spec.Path(), true, true); err != nil {
|
||||
if err := nuker.Delete(spec.Path(), nil, true); err != nil {
|
||||
x.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
x.app.Flash().Infof("%s `%s deleted successfully", x.GVR(), spec.Path())
|
||||
|
|
|
|||
Loading…
Reference in New Issue