Skip to content

Commit

Permalink
Merge pull request #859 from jblackburn21/waiting-promotion-phase
Browse files Browse the repository at this point in the history
feat: added WaitingPromotion phase
  • Loading branch information
stefanprodan authored Mar 23, 2021
2 parents c8a1165 + f0bf521 commit ef2df0d
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 10 deletions.
1 change: 1 addition & 0 deletions artifacts/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ spec:
- Initialized
- Waiting
- Progressing
- WaitingPromotion
- Promoting
- Finalising
- Succeeded
Expand Down
1 change: 1 addition & 0 deletions charts/flagger/crds/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ spec:
- Initialized
- Waiting
- Progressing
- WaitingPromotion
- Promoting
- Finalising
- Succeeded
Expand Down
2 changes: 1 addition & 1 deletion docs/gitbook/usage/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ status:
```

The `Promoted` status condition can have one of the following reasons:
Initialized, Waiting, Progressing, Promoting, Finalising, Succeeded or Failed.
Initialized, Waiting, Progressing, WaitingPromotion, Promoting, Finalising, Succeeded or Failed.
A failed canary will have the promoted status set to `false`,
the reason to `failed` and the last applied spec will be different to the last promoted one.

Expand Down
1 change: 1 addition & 0 deletions kustomize/base/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,7 @@ spec:
- Initialized
- Waiting
- Progressing
- WaitingPromotion
- Promoting
- Finalising
- Succeeded
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/flagger/v1beta1/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const (
CanaryPhaseWaiting CanaryPhase = "Waiting"
// CanaryPhaseProgressing means the canary analysis is underway
CanaryPhaseProgressing CanaryPhase = "Progressing"
// CanaryWaitingPromotion means the canary promotion is paused (waiting for confirmation to proceed)
CanaryWaitingPromotion CanaryPhase = "WaitingPromotion"
// CanaryPhasePromoting means the canary analysis is finished and the primary spec has been updated
CanaryPhasePromoting CanaryPhase = "Promoting"
// CanaryPhaseFinalising means the canary promotion is finished and traffic has been routed back to primary
Expand Down
3 changes: 3 additions & 0 deletions pkg/canary/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ func MakeStatusConditions(cd *flaggerv1.Canary,
case flaggerv1.CanaryPhaseWaiting:
status = corev1.ConditionUnknown
message = "Waiting for approval."
case flaggerv1.CanaryWaitingPromotion:
status = corev1.ConditionUnknown
message = "Waiting for approval."
case flaggerv1.CanaryPhaseProgressing:
status = corev1.ConditionUnknown
message = "New revision detected, progressing canary analysis."
Expand Down
14 changes: 9 additions & 5 deletions pkg/controller/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ func (c *Controller) advanceCanary(name string, namespace string) {

// check if we should rollback
if cd.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
cd.Status.Phase == flaggerv1.CanaryPhaseWaiting {
cd.Status.Phase == flaggerv1.CanaryPhaseWaiting ||
cd.Status.Phase == flaggerv1.CanaryWaitingPromotion {
if ok := c.runRollbackHooks(cd, cd.Status.Phase); ok {
c.recordEventWarningf(cd, "Rolling back %s.%s manual webhook invoked", cd.Name, cd.Namespace)
c.alert(cd, "Rolling back manual webhook invoked", false, flaggerv1.SeverityWarn)
Expand Down Expand Up @@ -534,7 +535,7 @@ func (c *Controller) runCanary(canary *flaggerv1.Canary, canaryController canary
// promote canary - max weight reached
if canaryWeight >= maxWeight {
// check promotion gate
if promote := c.runConfirmPromotionHooks(canary); !promote {
if promote := c.runConfirmPromotionHooks(canary, canaryController); !promote {
return
}

Expand Down Expand Up @@ -576,7 +577,7 @@ func (c *Controller) runAB(canary *flaggerv1.Canary, canaryController canary.Con
}

// check promotion gate
if promote := c.runConfirmPromotionHooks(canary); !promote {
if promote := c.runConfirmPromotionHooks(canary, canaryController); !promote {
return
}

Expand Down Expand Up @@ -622,7 +623,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
}

// check promotion gate
if promote := c.runConfirmPromotionHooks(canary); !promote {
if promote := c.runConfirmPromotionHooks(canary, canaryController); !promote {
return
}

Expand Down Expand Up @@ -751,6 +752,7 @@ func (c *Controller) shouldAdvance(canary *flaggerv1.Canary, canaryController ca
canary.Status.Phase == flaggerv1.CanaryPhaseInitializing ||
canary.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
canary.Status.Phase == flaggerv1.CanaryPhaseWaiting ||
canary.Status.Phase == flaggerv1.CanaryWaitingPromotion ||
canary.Status.Phase == flaggerv1.CanaryPhasePromoting ||
canary.Status.Phase == flaggerv1.CanaryPhaseFinalising {
return true, nil
Expand All @@ -776,6 +778,7 @@ func (c *Controller) shouldAdvance(canary *flaggerv1.Canary, canaryController ca
func (c *Controller) checkCanaryStatus(canary *flaggerv1.Canary, canaryController canary.Controller, shouldAdvance bool) bool {
c.recorder.SetStatus(canary, canary.Status.Phase)
if canary.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
canary.Status.Phase == flaggerv1.CanaryWaitingPromotion ||
canary.Status.Phase == flaggerv1.CanaryPhasePromoting ||
canary.Status.Phase == flaggerv1.CanaryPhaseFinalising {
return true
Expand Down Expand Up @@ -822,7 +825,8 @@ func (c *Controller) checkCanaryStatus(canary *flaggerv1.Canary, canaryControlle
}

func (c *Controller) hasCanaryRevisionChanged(canary *flaggerv1.Canary, canaryController canary.Controller) bool {
if canary.Status.Phase == flaggerv1.CanaryPhaseProgressing {
if canary.Status.Phase == flaggerv1.CanaryPhaseProgressing ||
canary.Status.Phase == flaggerv1.CanaryWaitingPromotion {
if diff, _ := canaryController.HasTargetChanged(canary); diff {
return true
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/controller/scheduler_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,19 @@ func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1.Canary, canaryCont
return true
}

func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary) bool {
func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary, canaryController canary.Controller) bool {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.ConfirmPromotionHook {
err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
if err != nil {
c.recordEventWarningf(canary, "Halt %s.%s advancement waiting for promotion approval %s",
canary.Name, canary.Namespace, webhook.Name)
c.alert(canary, "Canary promotion is waiting for approval.", false, flaggerv1.SeverityWarn)
if canary.Status.Phase != flaggerv1.CanaryWaitingPromotion {
if err := canaryController.SetStatusPhase(canary, flaggerv1.CanaryWaitingPromotion); err != nil {
c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).Errorf("%v", err)
}
c.recordEventWarningf(canary, "Halt %s.%s advancement waiting for promotion approval %s",
canary.Name, canary.Namespace, webhook.Name)
c.alert(canary, "Canary promotion is waiting for approval.", false, flaggerv1.SeverityWarn)
}
return false
} else {
c.recordEventInfof(canary, "Confirm-promotion check %s passed", webhook.Name)
Expand Down

0 comments on commit ef2df0d

Please sign in to comment.