Skip to content

Commit

Permalink
feat: Show scale down time for bluegreen replicasets (argoproj#370)
Browse files Browse the repository at this point in the history
Display time remaining until BlueGreen replicaset scale down deadline
  • Loading branch information
cronik committed Jan 24, 2020
1 parent 34732b2 commit 89a9154
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 26 deletions.
4 changes: 4 additions & 0 deletions pkg/kubectl-argo-rollouts/cmd/get/get_rollout.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ func (o *GetOptions) PrintReplicaSetInfo(w io.Writer, rsInfo info.ReplicaSetInfo
infoCols = append(infoCols, o.colorize(info.InfoTagPreview))
name = o.colorizeStatus(name, info.InfoTagPreview)
}
if rsInfo.ScaleDownDeadline != "" {
infoCols = append(infoCols, fmt.Sprintf("delay:%s", rsInfo.ScaleDownDelay()))
}

fmt.Fprintf(w, "%s%s %s\t%s\t%s %s\t%s\t%v\n", prefix, IconReplicaSet, name, "ReplicaSet", o.colorize(rsInfo.Icon), rsInfo.Status, rsInfo.Age(), strings.Join(infoCols, ","))
for i, podInfo := range rsInfo.Pods {
isLast := i == len(rsInfo.Pods)-1
Expand Down
51 changes: 51 additions & 0 deletions pkg/kubectl-argo-rollouts/cmd/get/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"fmt"
"strings"
"testing"
"time"

"github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/stretchr/testify/assert"
"k8s.io/cli-runtime/pkg/genericclioptions"
Expand Down Expand Up @@ -136,6 +140,53 @@ NAME KIND STATUS AGE INFO
assertStdout(t, expectedOut, o.IOStreams)
}

func TestGetBlueGreenRolloutScaleDownDelay(t *testing.T) {
rolloutObjs := testdata.NewBlueGreenRollout()
inFourHours := metav1.Now().Add(4 * time.Hour).Truncate(time.Second).UTC().Format(time.RFC3339)
rolloutObjs.ReplicaSets[2].Annotations[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey] = inFourHours
delete(rolloutObjs.ReplicaSets[2].Labels, v1alpha1.DefaultRolloutUniqueLabelKey)

tf, o := options.NewFakeArgoRolloutsOptions(rolloutObjs.AllObjects()...)
o.RESTClientGetter = tf.WithNamespace(rolloutObjs.Rollouts[0].Namespace)
defer tf.Cleanup()
cmd := NewCmdGetRollout(o)
cmd.PersistentPreRunE = o.PersistentPreRunE
cmd.SetArgs([]string{rolloutObjs.Rollouts[0].Name, "--no-color"})
err := cmd.Execute()
assert.NoError(t, err)

expectedOut := strings.TrimPrefix(`
Name: bluegreen-demo
Namespace: jesse-test
Status: ॥ Paused
Strategy: BlueGreen
Images: argoproj/rollouts-demo:blue (active)
argoproj/rollouts-demo:green
Replicas:
Desired: 3
Current: 6
Updated: 3
Ready: 6
Available: 3
NAME KIND STATUS AGE INFO
⟳ bluegreen-demo Rollout ॥ Paused 7d
├──# revision:11
│ └──⧉ bluegreen-demo-74b948fccb ReplicaSet ✔ Healthy 7d delay:3h59m
│ ├──□ bluegreen-demo-74b948fccb-5jz59 Pod ✔ Running 7d ready:1/1
│ ├──□ bluegreen-demo-74b948fccb-mkhrl Pod ✔ Running 7d ready:1/1
│ └──□ bluegreen-demo-74b948fccb-vvj2t Pod ✔ Running 7d ready:1/1
├──# revision:10
│ └──⧉ bluegreen-demo-6cbccd9f99 ReplicaSet ✔ Healthy 7d active
│ ├──□ bluegreen-demo-6cbccd9f99-gk78v Pod ✔ Running 7d ready:1/1
│ ├──□ bluegreen-demo-6cbccd9f99-kxj8g Pod ✔ Running 7d ready:1/1
│ └──□ bluegreen-demo-6cbccd9f99-t2d4f Pod ✔ Running 7d ready:1/1
└──# revision:8
└──⧉ bluegreen-demo-746d5fddf6 ReplicaSet • ScaledDown 7d
`, "\n")
assertStdout(t, expectedOut, o.IOStreams)
}

func TestGetCanaryRollout(t *testing.T) {
rolloutObjs := testdata.NewCanaryRollout()

Expand Down
7 changes: 7 additions & 0 deletions pkg/kubectl-argo-rollouts/info/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,10 @@ func parseExperimentTemplateName(annots map[string]string) string {
}
return ""
}

func parseScaleDownDeadline(annots map[string]string) string {
if annots != nil {
return annots[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey]
}
return ""
}
48 changes: 34 additions & 14 deletions pkg/kubectl-argo-rollouts/info/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,41 @@ func TestCanaryRolloutInfo(t *testing.T) {
}

func TestBlueGreenRolloutInfo(t *testing.T) {
rolloutObjs := testdata.NewBlueGreenRollout()
roInfo := NewRolloutInfo(rolloutObjs.Rollouts[0], rolloutObjs.ReplicaSets, rolloutObjs.Pods, rolloutObjs.Experiments, rolloutObjs.AnalysisRuns)
assert.Equal(t, roInfo.Name, rolloutObjs.Rollouts[0].Name)
assert.Len(t, roInfo.Revisions(), 3)
{
rolloutObjs := testdata.NewBlueGreenRollout()
roInfo := NewRolloutInfo(rolloutObjs.Rollouts[0], rolloutObjs.ReplicaSets, rolloutObjs.Pods, rolloutObjs.Experiments, rolloutObjs.AnalysisRuns)
assert.Equal(t, roInfo.Name, rolloutObjs.Rollouts[0].Name)
assert.Len(t, roInfo.Revisions(), 3)

assert.Equal(t, roInfo.Images(), []ImageInfo{
{
Image: "argoproj/rollouts-demo:blue",
Tags: []string{InfoTagActive},
},
{
Image: "argoproj/rollouts-demo:green",
Tags: []string{InfoTagPreview},
},
})
assert.Len(t, roInfo.ReplicaSetsByRevision(11), 1)
assert.Len(t, roInfo.ReplicaSetsByRevision(10), 1)
assert.Len(t, roInfo.ReplicaSetsByRevision(8), 1)

assert.Equal(t, roInfo.ReplicaSets[0].ScaleDownDeadline, "")
assert.Equal(t, roInfo.ReplicaSets[0].ScaleDownDelay(), "")

assert.Equal(t, roInfo.Images(), []ImageInfo{
{
Image: "argoproj/rollouts-demo:blue",
Tags: []string{InfoTagActive},
},
{
Image: "argoproj/rollouts-demo:green",
Tags: []string{InfoTagPreview},
},
})
}
{
rolloutObjs := testdata.NewBlueGreenRollout()
inFourHours := metav1.Now().Add(4 * time.Hour).Truncate(time.Second).UTC().Format(time.RFC3339)
rolloutObjs.ReplicaSets[0].Annotations[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey] = inFourHours
delayedRs := rolloutObjs.ReplicaSets[0].ObjectMeta.UID
roInfo := NewRolloutInfo(rolloutObjs.Rollouts[0], rolloutObjs.ReplicaSets, rolloutObjs.Pods, rolloutObjs.Experiments, rolloutObjs.AnalysisRuns)

assert.Equal(t, roInfo.ReplicaSets[1].UID, delayedRs)
assert.Equal(t, roInfo.ReplicaSets[1].ScaleDownDeadline, inFourHours)
assert.Equal(t, roInfo.ReplicaSets[1].ScaleDownDelay(), "3h59m")
}
}

func TestExperimentAnalysisRolloutInfo(t *testing.T) {
Expand Down
37 changes: 25 additions & 12 deletions pkg/kubectl-argo-rollouts/info/replicaset_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,33 @@ package info

import (
"sort"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/duration"

"github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1"
)

type ReplicaSetInfo struct {
Metadata
Status string
Icon string
Revision int
Stable bool
Canary bool
Active bool
Preview bool
Replicas int32
Available int32
Template string
Images []string
Pods []PodInfo
Status string
Icon string
Revision int
Stable bool
Canary bool
Active bool
Preview bool
Replicas int32
Available int32
Template string
ScaleDownDeadline string
Images []string
Pods []PodInfo
}

func getReplicaSetInfo(ownerUID types.UID, ro *v1alpha1.Rollout, allReplicaSets []*appsv1.ReplicaSet, allPods []*corev1.Pod) []ReplicaSetInfo {
Expand All @@ -47,6 +52,7 @@ func getReplicaSetInfo(ownerUID types.UID, ro *v1alpha1.Rollout, allReplicaSets
rsInfo.Icon = replicaSetIcon(rsInfo.Status)
rsInfo.Revision = parseRevision(rs.ObjectMeta.Annotations)
rsInfo.Template = parseExperimentTemplateName(rs.ObjectMeta.Annotations)
rsInfo.ScaleDownDeadline = parseScaleDownDeadline(rs.ObjectMeta.Annotations)

if ro != nil {
if ro.Spec.Strategy.Canary != nil && rs.Labels != nil {
Expand Down Expand Up @@ -122,3 +128,10 @@ func getReplicaSetCondition(status appsv1.ReplicaSetStatus, condType appsv1.Repl
}
return nil
}

func (rs ReplicaSetInfo) ScaleDownDelay() string {
if deadline, err := time.Parse(time.RFC3339, rs.ScaleDownDeadline); err == nil {
return duration.HumanDuration(deadline.Sub(metav1.Now().Time))
}
return ""
}

0 comments on commit 89a9154

Please sign in to comment.