diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e0b7de1d..1f7ca7097 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -14,8 +14,8 @@ jobs: name: Run go mod download command: go mod download - run: - name: Run go fmt - command: make test-fmt + name: Check code formatting + command: go install golang.org/x/tools/cmd/goimports && make test-fmt - run: name: Build Flagger command: | diff --git a/Makefile b/Makefile index dd9c42fa8..4bbef9de0 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,6 @@ TAG?=latest VERSION?=$(shell grep 'VERSION' pkg/version/version.go | awk '{ print $$4 }' | tr -d '"') VERSION_MINOR:=$(shell grep 'VERSION' pkg/version/version.go | awk '{ print $$4 }' | tr -d '"' | rev | cut -d'.' -f2- | rev) PATCH:=$(shell grep 'VERSION' pkg/version/version.go | awk '{ print $$4 }' | tr -d '"' | awk -F. '{print $$NF}') -SOURCE_DIRS = cmd pkg/apis pkg/controller pkg/server pkg/canary pkg/metrics pkg/router pkg/notifier LT_VERSION?=$(shell grep 'VERSION' cmd/loadtester/main.go | awk '{ print $$4 }' | tr -d '"' | head -n1) TS=$(shell date +%Y-%m-%d_%H-%M-%S) @@ -43,10 +42,12 @@ push: docker push weaveworks/flagger:$(VERSION) fmt: - gofmt -l -s -w $(SOURCE_DIRS) + gofmt -l -s -w ./ + goimports -l -w ./ test-fmt: - gofmt -l -s $(SOURCE_DIRS) | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi + gofmt -l -s ./ | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi + goimports -l ./ | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi test-codegen: ./hack/verify-codegen.sh diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml index 17fcc3f5f..957b3f79e 100644 --- a/artifacts/flagger/crd.yaml +++ b/artifacts/flagger/crd.yaml @@ -42,19 +42,19 @@ spec: priority: 1 - name: Interval type: string - JSONPath: .spec.canaryAnalysis.interval + JSONPath: .spec.analysis.interval priority: 1 - name: Mirror type: boolean - JSONPath: .spec.canaryAnalysis.mirror + JSONPath: .spec.analysis.mirror priority: 1 - name: StepWeight type: string - JSONPath: .spec.canaryAnalysis.stepWeight + JSONPath: .spec.analysis.stepWeight priority: 1 - name: MaxWeight type: string - JSONPath: .spec.canaryAnalysis.maxWeight + JSONPath: .spec.analysis.maxWeight priority: 1 - name: LastTransitionTime type: string @@ -66,7 +66,7 @@ spec: required: - targetRef - service - - canaryAnalysis + - analysis properties: provider: description: Traffic managent provider @@ -502,9 +502,12 @@ spec: skipAnalysis: description: Skip analysis and promote canary type: boolean - canaryAnalysis: + analysis: description: Canary analysis for this canary type: object + oneOf: + - required: ["interval", "threshold", "iterations"] + - required: ["interval", "threshold", "stepWeight"] properties: interval: description: Schedule interval for this canary @@ -523,7 +526,7 @@ spec: description: Incremental traffic percentage step type: number mirror: - description: Mirror traffic to canary before shifting + description: Mirror traffic to canary type: boolean match: description: A/B testing match conditions diff --git a/charts/flagger/crds/crd.yaml b/charts/flagger/crds/crd.yaml index 17fcc3f5f..957b3f79e 100644 --- a/charts/flagger/crds/crd.yaml +++ b/charts/flagger/crds/crd.yaml @@ -42,19 +42,19 @@ spec: priority: 1 - name: Interval type: string - JSONPath: .spec.canaryAnalysis.interval + JSONPath: .spec.analysis.interval priority: 1 - name: Mirror type: boolean - JSONPath: .spec.canaryAnalysis.mirror + JSONPath: .spec.analysis.mirror priority: 1 - name: StepWeight type: string - JSONPath: .spec.canaryAnalysis.stepWeight + JSONPath: .spec.analysis.stepWeight priority: 1 - name: MaxWeight type: string - JSONPath: .spec.canaryAnalysis.maxWeight + JSONPath: .spec.analysis.maxWeight priority: 1 - name: LastTransitionTime type: string @@ -66,7 +66,7 @@ spec: required: - targetRef - service - - canaryAnalysis + - analysis properties: provider: description: Traffic managent provider @@ -502,9 +502,12 @@ spec: skipAnalysis: description: Skip analysis and promote canary type: boolean - canaryAnalysis: + analysis: description: Canary analysis for this canary type: object + oneOf: + - required: ["interval", "threshold", "iterations"] + - required: ["interval", "threshold", "stepWeight"] properties: interval: description: Schedule interval for this canary @@ -523,7 +526,7 @@ spec: description: Incremental traffic percentage step type: number mirror: - description: Mirror traffic to canary before shifting + description: Mirror traffic to canary type: boolean match: description: A/B testing match conditions diff --git a/cmd/loadtester/main.go b/cmd/loadtester/main.go index a7b6a9233..db01eef81 100644 --- a/cmd/loadtester/main.go +++ b/cmd/loadtester/main.go @@ -2,12 +2,13 @@ package main import ( "flag" + "log" + "time" + "github.com/weaveworks/flagger/pkg/loadtester" "github.com/weaveworks/flagger/pkg/logger" "github.com/weaveworks/flagger/pkg/signals" "go.uber.org/zap" - "log" - "time" ) var VERSION = "0.12.1" diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml index 17fcc3f5f..957b3f79e 100644 --- a/kustomize/base/flagger/crd.yaml +++ b/kustomize/base/flagger/crd.yaml @@ -42,19 +42,19 @@ spec: priority: 1 - name: Interval type: string - JSONPath: .spec.canaryAnalysis.interval + JSONPath: .spec.analysis.interval priority: 1 - name: Mirror type: boolean - JSONPath: .spec.canaryAnalysis.mirror + JSONPath: .spec.analysis.mirror priority: 1 - name: StepWeight type: string - JSONPath: .spec.canaryAnalysis.stepWeight + JSONPath: .spec.analysis.stepWeight priority: 1 - name: MaxWeight type: string - JSONPath: .spec.canaryAnalysis.maxWeight + JSONPath: .spec.analysis.maxWeight priority: 1 - name: LastTransitionTime type: string @@ -66,7 +66,7 @@ spec: required: - targetRef - service - - canaryAnalysis + - analysis properties: provider: description: Traffic managent provider @@ -502,9 +502,12 @@ spec: skipAnalysis: description: Skip analysis and promote canary type: boolean - canaryAnalysis: + analysis: description: Canary analysis for this canary type: object + oneOf: + - required: ["interval", "threshold", "iterations"] + - required: ["interval", "threshold", "stepWeight"] properties: interval: description: Schedule interval for this canary @@ -523,7 +526,7 @@ spec: description: Incremental traffic percentage step type: number mirror: - description: Mirror traffic to canary before shifting + description: Mirror traffic to canary type: boolean match: description: A/B testing match conditions diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index f370f55e5..f13bd9087 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -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 +} diff --git a/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go index c825b121d..86fb45e78 100644 --- a/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/flagger/v1beta1/zz_generated.deepcopy.go @@ -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) diff --git a/pkg/canary/daemonset_controller.go b/pkg/canary/daemonset_controller.go index 1c07c7fcf..0041247ba 100644 --- a/pkg/canary/daemonset_controller.go +++ b/pkg/canary/daemonset_controller.go @@ -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 diff --git a/pkg/canary/deployment_controller.go b/pkg/canary/deployment_controller.go index e27dbc636..96b6b77f8 100644 --- a/pkg/canary/deployment_controller.go +++ b/pkg/canary/deployment_controller.go @@ -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 diff --git a/pkg/canary/deployment_fixture_test.go b/pkg/canary/deployment_fixture_test.go index 62e2a2b9f..486b34722 100644 --- a/pkg/canary/deployment_fixture_test.go +++ b/pkg/canary/deployment_fixture_test.go @@ -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, diff --git a/pkg/controller/events.go b/pkg/controller/events.go index 00fe49a13..fb29915a6 100644 --- a/pkg/controller/events.go +++ b/pkg/controller/events.go @@ -2,6 +2,7 @@ package controller import ( "fmt" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" corev1 "k8s.io/api/core/v1" @@ -30,8 +31,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 +52,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 +62,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 +73,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 +162,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 +170,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", diff --git a/pkg/controller/scheduler.go b/pkg/controller/scheduler.go index f930f0e1f..6d393b064 100644 --- a/pkg/controller/scheduler.go +++ b/pkg/controller/scheduler.go @@ -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), diff --git a/pkg/controller/scheduler_common_test.go b/pkg/controller/scheduler_common_test.go index 512a0f4ce..01f06865f 100644 --- a/pkg/controller/scheduler_common_test.go +++ b/pkg/controller/scheduler_common_test.go @@ -1,5 +1,26 @@ package controller +import ( + "fmt" + + flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1" + clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func assertPhase(flaggerClient clientset.Interface, canary string, phase flaggerv1.CanaryPhase) error { + c, err := flaggerClient.FlaggerV1beta1().Canaries("default").Get(canary, metav1.GetOptions{}) + if err != nil { + return err + } + + if c.Status.Phase != phase { + return fmt.Errorf("Got canary state %v wanted %v", c.Status.Phase, phase) + } + + return nil +} + func alwaysReady() bool { return true } diff --git a/pkg/controller/scheduler_daemonset_fixture_test.go b/pkg/controller/scheduler_daemonset_fixture_test.go index 8e0b24786..8d2cdd6d1 100644 --- a/pkg/controller/scheduler_daemonset_fixture_test.go +++ b/pkg/controller/scheduler_daemonset_fixture_test.go @@ -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{ diff --git a/pkg/controller/scheduler_deployment_fixture_test.go b/pkg/controller/scheduler_deployment_fixture_test.go index a3f2db509..74a7321ef 100644 --- a/pkg/controller/scheduler_deployment_fixture_test.go +++ b/pkg/controller/scheduler_deployment_fixture_test.go @@ -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{ diff --git a/pkg/controller/scheduler_deployment_test.go b/pkg/controller/scheduler_deployment_test.go index da72f3758..b1171942d 100644 --- a/pkg/controller/scheduler_deployment_test.go +++ b/pkg/controller/scheduler_deployment_test.go @@ -144,6 +144,116 @@ func TestScheduler_DeploymentSkipAnalysis(t *testing.T) { } } +func TestScheduler_DeploymentAnalysisPhases(t *testing.T) { + cd := newDeploymentTestCanary() + cd.Spec.Analysis = &flaggerv1.CanaryAnalysis{ + Interval: "1m", + StepWeight: 100, + } + mocks := newDeploymentFixture(cd) + + // init + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseInitialized); err != nil { + t.Fatal(err.Error()) + } + + // update + dep2 := newDeploymentTestDeploymentV2() + _, err := mocks.kubeClient.AppsV1().Deployments("default").Update(dep2) + if err != nil { + t.Fatal(err.Error()) + } + + // detect changes + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseProgressing); err != nil { + t.Fatal(err.Error()) + } + + // progressing + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseProgressing); err != nil { + t.Fatal(err.Error()) + } + + // promoting + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhasePromoting); err != nil { + t.Fatal(err.Error()) + } + + // finalising + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseFinalising); err != nil { + t.Fatal(err.Error()) + } + + // succeeded + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseSucceeded); err != nil { + t.Fatal(err.Error()) + } +} + +func TestScheduler_DeploymentBlueGreenAnalysisPhases(t *testing.T) { + cd := newDeploymentTestCanary() + cd.Spec.Analysis = &flaggerv1.CanaryAnalysis{ + Interval: "1m", + Iterations: 1, + } + mocks := newDeploymentFixture(cd) + + // init + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseInitialized); err != nil { + t.Fatal(err.Error()) + } + + // update + dep2 := newDeploymentTestDeploymentV2() + _, err := mocks.kubeClient.AppsV1().Deployments("default").Update(dep2) + if err != nil { + t.Fatal(err.Error()) + } + + // detect changes (progressing) + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseProgressing); err != nil { + t.Fatal(err.Error()) + } + + // advance (progressing) + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseProgressing); err != nil { + t.Fatal(err.Error()) + } + + // route traffic to primary (progressing) + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseProgressing); err != nil { + t.Fatal(err.Error()) + } + + // promoting + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhasePromoting); err != nil { + t.Fatal(err.Error()) + } + + // finalising + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseFinalising); err != nil { + t.Fatal(err.Error()) + } + + // succeeded + mocks.ctrl.advanceCanary("podinfo", "default", true) + if err := assertPhase(mocks.flaggerClient, "podinfo", flaggerv1.CanaryPhaseSucceeded); err != nil { + t.Fatal(err.Error()) + } +} + func TestScheduler_DeploymentNewRevisionReset(t *testing.T) { mocks := newDeploymentFixture(nil) // init diff --git a/pkg/controller/scheduler_svc_test.go b/pkg/controller/scheduler_svc_test.go index 5e11d9fcd..0db42439e 100644 --- a/pkg/controller/scheduler_svc_test.go +++ b/pkg/controller/scheduler_svc_test.go @@ -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, diff --git a/pkg/controller/webhook.go b/pkg/controller/webhook.go index ed5316c7a..c07bd6572 100644 --- a/pkg/controller/webhook.go +++ b/pkg/controller/webhook.go @@ -7,12 +7,13 @@ import ( "errors" "fmt" "io/ioutil" - "k8s.io/utils/clock" "net/http" "net/url" "strconv" "time" + "k8s.io/utils/clock" + flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1" ) diff --git a/pkg/loadtester/runner.go b/pkg/loadtester/runner.go index 2cba9050d..0a9ea90a4 100644 --- a/pkg/loadtester/runner.go +++ b/pkg/loadtester/runner.go @@ -2,10 +2,11 @@ package loadtester import ( "context" - "go.uber.org/zap" "sync" "sync/atomic" "time" + + "go.uber.org/zap" ) type TaskRunner struct { diff --git a/pkg/loadtester/runner_test.go b/pkg/loadtester/runner_test.go index 1c7ab9c7f..1ab724876 100644 --- a/pkg/loadtester/runner_test.go +++ b/pkg/loadtester/runner_test.go @@ -1,9 +1,10 @@ package loadtester import ( - "github.com/weaveworks/flagger/pkg/logger" "testing" "time" + + "github.com/weaveworks/flagger/pkg/logger" ) func TestTaskRunner_Start(t *testing.T) { diff --git a/pkg/loadtester/server.go b/pkg/loadtester/server.go index a8817a4b9..f6dc79dab 100644 --- a/pkg/loadtester/server.go +++ b/pkg/loadtester/server.go @@ -179,7 +179,6 @@ func ListenAndServe(port string, timeout time.Duration, logger *zap.SugaredLogge return } - canaryName := fmt.Sprintf("rollback.%s.%s", canary.Name, canary.Namespace) gate.close(canaryName) diff --git a/pkg/loadtester/task.go b/pkg/loadtester/task.go index 395b34a9b..1ad8056a0 100644 --- a/pkg/loadtester/task.go +++ b/pkg/loadtester/task.go @@ -3,9 +3,10 @@ package loadtester import ( "context" "encoding/hex" - "go.uber.org/zap" "hash/fnv" "sync" + + "go.uber.org/zap" ) // Modeling a loadtester task diff --git a/pkg/loadtester/task_ngrinder.go b/pkg/loadtester/task_ngrinder.go index 4a4dca15e..9d7e8b86f 100644 --- a/pkg/loadtester/task_ngrinder.go +++ b/pkg/loadtester/task_ngrinder.go @@ -6,12 +6,13 @@ import ( "encoding/json" "errors" "fmt" - "go.uber.org/zap" "io/ioutil" "net/http" "net/url" "strconv" "time" + + "go.uber.org/zap" ) const TaskTypeNGrinder = "ngrinder" diff --git a/pkg/loadtester/task_ngrinder_test.go b/pkg/loadtester/task_ngrinder_test.go index 699aea72d..b79177638 100644 --- a/pkg/loadtester/task_ngrinder_test.go +++ b/pkg/loadtester/task_ngrinder_test.go @@ -3,10 +3,11 @@ package loadtester import ( "context" "fmt" - "github.com/weaveworks/flagger/pkg/logger" - "gopkg.in/h2non/gock.v1" "testing" "time" + + "github.com/weaveworks/flagger/pkg/logger" + "gopkg.in/h2non/gock.v1" ) func TestTaskNGrinder(t *testing.T) { diff --git a/pkg/loadtester/task_shell.go b/pkg/loadtester/task_shell.go index 4f79b5056..c8fcf4961 100644 --- a/pkg/loadtester/task_shell.go +++ b/pkg/loadtester/task_shell.go @@ -4,9 +4,10 @@ import ( "context" "errors" "fmt" - "go.uber.org/zap" "os/exec" "strconv" + + "go.uber.org/zap" ) const TaskTypeShell = "cmd" diff --git a/pkg/metrics/observers/observer.go b/pkg/metrics/observers/observer.go index a2e906587..496f2dd4a 100644 --- a/pkg/metrics/observers/observer.go +++ b/pkg/metrics/observers/observer.go @@ -1,8 +1,9 @@ package observers import ( - flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1" "time" + + flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1" ) type Interface interface { diff --git a/pkg/router/appmesh.go b/pkg/router/appmesh.go index 1d13fff8f..2f0964177 100644 --- a/pkg/router/appmesh.go +++ b/pkg/router/appmesh.go @@ -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, diff --git a/pkg/router/contour.go b/pkg/router/contour.go index 50bbee2a2..8ad846ab1 100644 --- a/pkg/router/contour.go +++ b/pkg/router/contour.go @@ -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, diff --git a/pkg/router/ingress.go b/pkg/router/ingress.go index 22e8b9b86..e97d68c41 100644 --- a/pkg/router/ingress.go +++ b/pkg/router/ingress.go @@ -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 diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 015698cfe..df8093131 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -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, diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index 9e4ad3ef3..205a8ab3e 100644 --- a/pkg/router/router_test.go +++ b/pkg/router/router_test.go @@ -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, diff --git a/test/e2e-contour-tests.sh b/test/e2e-contour-tests.sh index a27eb398c..70d183726 100755 --- a/test/e2e-contour-tests.sh +++ b/test/e2e-contour-tests.sh @@ -34,7 +34,7 @@ spec: EOF cat <>> Installing Istio ${ISTIO_VER}" diff --git a/test/e2e-kubernetes-tests-daemonset.sh b/test/e2e-kubernetes-tests-daemonset.sh index 2b35c3bcc..443f4dfbb 100755 --- a/test/e2e-kubernetes-tests-daemonset.sh +++ b/test/e2e-kubernetes-tests-daemonset.sh @@ -18,7 +18,7 @@ echo '>>> Initialising canary' kubectl apply -f ${REPO_ROOT}/test/e2e-daemonset.yaml cat <>> Initialising canary' kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml cat <>> Installing NGINX Ingress' kubectl create ns ingress-nginx diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh index 599a86898..a19ef5ed9 100755 --- a/test/e2e-tests.sh +++ b/test/e2e-tests.sh @@ -19,7 +19,7 @@ echo '>>> Initialising canary' kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml cat <