Deprecate spec.canaryAnalysis replaced by spec.analysis

- add analysis field to Canary spec
- deprecate canaryAnalysis filed (to be removed in the next API version)
- maintain backwards compatibility with v1alpha3 by using spec.canaryAnalysis if spec.analysis is nil
- set analysis threshold default value to 1
This commit is contained in:
stefanprodan
2020-02-28 11:24:38 +02:00
parent 41f644ab8c
commit 287977c2b5
15 changed files with 117 additions and 79 deletions
+33 -4
View File
@@ -80,8 +80,11 @@ type CanarySpec struct {
// Service defines how ClusterIP services, service mesh or ingress routing objects are generated
Service CanaryService `json:"service"`
// CanaryAnalysis defines how the analysis should be performed
CanaryAnalysis CanaryAnalysis `json:"canaryAnalysis"`
// Analysis defines the validation process of a release
Analysis *CanaryAnalysis `json:"analysis,omitempty"`
// Deprecated: replaced by Analysis
CanaryAnalysis *CanaryAnalysis `json:"canaryAnalysis,omitempty"`
// ProgressDeadlineSeconds represents the maximum time in seconds for a
// canary deployment to make progress before it is considered to be failed
@@ -352,13 +355,22 @@ func (c *Canary) GetProgressDeadlineSeconds() int {
return ProgressDeadlineSeconds
}
// GetAnalysis returns the analysis v1beta1 or v1alpha3
// to be removed along with spec.canaryAnalysis in v1
func (c *Canary) GetAnalysis() *CanaryAnalysis {
if c.Spec.Analysis != nil {
return c.Spec.Analysis
}
return c.Spec.CanaryAnalysis
}
// GetAnalysisInterval returns the canary analysis interval (default 60s)
func (c *Canary) GetAnalysisInterval() time.Duration {
if c.Spec.CanaryAnalysis.Interval == "" {
if c.GetAnalysis().Interval == "" {
return AnalysisInterval
}
interval, err := time.ParseDuration(c.Spec.CanaryAnalysis.Interval)
interval, err := time.ParseDuration(c.GetAnalysis().Interval)
if err != nil {
return AnalysisInterval
}
@@ -370,7 +382,24 @@ func (c *Canary) GetAnalysisInterval() time.Duration {
return interval
}
// GetAnalysisThreshold returns the canary threshold (default 1)
func (c *Canary) GetAnalysisThreshold() int {
if c.GetAnalysis().Threshold > 0 {
return c.GetAnalysis().Threshold
}
return 1
}
// GetMetricInterval returns the metric interval default value (1m)
func (c *Canary) GetMetricInterval() string {
return MetricInterval
}
// SkipAnalysis returns true if the analysis is nil
// or if spec.SkipAnalysis is true
func (c *Canary) SkipAnalysis() bool {
if c.Spec.Analysis == nil && c.Spec.CanaryAnalysis == nil {
return true
}
return c.Spec.SkipAnalysis
}
@@ -392,7 +392,16 @@ func (in *CanarySpec) DeepCopyInto(out *CanarySpec) {
**out = **in
}
in.Service.DeepCopyInto(&out.Service)
in.CanaryAnalysis.DeepCopyInto(&out.CanaryAnalysis)
if in.Analysis != nil {
in, out := &in.Analysis, &out.Analysis
*out = new(CanaryAnalysis)
(*in).DeepCopyInto(*out)
}
if in.CanaryAnalysis != nil {
in, out := &in.CanaryAnalysis, &out.CanaryAnalysis
*out = new(CanaryAnalysis)
(*in).DeepCopyInto(*out)
}
if in.ProgressDeadlineSeconds != nil {
in, out := &in.ProgressDeadlineSeconds, &out.ProgressDeadlineSeconds
*out = new(int32)
+1 -1
View File
@@ -91,7 +91,7 @@ func (c *DaemonSetController) Initialize(cd *flaggerv1.Canary, skipLivenessCheck
}
if cd.Status.Phase == "" || cd.Status.Phase == flaggerv1.CanaryPhaseInitializing {
if !skipLivenessChecks && !cd.Spec.SkipAnalysis {
if !skipLivenessChecks && !cd.SkipAnalysis() {
_, readyErr := c.IsPrimaryReady(cd)
if readyErr != nil {
return readyErr
+1 -1
View File
@@ -37,7 +37,7 @@ func (c *DeploymentController) Initialize(cd *flaggerv1.Canary, skipLivenessChec
}
if cd.Status.Phase == "" || cd.Status.Phase == flaggerv1.CanaryPhaseInitializing {
if !skipLivenessChecks && !cd.Spec.SkipAnalysis {
if !skipLivenessChecks && !cd.SkipAnalysis() {
_, readyErr := c.IsPrimaryReady(cd)
if readyErr != nil {
return readyErr
+1 -1
View File
@@ -207,7 +207,7 @@ func newDeploymentControllerTestCanary() *flaggerv1.Canary {
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
+11 -11
View File
@@ -30,8 +30,8 @@ func (c *Controller) recordEventWarningf(r *flaggerv1.Canary, template string, a
func (c *Controller) sendEventToWebhook(r *flaggerv1.Canary, eventType, template string, args []interface{}) {
webhookOverride := false
if len(r.Spec.CanaryAnalysis.Webhooks) > 0 {
for _, canaryWebhook := range r.Spec.CanaryAnalysis.Webhooks {
if len(r.GetAnalysis().Webhooks) > 0 {
for _, canaryWebhook := range r.GetAnalysis().Webhooks {
if canaryWebhook.Type == flaggerv1.EventHook {
webhookOverride = true
err := CallEventWebhook(r, canaryWebhook.URL, fmt.Sprintf(template, args...), eventType)
@@ -51,7 +51,7 @@ func (c *Controller) sendEventToWebhook(r *flaggerv1.Canary, eventType, template
}
func (c *Controller) alert(canary *flaggerv1.Canary, message string, metadata bool, severity flaggerv1.AlertSeverity) {
if c.notifier == nil && len(canary.Spec.CanaryAnalysis.Alerts) == 0 {
if c.notifier == nil && len(canary.GetAnalysis().Alerts) == 0 {
return
}
@@ -61,7 +61,7 @@ func (c *Controller) alert(canary *flaggerv1.Canary, message string, metadata bo
}
// send alert with the global notifier
if len(canary.Spec.CanaryAnalysis.Alerts) == 0 {
if len(canary.GetAnalysis().Alerts) == 0 {
err := c.notifier.Post(canary.Name, canary.Namespace, message, fields, string(severity))
if err != nil {
c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
@@ -72,7 +72,7 @@ func (c *Controller) alert(canary *flaggerv1.Canary, message string, metadata bo
}
// send canary alerts
for _, alert := range canary.Spec.CanaryAnalysis.Alerts {
for _, alert := range canary.GetAnalysis().Alerts {
// determine if alert should be sent based on severity level
shouldAlert := false
if alert.Severity == flaggerv1.SeverityInfo {
@@ -161,7 +161,7 @@ func alertMetadata(canary *flaggerv1.Canary) []notifier.Field {
},
notifier.Field{
Name: "Failed checks threshold",
Value: fmt.Sprintf("%v", canary.Spec.CanaryAnalysis.Threshold),
Value: fmt.Sprintf("%v", canary.GetAnalysisThreshold()),
},
notifier.Field{
Name: "Progress deadline",
@@ -169,19 +169,19 @@ func alertMetadata(canary *flaggerv1.Canary) []notifier.Field {
},
)
if canary.Spec.CanaryAnalysis.StepWeight > 0 {
if canary.GetAnalysis().StepWeight > 0 {
fields = append(fields, notifier.Field{
Name: "Traffic routing",
Value: fmt.Sprintf("Weight step: %v max: %v",
canary.Spec.CanaryAnalysis.StepWeight,
canary.Spec.CanaryAnalysis.MaxWeight),
canary.GetAnalysis().StepWeight,
canary.GetAnalysis().MaxWeight),
})
} else if len(canary.Spec.CanaryAnalysis.Match) > 0 {
} else if len(canary.GetAnalysis().Match) > 0 {
fields = append(fields, notifier.Field{
Name: "Traffic routing",
Value: "A/B Testing",
})
} else if canary.Spec.CanaryAnalysis.Iterations > 0 {
} else if canary.GetAnalysis().Iterations > 0 {
fields = append(fields, notifier.Field{
Name: "Traffic routing",
Value: "Blue/Green",
+36 -36
View File
@@ -157,12 +157,12 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
// set max weight default value to 100%
maxWeight := 100
if cd.Spec.CanaryAnalysis.MaxWeight > 0 {
maxWeight = cd.Spec.CanaryAnalysis.MaxWeight
if cd.GetAnalysis().MaxWeight > 0 {
maxWeight = cd.GetAnalysis().MaxWeight
}
// check primary status
if !skipLivenessChecks && !cd.Spec.SkipAnalysis {
if !skipLivenessChecks && !cd.SkipAnalysis() {
if _, err := canaryController.IsPrimaryReady(cd); err != nil {
c.recordEventWarningf(cd, "%v", err)
return
@@ -278,7 +278,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
// check if the number of failed checks reached the threshold
if cd.Status.Phase == flaggerv1.CanaryPhaseProgressing &&
(!retriable || cd.Status.FailedChecks >= cd.Spec.CanaryAnalysis.Threshold) {
(!retriable || cd.Status.FailedChecks >= cd.GetAnalysisThreshold()) {
if !retriable {
c.recordEventWarningf(cd, "Rolling back %s.%s progress deadline exceeded %v",
cd.Name, cd.Namespace, err)
@@ -297,7 +297,7 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
// check if the canary success rate is above the threshold
// skip check if no traffic is routed or mirrored to canary
if canaryWeight == 0 && cd.Status.Iterations == 0 &&
(cd.Spec.CanaryAnalysis.Mirror == false || mirrored == false) {
(cd.GetAnalysis().Mirror == false || mirrored == false) {
c.recordEventInfof(cd, "Starting canary analysis for %s.%s", cd.Spec.TargetRef.Name, cd.Namespace)
// run pre-rollout web hooks
@@ -320,31 +320,31 @@ func (c *Controller) advanceCanary(name string, namespace string, skipLivenessCh
// use blue/green strategy for kubernetes provider
if provider == "kubernetes" {
if len(cd.Spec.CanaryAnalysis.Match) > 0 {
if len(cd.GetAnalysis().Match) > 0 {
c.recordEventWarningf(cd, "A/B testing is not supported when using the kubernetes provider")
cd.Spec.CanaryAnalysis.Match = nil
cd.GetAnalysis().Match = nil
}
if cd.Spec.CanaryAnalysis.Iterations < 1 {
if cd.GetAnalysis().Iterations < 1 {
c.recordEventWarningf(cd, "Progressive traffic is not supported when using the kubernetes provider")
c.recordEventWarningf(cd, "Setting canaryAnalysis.iterations: 10")
cd.Spec.CanaryAnalysis.Iterations = 10
cd.GetAnalysis().Iterations = 10
}
}
// strategy: A/B testing
if len(cd.Spec.CanaryAnalysis.Match) > 0 && cd.Spec.CanaryAnalysis.Iterations > 0 {
if len(cd.GetAnalysis().Match) > 0 && cd.GetAnalysis().Iterations > 0 {
c.runAB(cd, canaryController, meshRouter, provider)
return
}
// strategy: Blue/Green
if cd.Spec.CanaryAnalysis.Iterations > 0 {
if cd.GetAnalysis().Iterations > 0 {
c.runBlueGreen(cd, canaryController, meshRouter, provider, mirrored)
return
}
// strategy: Canary progressive traffic increase
if cd.Spec.CanaryAnalysis.StepWeight > 0 {
if cd.GetAnalysis().StepWeight > 0 {
c.runCanary(cd, canaryController, meshRouter, provider, mirrored, canaryWeight, primaryWeight, maxWeight)
}
@@ -358,25 +358,25 @@ func (c *Controller) runCanary(canary *flaggerv1.Canary, canaryController canary
// If in "mirror" mode, do one step of mirroring before shifting traffic to canary.
// When mirroring, all requests go to primary and canary, but only responses from
// primary go back to the user.
if canary.Spec.CanaryAnalysis.Mirror && canaryWeight == 0 {
if canary.GetAnalysis().Mirror && canaryWeight == 0 {
if mirrored == false {
mirrored = true
primaryWeight = 100
canaryWeight = 0
} else {
mirrored = false
primaryWeight = 100 - canary.Spec.CanaryAnalysis.StepWeight
canaryWeight = canary.Spec.CanaryAnalysis.StepWeight
primaryWeight = 100 - canary.GetAnalysis().StepWeight
canaryWeight = canary.GetAnalysis().StepWeight
}
c.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
Infof("Running mirror step %d/%d/%t", primaryWeight, canaryWeight, mirrored)
} else {
primaryWeight -= canary.Spec.CanaryAnalysis.StepWeight
primaryWeight -= canary.GetAnalysis().StepWeight
if primaryWeight < 0 {
primaryWeight = 0
}
canaryWeight += canary.Spec.CanaryAnalysis.StepWeight
canaryWeight += canary.GetAnalysis().StepWeight
if canaryWeight > 100 {
canaryWeight = 100
}
@@ -424,7 +424,7 @@ func (c *Controller) runAB(canary *flaggerv1.Canary, canaryController canary.Con
primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name)
// route traffic to canary and increment iterations
if canary.Spec.CanaryAnalysis.Iterations > canary.Status.Iterations {
if canary.GetAnalysis().Iterations > canary.Status.Iterations {
if err := meshRouter.SetRoutes(canary, 0, 100, false); err != nil {
c.recordEventWarningf(canary, "%v", err)
return
@@ -436,7 +436,7 @@ func (c *Controller) runAB(canary *flaggerv1.Canary, canaryController canary.Con
return
}
c.recordEventInfof(canary, "Advance %s.%s canary iteration %v/%v",
canary.Name, canary.Namespace, canary.Status.Iterations+1, canary.Spec.CanaryAnalysis.Iterations)
canary.Name, canary.Namespace, canary.Status.Iterations+1, canary.GetAnalysis().Iterations)
return
}
@@ -446,7 +446,7 @@ func (c *Controller) runAB(canary *flaggerv1.Canary, canaryController canary.Con
}
// promote canary - max iterations reached
if canary.Spec.CanaryAnalysis.Iterations == canary.Status.Iterations {
if canary.GetAnalysis().Iterations == canary.Status.Iterations {
c.recordEventInfof(canary, "Copying %s.%s template spec to %s.%s",
canary.Spec.TargetRef.Name, canary.Namespace, primaryName, canary.Namespace)
if err := canaryController.Promote(canary); err != nil {
@@ -466,10 +466,10 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
primaryName := fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name)
// increment iterations
if canary.Spec.CanaryAnalysis.Iterations > canary.Status.Iterations {
if canary.GetAnalysis().Iterations > canary.Status.Iterations {
// If in "mirror" mode, mirror requests during the entire B/G canary test
if provider != "kubernetes" &&
canary.Spec.CanaryAnalysis.Mirror == true && mirrored == false {
canary.GetAnalysis().Mirror == true && mirrored == false {
if err := meshRouter.SetRoutes(canary, 100, 0, true); err != nil {
c.recordEventWarningf(canary, "%v", err)
}
@@ -481,7 +481,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
return
}
c.recordEventInfof(canary, "Advance %s.%s canary iteration %v/%v",
canary.Name, canary.Namespace, canary.Status.Iterations+1, canary.Spec.CanaryAnalysis.Iterations)
canary.Name, canary.Namespace, canary.Status.Iterations+1, canary.GetAnalysis().Iterations)
return
}
@@ -491,9 +491,9 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
}
// route all traffic to canary - max iterations reached
if canary.Spec.CanaryAnalysis.Iterations == canary.Status.Iterations {
if canary.GetAnalysis().Iterations == canary.Status.Iterations {
if provider != "kubernetes" {
if canary.Spec.CanaryAnalysis.Mirror {
if canary.GetAnalysis().Mirror {
c.recordEventInfof(canary, "Stop traffic mirroring and route all traffic to canary")
} else {
c.recordEventInfof(canary, "Routing all traffic to canary")
@@ -514,7 +514,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
}
// promote canary - max iterations reached
if canary.Spec.CanaryAnalysis.Iterations < canary.Status.Iterations {
if canary.GetAnalysis().Iterations < canary.Status.Iterations {
c.recordEventInfof(canary, "Copying %s.%s template spec to %s.%s",
canary.Spec.TargetRef.Name, canary.Namespace, primaryName, canary.Namespace)
if err := canaryController.Promote(canary); err != nil {
@@ -532,7 +532,7 @@ func (c *Controller) runBlueGreen(canary *flaggerv1.Canary, canaryController can
}
func (c *Controller) shouldSkipAnalysis(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface, primaryWeight int, canaryWeight int) bool {
if !canary.Spec.SkipAnalysis {
if !canary.SkipAnalysis() {
return false
}
@@ -656,7 +656,7 @@ func (c *Controller) hasCanaryRevisionChanged(canary *flaggerv1.Canary, canaryCo
}
func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1.Canary, canaryController canary.Controller) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.ConfirmRolloutHook {
err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
if err != nil {
@@ -685,7 +685,7 @@ func (c *Controller) runConfirmRolloutHooks(canary *flaggerv1.Canary, canaryCont
}
func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.ConfirmPromotionHook {
err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
if err != nil {
@@ -702,7 +702,7 @@ func (c *Controller) runConfirmPromotionHooks(canary *flaggerv1.Canary) bool {
}
func (c *Controller) runPreRolloutHooks(canary *flaggerv1.Canary) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.PreRolloutHook {
err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
if err != nil {
@@ -718,7 +718,7 @@ func (c *Controller) runPreRolloutHooks(canary *flaggerv1.Canary) bool {
}
func (c *Controller) runPostRolloutHooks(canary *flaggerv1.Canary, phase flaggerv1.CanaryPhase) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.PostRolloutHook {
err := CallWebhook(canary.Name, canary.Namespace, phase, webhook)
if err != nil {
@@ -733,7 +733,7 @@ func (c *Controller) runPostRolloutHooks(canary *flaggerv1.Canary, phase flagger
}
func (c *Controller) runRollbackHooks(canary *flaggerv1.Canary, phase flaggerv1.CanaryPhase) bool {
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == flaggerv1.RollbackHook {
err := CallWebhook(canary.Name, canary.Namespace, phase, webhook)
if err != nil {
@@ -749,7 +749,7 @@ func (c *Controller) runRollbackHooks(canary *flaggerv1.Canary, phase flaggerv1.
func (c *Controller) runAnalysis(canary *flaggerv1.Canary) bool {
// run external checks
for _, webhook := range canary.Spec.CanaryAnalysis.Webhooks {
for _, webhook := range canary.GetAnalysis().Webhooks {
if webhook.Type == "" || webhook.Type == flaggerv1.RolloutHook {
err := CallWebhook(canary.Name, canary.Namespace, flaggerv1.CanaryPhaseProgressing, webhook)
if err != nil {
@@ -812,7 +812,7 @@ func (c *Controller) runBuiltinMetricChecks(canary *flaggerv1.Canary) bool {
observer := observerFactory.Observer(metricsProvider)
// run metrics checks
for _, metric := range canary.Spec.CanaryAnalysis.Metrics {
for _, metric := range canary.GetAnalysis().Metrics {
if metric.Interval == "" {
metric.Interval = canary.GetMetricInterval()
}
@@ -914,7 +914,7 @@ func (c *Controller) runBuiltinMetricChecks(canary *flaggerv1.Canary) bool {
}
func (c *Controller) runMetricChecks(canary *flaggerv1.Canary) bool {
for _, metric := range canary.Spec.CanaryAnalysis.Metrics {
for _, metric := range canary.GetAnalysis().Metrics {
if metric.TemplateRef != nil {
namespace := canary.Namespace
if metric.TemplateRef.Namespace != "" {
@@ -1007,7 +1007,7 @@ func toMetricModel(r *flaggerv1.Canary, interval string) flaggerv1.MetricTemplat
}
func (c *Controller) rollback(canary *flaggerv1.Canary, canaryController canary.Controller, meshRouter router.Interface) {
if canary.Status.FailedChecks >= canary.Spec.CanaryAnalysis.Threshold {
if canary.Status.FailedChecks >= canary.GetAnalysisThreshold() {
c.recordEventWarningf(canary, "Rolling back %s.%s failed checks threshold reached %v",
canary.Name, canary.Namespace, canary.Status.FailedChecks)
c.alert(canary, fmt.Sprintf("Failed checks threshold reached %v", canary.Status.FailedChecks),
@@ -250,7 +250,7 @@ func newDaemonSetTestCanary() *flaggerv1.Canary {
Kind: "DaemonSet",
}, Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
@@ -307,7 +307,7 @@ func newDaemonSetTestCanaryAB() *flaggerv1.Canary {
Kind: "DaemonSet",
}, Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
Iterations: 10,
Match: []istiov1alpha3.HTTPMatchRequest{
@@ -257,7 +257,7 @@ func newDeploymentTestCanary() *flaggerv1.Canary {
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
@@ -319,7 +319,7 @@ func newDeploymentTestCanaryAB() *flaggerv1.Canary {
Kind: "HorizontalPodAutoscaler",
}, Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
Iterations: 10,
Match: []istiov1alpha3.HTTPMatchRequest{
+1 -1
View File
@@ -142,7 +142,7 @@ func newTestServiceCanary() *flaggerv1.Canary {
Service: flaggerv1.CanaryService{
Port: 9898,
},
CanaryAnalysis: flaggerv1.CanaryAnalysis{
CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
+2 -2
View File
@@ -203,7 +203,7 @@ func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name
}
// A/B testing - header based routing
if len(canary.Spec.CanaryAnalysis.Match) > 0 && canaryWeight == 0 {
if len(canary.GetAnalysis().Match) > 0 && canaryWeight == 0 {
routes = []appmeshv1.Route{
{
Name: fmt.Sprintf("%s-a", apexName),
@@ -451,7 +451,7 @@ func makeRetryPolicy(canary *flaggerv1.Canary) *appmeshv1.HttpRetryPolicy {
func (ar *AppMeshRouter) makeHeaders(canary *flaggerv1.Canary) []appmeshv1.HttpRouteHeader {
headers := []appmeshv1.HttpRouteHeader{}
for _, m := range canary.Spec.CanaryAnalysis.Match {
for _, m := range canary.GetAnalysis().Match {
for key, value := range m.Headers {
header := appmeshv1.HttpRouteHeader{
Name: key,
+4 -4
View File
@@ -64,7 +64,7 @@ func (cr *ContourRouter) Reconcile(canary *flaggerv1.Canary) error {
},
}
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
if len(canary.GetAnalysis().Match) > 0 {
newSpec = contourv1.HTTPProxySpec{
Routes: []contourv1.Route{
{
@@ -277,7 +277,7 @@ func (cr *ContourRouter) SetRoutes(
},
}
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
if len(canary.GetAnalysis().Match) > 0 {
proxy.Spec = contourv1.HTTPProxySpec{
Routes: []contourv1.Route{
{
@@ -364,8 +364,8 @@ func (cr *ContourRouter) makePrefix(canary *flaggerv1.Canary) string {
func (cr *ContourRouter) makeConditions(canary *flaggerv1.Canary) []contourv1.Condition {
list := []contourv1.Condition{}
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
for _, match := range canary.Spec.CanaryAnalysis.Match {
if len(canary.GetAnalysis().Match) > 0 {
for _, match := range canary.GetAnalysis().Match {
for s, stringMatch := range match.Headers {
h := &contourv1.HeaderCondition{
Name: s,
+3 -3
View File
@@ -117,7 +117,7 @@ func (i *IngressRouter) GetRoutes(canary *flaggerv1.Canary) (
}
// A/B testing
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
if len(canary.GetAnalysis().Match) > 0 {
for k := range canaryIngress.Annotations {
if k == i.GetAnnotationWithPrefix("canary-by-cookie") || k == i.GetAnnotationWithPrefix("canary-by-header") {
return 0, 100, false, nil
@@ -158,11 +158,11 @@ func (i *IngressRouter) SetRoutes(
iClone := canaryIngress.DeepCopy()
// A/B testing
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
if len(canary.GetAnalysis().Match) > 0 {
cookie := ""
header := ""
headerValue := ""
for _, m := range canary.Spec.CanaryAnalysis.Match {
for _, m := range canary.GetAnalysis().Match {
for k, v := range m.Headers {
if k == "cookie" {
cookie = v.Exact
+4 -4
View File
@@ -152,8 +152,8 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error {
},
}
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
canaryMatch := mergeMatchConditions(canary.Spec.CanaryAnalysis.Match, canary.Spec.Service.Match)
if len(canary.GetAnalysis().Match) > 0 {
canaryMatch := mergeMatchConditions(canary.GetAnalysis().Match, canary.Spec.Service.Match)
newSpec.Http = []istiov1alpha3.HTTPRoute{
{
Match: canaryMatch,
@@ -323,9 +323,9 @@ func (ir *IstioRouter) SetRoutes(
}
// fix routing (A/B testing)
if len(canary.Spec.CanaryAnalysis.Match) > 0 {
if len(canary.GetAnalysis().Match) > 0 {
// merge the common routes with the canary ones
canaryMatch := mergeMatchConditions(canary.Spec.CanaryAnalysis.Match, canary.Spec.Service.Match)
canaryMatch := mergeMatchConditions(canary.GetAnalysis().Match, canary.Spec.Service.Match)
vsCopy.Spec.Http = []istiov1alpha3.HTTPRoute{
{
Match: canaryMatch,
+6 -6
View File
@@ -112,7 +112,7 @@ func newTestCanary() *flaggerv1.Canary {
"public-gateway.istio",
"mesh",
},
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
@@ -158,7 +158,7 @@ func newTestCanaryAppMesh() *flaggerv1.Canary {
PerTryTimeout: "gateway-error",
RetryOn: "5s",
},
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
@@ -203,7 +203,7 @@ func newTestSMICanary() *flaggerv1.Canary {
},
PortDiscovery: true,
},
CanaryAnalysis: flaggerv1.CanaryAnalysis{
CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,
@@ -227,7 +227,7 @@ func newTestSMICanary() *flaggerv1.Canary {
func newTestMirror() *flaggerv1.Canary {
cd := newTestCanary()
cd.Spec.CanaryAnalysis.Mirror = true
cd.GetAnalysis().Mirror = true
return cd
}
@@ -247,7 +247,7 @@ func newTestABTest() *flaggerv1.Canary {
Service: flaggerv1.CanaryService{
Port: 9898,
MeshName: "global",
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
Iterations: 2,
Match: []istiov1alpha3.HTTPMatchRequest{
@@ -397,7 +397,7 @@ func newTestCanaryIngress() *flaggerv1.Canary {
},
Service: flaggerv1.CanaryService{
Port: 9898,
}, CanaryAnalysis: flaggerv1.CanaryAnalysis{
}, CanaryAnalysis: &flaggerv1.CanaryAnalysis{
Threshold: 10,
StepWeight: 10,
MaxWeight: 50,