Skip to content

Commit ebd6cbd

Browse files
authored
fix: promote nil pointer error when there are no steps (argoproj#1510)
Signed-off-by: Leonardo Luz Almeida <[email protected]>
1 parent ea1b8ea commit ebd6cbd

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

pkg/kubectl-argo-rollouts/cmd/promote/promote.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,14 @@ func getPatches(rollout *v1alpha1.Rollout, skipCurrentStep, skipAllStep, full bo
138138
_, index := replicasetutil.GetCurrentCanaryStep(rollout)
139139
// At this point, the controller knows that the rollout is a canary with steps and GetCurrentCanaryStep returns 0 if
140140
// the index is not set in the rollout
141-
if *index < int32(len(rollout.Spec.Strategy.Canary.Steps)) {
142-
*index++
141+
if index != nil {
142+
if *index < int32(len(rollout.Spec.Strategy.Canary.Steps)) {
143+
*index++
144+
}
145+
statusPatch = []byte(fmt.Sprintf(setCurrentStepIndex, *index))
146+
unifiedPatch = statusPatch
143147
}
144-
statusPatch = []byte(fmt.Sprintf(setCurrentStepIndex, *index))
145-
unifiedPatch = statusPatch
148+
146149
case skipAllStep:
147150
statusPatch = []byte(fmt.Sprintf(setCurrentStepIndex, len(rollout.Spec.Strategy.Canary.Steps)))
148151
unifiedPatch = statusPatch
@@ -165,11 +168,13 @@ func getPatches(rollout *v1alpha1.Rollout, skipCurrentStep, skipAllStep, full bo
165168
_, index := replicasetutil.GetCurrentCanaryStep(rollout)
166169
// At this point, the controller knows that the rollout is a canary with steps and GetCurrentCanaryStep returns 0 if
167170
// the index is not set in the rollout
168-
if *index < int32(len(rollout.Spec.Strategy.Canary.Steps)) {
169-
*index++
171+
if index != nil {
172+
if *index < int32(len(rollout.Spec.Strategy.Canary.Steps)) {
173+
*index++
174+
}
175+
statusPatch = []byte(fmt.Sprintf(clearPauseConditionsPatchWithStep, *index))
176+
unifiedPatch = []byte(fmt.Sprintf(unpauseAndClearPauseConditionsPatchWithStep, *index))
170177
}
171-
statusPatch = []byte(fmt.Sprintf(clearPauseConditionsPatchWithStep, *index))
172-
unifiedPatch = []byte(fmt.Sprintf(unpauseAndClearPauseConditionsPatchWithStep, *index))
173178
}
174179
}
175180
return specPatch, statusPatch, unifiedPatch

pkg/kubectl-argo-rollouts/cmd/promote/promote_test.go

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,31 @@ func TestPromoteSkipFlagOnNoStepCanaryError(t *testing.T) {
9494
assert.Contains(t, stderr, skipFlagWithNoStepCanaryError)
9595
}
9696

97+
func TestPromoteNoStepCanary(t *testing.T) {
98+
ro := v1alpha1.Rollout{
99+
ObjectMeta: metav1.ObjectMeta{
100+
Name: "guestbook",
101+
Namespace: metav1.NamespaceDefault,
102+
},
103+
Spec: v1alpha1.RolloutSpec{
104+
Strategy: v1alpha1.RolloutStrategy{
105+
Canary: &v1alpha1.CanaryStrategy{},
106+
},
107+
},
108+
}
109+
tf, o := options.NewFakeArgoRolloutsOptions(&ro)
110+
defer tf.Cleanup()
111+
cmd := NewCmdPromote(o)
112+
cmd.PersistentPreRunE = o.PersistentPreRunE
113+
cmd.SetArgs([]string{"guestbook"})
114+
err := cmd.Execute()
115+
assert.NoError(t, err)
116+
stdout := o.Out.(*bytes.Buffer).String()
117+
assert.NotEmpty(t, stdout)
118+
stderr := o.ErrOut.(*bytes.Buffer).String()
119+
assert.Empty(t, stderr)
120+
}
121+
97122
func TestPromoteCmdSuccesSkipAllSteps(t *testing.T) {
98123
ro := v1alpha1.Rollout{
99124
ObjectMeta: metav1.ObjectMeta{
@@ -144,7 +169,7 @@ func TestPromoteCmdSuccesSkipAllSteps(t *testing.T) {
144169
assert.Empty(t, stderr)
145170
}
146171

147-
func TestPromoteCmdSuccesFirstStep(t *testing.T) {
172+
func TestPromoteCmdSuccesFirstStepWithSkipFirstStep(t *testing.T) {
148173
ro := v1alpha1.Rollout{
149174
ObjectMeta: metav1.ObjectMeta{
150175
Name: "guestbook",
@@ -194,6 +219,56 @@ func TestPromoteCmdSuccesFirstStep(t *testing.T) {
194219
assert.Empty(t, stderr)
195220
}
196221

222+
func TestPromoteCmdSuccesFirstStep(t *testing.T) {
223+
ro := v1alpha1.Rollout{
224+
ObjectMeta: metav1.ObjectMeta{
225+
Name: "guestbook",
226+
Namespace: metav1.NamespaceDefault,
227+
},
228+
Spec: v1alpha1.RolloutSpec{
229+
Strategy: v1alpha1.RolloutStrategy{
230+
Canary: &v1alpha1.CanaryStrategy{
231+
Steps: []v1alpha1.CanaryStep{
232+
{
233+
SetWeight: pointer.Int32Ptr(1),
234+
},
235+
{
236+
SetWeight: pointer.Int32Ptr(2),
237+
},
238+
},
239+
},
240+
},
241+
},
242+
}
243+
244+
tf, o := options.NewFakeArgoRolloutsOptions(&ro)
245+
defer tf.Cleanup()
246+
fakeClient := o.RolloutsClient.(*fakeroclient.Clientset)
247+
fakeClient.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) {
248+
if patchAction, ok := action.(kubetesting.PatchAction); ok {
249+
patchRo := v1alpha1.Rollout{}
250+
err := json.Unmarshal(patchAction.GetPatch(), &patchRo)
251+
if err != nil {
252+
panic(err)
253+
}
254+
ro.Status.CurrentStepIndex = patchRo.Status.CurrentStepIndex
255+
}
256+
return true, &ro, nil
257+
})
258+
259+
cmd := NewCmdPromote(o)
260+
cmd.PersistentPreRunE = o.PersistentPreRunE
261+
cmd.SetArgs([]string{"guestbook"})
262+
263+
err := cmd.Execute()
264+
assert.Nil(t, err)
265+
assert.Equal(t, int32(1), *ro.Status.CurrentStepIndex)
266+
stdout := o.Out.(*bytes.Buffer).String()
267+
stderr := o.ErrOut.(*bytes.Buffer).String()
268+
assert.Equal(t, stdout, "rollout 'guestbook' promoted\n")
269+
assert.Empty(t, stderr)
270+
}
271+
197272
func TestPromoteCmdSuccessDoNotGoPastLastStep(t *testing.T) {
198273
ro := v1alpha1.Rollout{
199274
ObjectMeta: metav1.ObjectMeta{

0 commit comments

Comments
 (0)