feat: Add action to restart rollout of dp, ds, sts

mine
Michael Cristina 2019-10-08 17:00:51 -05:00
parent ee1b734464
commit b246ca0752
11 changed files with 156 additions and 5 deletions

View File

@ -2,6 +2,8 @@ package k8s
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubectl/pkg/polymorphichelpers"
)
// 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)
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
}

View File

@ -2,6 +2,8 @@ package k8s
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubectl/pkg/polymorphichelpers"
)
// DaemonSet represents a Kubernetes DaemonSet
@ -48,3 +50,19 @@ func (d *DaemonSet) Delete(ns, n string, cascade, force bool) error {
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
}

View File

@ -2,6 +2,8 @@ package k8s
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubectl/pkg/polymorphichelpers"
)
// 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)
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
}

View File

@ -35,6 +35,11 @@ type (
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 k8s.Connection

View File

@ -10,6 +10,10 @@ import (
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.
type Deployment struct {
*Base
@ -129,3 +133,8 @@ func (r *Deployment) Fields(ns string) Row {
func (r *Deployment) Scale(ns, n string, replicas int32) error {
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)
}

View File

@ -10,6 +10,9 @@ import (
appsv1 "k8s.io/api/apps/v1"
)
// Compile time checks to ensure type satisfies interface
var _ Restartable = (*DaemonSet)(nil)
// DaemonSet tracks a kubernetes resource.
type DaemonSet struct {
*Base
@ -112,3 +115,8 @@ func (r *DaemonSet) Fields(ns string) Row {
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)
}

View File

@ -10,6 +10,10 @@ import (
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.
type StatefulSet struct {
*Base
@ -118,3 +122,8 @@ func (r *StatefulSet) Fields(ns string) Row {
func (r *StatefulSet) Scale(ns, n string, replicas int32) error {
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)
}

View File

@ -10,14 +10,19 @@ import (
type deployView struct {
*logResourceView
scalableResourceView *scalableResourceView
scalableResourceView *scalableResourceView
restartableResourceView *restartableResourceView
}
const scaleDialogKey = "scale"
func newDeployView(title, gvr string, app *appView, list resource.List) resourceViewer {
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.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) {
v.logResourceView.extraActions(aa)
v.scalableResourceView.extraActions(aa)
v.restartableResourceView.extraActions(aa)
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
}

View File

@ -10,10 +10,15 @@ import (
type daemonSetView struct {
*logResourceView
restartableResourceView *restartableResourceView
}
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.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) {
v.logResourceView.extraActions(aa)
v.restartableResourceView.extraActions(aa)
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(2, false), false)
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(3, false), false)
}

View File

@ -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")
}

View File

@ -11,12 +11,13 @@ import (
type statefulSetView struct {
*logResourceView
scalableResourceView *scalableResourceView
scalableResourceView *scalableResourceView
restartableResourceView *restartableResourceView
}
func newStatefulSetView(title, gvr string, app *appView, list resource.List) resourceViewer {
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.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) {
v.logResourceView.extraActions(aa)
v.scalableResourceView.extraActions(aa)
v.restartableResourceView.extraActions(aa)
aa[ui.KeyShiftD] = ui.NewKeyAction("Sort Desired", v.sortColCmd(1, false), false)
aa[ui.KeyShiftC] = ui.NewKeyAction("Sort Current", v.sortColCmd(2, false), false)
}