Implement confirm-promotion hook

The confirm promotion hooks are executed right before the promotion step. The canary promotion is paused until the hooks return HTTP 200. While the promotion is paused, Flagger will continue to run the metrics checks and load tests.
This commit is contained in:
stefanprodan
2019-09-22 13:23:19 +03:00
parent 2b6966d8e3
commit 8282f86d9c
2 changed files with 36 additions and 0 deletions
+34
View File
@@ -323,6 +323,11 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
return
}
// check promotion gate
if promote := c.runConfirmPromotionHooks(cd); !promote {
return
}
// promote canary - max iterations reached
if cd.Spec.CanaryAnalysis.Iterations == cd.Status.Iterations {
c.recordEventInfof(cd, "Copying %s.%s template spec to %s.%s",
@@ -375,6 +380,11 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
return
}
// check promotion gate
if promote := c.runConfirmPromotionHooks(cd); !promote {
return
}
// route all traffic to canary - max iterations reached
if cd.Spec.CanaryAnalysis.Iterations == cd.Status.Iterations {
if provider != "kubernetes" {
@@ -445,6 +455,13 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
primaryWeight = 100
}
// check promotion gate
if canaryWeight >= maxWeight {
if promote := c.runConfirmPromotionHooks(cd); !promote {
return
}
}
if err := meshRouter.SetRoutes(cd, primaryWeight, canaryWeight); err != nil {
c.recordEventWarningf(cd, "%v", err)
return
@@ -637,6 +654,23 @@ func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1.Canary) bool {
return true
}
func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.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.sendNotification(canary, "Canary promotion is waiting for approval.", false, false)
return false
} else {
c.recordEventInfof(canary, "Confirm-promotion check %s passed", webhook.Name)
}
}
}
return true
}
func (c *Controller) runPreRolloutHooks(canary *flaggerv1.Canary) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
if webhook.Type == flaggerv1.PreRolloutHook {