feat: Add action to restart rollout of dp, ds, sts
parent
ee1b734464
commit
b246ca0752
|
|
@ -2,6 +2,8 @@ package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Deployment represents a Kubernetes Deployment.
|
// Deployment represents a Kubernetes Deployment.
|
||||||
|
|
@ -54,3 +56,19 @@ func (d *Deployment) Scale(ns, n string, replicas int32) error {
|
||||||
_, err = d.DialOrDie().AppsV1().Deployments(ns).UpdateScale(n, scale)
|
_, err = d.DialOrDie().AppsV1().Deployments(ns).UpdateScale(n, scale)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart a Deployment rollout.
|
||||||
|
func (d *Deployment) Restart(ns, n string) error {
|
||||||
|
|
||||||
|
dp, err := d.DialOrDie().AppsV1().Deployments(ns).Get(n, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
update, err := polymorphichelpers.ObjectRestarterFn(dp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = d.DialOrDie().AppsV1().Deployments(ns).Patch(dp.Name, types.StrategicMergePatchType, update)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DaemonSet represents a Kubernetes DaemonSet
|
// DaemonSet represents a Kubernetes DaemonSet
|
||||||
|
|
@ -48,3 +50,19 @@ func (d *DaemonSet) Delete(ns, n string, cascade, force bool) error {
|
||||||
PropagationPolicy: &p,
|
PropagationPolicy: &p,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart a DaemonSet rollout.
|
||||||
|
func (d *DaemonSet) Restart(ns, n string) error {
|
||||||
|
|
||||||
|
ds, err := d.DialOrDie().AppsV1().DaemonSets(ns).Get(n, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
update, err := polymorphichelpers.ObjectRestarterFn(ds)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = d.DialOrDie().AppsV1().DaemonSets(ns).Patch(ds.Name, types.StrategicMergePatchType, update)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/kubectl/pkg/polymorphichelpers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StatefulSet manages a Kubernetes StatefulSet.
|
// StatefulSet manages a Kubernetes StatefulSet.
|
||||||
|
|
@ -60,3 +62,19 @@ func (s *StatefulSet) Scale(ns, n string, replicas int32) error {
|
||||||
_, err = s.DialOrDie().AppsV1().StatefulSets(ns).UpdateScale(n, scale)
|
_, err = s.DialOrDie().AppsV1().StatefulSets(ns).UpdateScale(n, scale)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart a StatefulSet rollout.
|
||||||
|
func (s *StatefulSet) Restart(ns, n string) error {
|
||||||
|
|
||||||
|
sts, err := s.DialOrDie().AppsV1().StatefulSets(ns).Get(n, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
update, err := polymorphichelpers.ObjectRestarterFn(sts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = s.DialOrDie().AppsV1().StatefulSets(ns).Patch(sts.Name, types.StrategicMergePatchType, update)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,11 @@ type (
|
||||||
Scale(ns string, name string, replicas int32) error
|
Scale(ns string, name string, replicas int32) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restartable represents a rollout restartable Kubernetes resource.
|
||||||
|
Restartable interface {
|
||||||
|
Restart(ns string, name string) error
|
||||||
|
}
|
||||||
|
|
||||||
// Connection represents a Kubenetes apiserver connection.
|
// Connection represents a Kubenetes apiserver connection.
|
||||||
Connection k8s.Connection
|
Connection k8s.Connection
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ import (
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Compile time checks to ensure type satisfies interface
|
||||||
|
var _ Restartable = (*Deployment)(nil)
|
||||||
|
var _ Scalable = (*Deployment)(nil)
|
||||||
|
|
||||||
// Deployment tracks a kubernetes resource.
|
// Deployment tracks a kubernetes resource.
|
||||||
type Deployment struct {
|
type Deployment struct {
|
||||||
*Base
|
*Base
|
||||||
|
|
@ -129,3 +133,8 @@ func (r *Deployment) Fields(ns string) Row {
|
||||||
func (r *Deployment) Scale(ns, n string, replicas int32) error {
|
func (r *Deployment) Scale(ns, n string, replicas int32) error {
|
||||||
return r.Resource.(Scalable).Scale(ns, n, replicas)
|
return r.Resource.(Scalable).Scale(ns, n, replicas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart the rollout of the specified resource.
|
||||||
|
func (r *Deployment) Restart(ns, n string) error {
|
||||||
|
return r.Resource.(Restartable).Restart(ns, n)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ import (
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Compile time checks to ensure type satisfies interface
|
||||||
|
var _ Restartable = (*DaemonSet)(nil)
|
||||||
|
|
||||||
// DaemonSet tracks a kubernetes resource.
|
// DaemonSet tracks a kubernetes resource.
|
||||||
type DaemonSet struct {
|
type DaemonSet struct {
|
||||||
*Base
|
*Base
|
||||||
|
|
@ -112,3 +115,8 @@ func (r *DaemonSet) Fields(ns string) Row {
|
||||||
toAge(i.ObjectMeta.CreationTimestamp),
|
toAge(i.ObjectMeta.CreationTimestamp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart the rollout of the specified resource.
|
||||||
|
func (r *DaemonSet) Restart(ns, n string) error {
|
||||||
|
return r.Resource.(Restartable).Restart(ns, n)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ import (
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Compile time checks to ensure type satisfies interface
|
||||||
|
var _ Restartable = (*StatefulSet)(nil)
|
||||||
|
var _ Scalable = (*StatefulSet)(nil)
|
||||||
|
|
||||||
// StatefulSet tracks a kubernetes resource.
|
// StatefulSet tracks a kubernetes resource.
|
||||||
type StatefulSet struct {
|
type StatefulSet struct {
|
||||||
*Base
|
*Base
|
||||||
|
|
@ -118,3 +122,8 @@ func (r *StatefulSet) Fields(ns string) Row {
|
||||||
func (r *StatefulSet) Scale(ns, n string, replicas int32) error {
|
func (r *StatefulSet) Scale(ns, n string, replicas int32) error {
|
||||||
return r.Resource.(Scalable).Scale(ns, n, replicas)
|
return r.Resource.(Scalable).Scale(ns, n, replicas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restart the rollout of the specified resource.
|
||||||
|
func (r *StatefulSet) Restart(ns, n string) error {
|
||||||
|
return r.Resource.(Restartable).Restart(ns, n)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,18 @@ import (
|
||||||
type deployView struct {
|
type deployView struct {
|
||||||
*logResourceView
|
*logResourceView
|
||||||
scalableResourceView *scalableResourceView
|
scalableResourceView *scalableResourceView
|
||||||
|
restartableResourceView *restartableResourceView
|
||||||
}
|
}
|
||||||
|
|
||||||
const scaleDialogKey = "scale"
|
const scaleDialogKey = "scale"
|
||||||
|
|
||||||
func newDeployView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
func newDeployView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
||||||
logResourceView := newLogResourceView(title, gvr, app, list)
|
logResourceView := newLogResourceView(title, gvr, app, list)
|
||||||
v := deployView{logResourceView, newScalableResourceViewForParent(logResourceView.resourceView)}
|
v := deployView{
|
||||||
|
logResourceView: logResourceView,
|
||||||
|
scalableResourceView: newScalableResourceViewForParent(logResourceView.resourceView),
|
||||||
|
restartableResourceView: newRestartableResourceViewForParent(logResourceView.resourceView),
|
||||||
|
}
|
||||||
v.extraActionsFn = v.extraActions
|
v.extraActionsFn = v.extraActions
|
||||||
v.enterFn = v.showPods
|
v.enterFn = v.showPods
|
||||||
|
|
||||||
|
|
@ -27,6 +32,7 @@ func newDeployView(title, gvr string, app *appView, list resource.List) resource
|
||||||
func (v *deployView) extraActions(aa ui.KeyActions) {
|
func (v *deployView) extraActions(aa ui.KeyActions) {
|
||||||
v.logResourceView.extraActions(aa)
|
v.logResourceView.extraActions(aa)
|
||||||
v.scalableResourceView.extraActions(aa)
|
v.scalableResourceView.extraActions(aa)
|
||||||
|
v.restartableResourceView.extraActions(aa)
|
||||||
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
|
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
|
||||||
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
|
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,15 @@ import (
|
||||||
|
|
||||||
type daemonSetView struct {
|
type daemonSetView struct {
|
||||||
*logResourceView
|
*logResourceView
|
||||||
|
restartableResourceView *restartableResourceView
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDaemonSetView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
func newDaemonSetView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
||||||
v := daemonSetView{newLogResourceView(title, gvr, app, list)}
|
view := newLogResourceView(title, gvr, app, list)
|
||||||
|
v := daemonSetView{
|
||||||
|
logResourceView: view,
|
||||||
|
restartableResourceView: newRestartableResourceViewForParent(view.resourceView),
|
||||||
|
}
|
||||||
v.extraActionsFn = v.extraActions
|
v.extraActionsFn = v.extraActions
|
||||||
v.enterFn = v.showPods
|
v.enterFn = v.showPods
|
||||||
|
|
||||||
|
|
@ -22,6 +27,7 @@ func newDaemonSetView(title, gvr string, app *appView, list resource.List) resou
|
||||||
|
|
||||||
func (v *daemonSetView) extraActions(aa ui.KeyActions) {
|
func (v *daemonSetView) extraActions(aa ui.KeyActions) {
|
||||||
v.logResourceView.extraActions(aa)
|
v.logResourceView.extraActions(aa)
|
||||||
|
v.restartableResourceView.extraActions(aa)
|
||||||
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
|
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
|
||||||
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
|
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
package views
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/derailed/k9s/internal/resource"
|
||||||
|
"github.com/derailed/k9s/internal/ui"
|
||||||
|
"github.com/gdamore/tcell"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
restartableResourceView struct {
|
||||||
|
*resourceView
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newRestartableResourceViewForParent(parent *resourceView) *restartableResourceView {
|
||||||
|
v := restartableResourceView{
|
||||||
|
parent,
|
||||||
|
}
|
||||||
|
parent.extraActionsFn = v.extraActions
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *restartableResourceView) extraActions(aa ui.KeyActions) {
|
||||||
|
aa[tcell.KeyCtrlR] = ui.NewKeyAction("Restart Rollout", v.restartCmd, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *restartableResourceView) restartCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
|
if !v.masterPage().RowSelected() {
|
||||||
|
return evt
|
||||||
|
}
|
||||||
|
|
||||||
|
v.restartRollout(v.masterPage().GetSelectedItem())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *restartableResourceView) restartRollout(selection string) {
|
||||||
|
ns, n := namespaced(selection)
|
||||||
|
|
||||||
|
r, ok := v.list.Resource().(resource.Restartable)
|
||||||
|
if !ok {
|
||||||
|
v.app.Flash().Err(errors.New("resource is not of type resource.Restartable"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.Restart(ns, n)
|
||||||
|
if err != nil {
|
||||||
|
v.app.Flash().Err(err)
|
||||||
|
}
|
||||||
|
v.app.Flash().Info("Restarted Rollout")
|
||||||
|
}
|
||||||
|
|
@ -12,11 +12,12 @@ import (
|
||||||
type statefulSetView struct {
|
type statefulSetView struct {
|
||||||
*logResourceView
|
*logResourceView
|
||||||
scalableResourceView *scalableResourceView
|
scalableResourceView *scalableResourceView
|
||||||
|
restartableResourceView *restartableResourceView
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStatefulSetView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
func newStatefulSetView(title, gvr string, app *appView, list resource.List) resourceViewer {
|
||||||
logResourceView := newLogResourceView(title, gvr, app, list)
|
logResourceView := newLogResourceView(title, gvr, app, list)
|
||||||
v := statefulSetView{logResourceView, newScalableResourceViewForParent(logResourceView.resourceView)}
|
v := statefulSetView{logResourceView: logResourceView, scalableResourceView: newScalableResourceViewForParent(logResourceView.resourceView), restartableResourceView: newRestartableResourceViewForParent(logResourceView.resourceView)}
|
||||||
v.extraActionsFn = v.extraActions
|
v.extraActionsFn = v.extraActions
|
||||||
v.enterFn = v.showPods
|
v.enterFn = v.showPods
|
||||||
|
|
||||||
|
|
@ -26,6 +27,7 @@ func newStatefulSetView(title, gvr string, app *appView, list resource.List) res
|
||||||
func (v *statefulSetView) extraActions(aa ui.KeyActions) {
|
func (v *statefulSetView) extraActions(aa ui.KeyActions) {
|
||||||
v.logResourceView.extraActions(aa)
|
v.logResourceView.extraActions(aa)
|
||||||
v.scalableResourceView.extraActions(aa)
|
v.scalableResourceView.extraActions(aa)
|
||||||
|
v.restartableResourceView.extraActions(aa)
|
||||||
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(1, false), false)
|
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(1, false), false)
|
||||||
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(2, false), false)
|
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(2, false), false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue