From cb130d3239a1d04acc9aba026760d4c4d5028285 Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 09:43:23 +0900 Subject: [PATCH 1/9] add api changes for making mirrorPercentage configurable --- artifacts/flagger/crd.yaml | 3 +++ charts/flagger/crds/crd.yaml | 3 +++ kustomize/base/flagger/crd.yaml | 3 +++ pkg/apis/flagger/v1beta1/canary.go | 6 +++++- pkg/apis/istio/v1alpha3/virtual_service.go | 10 +++++++++ .../istio/v1alpha3/zz_generated.deepcopy.go | 21 +++++++++++++++++++ 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml index 0c37ebc3..c46128f6 100644 --- a/artifacts/flagger/crd.yaml +++ b/artifacts/flagger/crd.yaml @@ -528,6 +528,9 @@ spec: mirror: description: Mirror traffic to canary type: boolean + mirrorWeight: + description: Weight of traffic to be mirrored when + type: number match: description: A/B testing match conditions type: array diff --git a/charts/flagger/crds/crd.yaml b/charts/flagger/crds/crd.yaml index 0c37ebc3..c46128f6 100644 --- a/charts/flagger/crds/crd.yaml +++ b/charts/flagger/crds/crd.yaml @@ -528,6 +528,9 @@ spec: mirror: description: Mirror traffic to canary type: boolean + mirrorWeight: + description: Weight of traffic to be mirrored when + type: number match: description: A/B testing match conditions type: array diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml index 0c37ebc3..c46128f6 100644 --- a/kustomize/base/flagger/crd.yaml +++ b/kustomize/base/flagger/crd.yaml @@ -528,6 +528,9 @@ spec: mirror: description: Mirror traffic to canary type: boolean + mirrorWeight: + description: Weight of traffic to be mirrored when + type: number match: description: A/B testing match conditions type: array diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index f13bd908..51e81c9b 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -175,10 +175,14 @@ type CanaryAnalysis struct { // +optional Iterations int `json:"iterations,omitempty"` - //Enable traffic mirroring for Blue/Green + // Enable traffic mirroring for Blue/Green // +optional Mirror bool `json:"mirror,omitempty"` + // Percentage of the traffic to be mirrored when mirroring is enabled + // +optional + MirrorWeight float64 `json:"mirror_weight,omitempty"` + // Max traffic percentage routed to canary // +optional MaxWeight int `json:"maxWeight,omitempty"` diff --git a/pkg/apis/istio/v1alpha3/virtual_service.go b/pkg/apis/istio/v1alpha3/virtual_service.go index d800142b..84ca29e2 100644 --- a/pkg/apis/istio/v1alpha3/virtual_service.go +++ b/pkg/apis/istio/v1alpha3/virtual_service.go @@ -325,6 +325,11 @@ type HTTPRoute struct { // destination. Mirror *Destination `json:"mirror,omitempty"` + // Percentage of the traffic to be mirrored by the `mirror` field. + // If this field is absent, all the traffic (100%) will be mirrored. + // Max value is 100. + MirrorPercentage *Percent `json:"mirror_percentage"` + // Cross-Origin Resource Sharing policy (CORS). Refer to // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS // for further details about cross origin resource sharing. @@ -334,6 +339,11 @@ type HTTPRoute struct { Headers *Headers `json:"headers,omitempty"` } +// Percent specifies a percentage in the range of [0.0, 100.0]. +type Percent struct { + Value float64 `json:"value,omitempty"` +} + // Header manipulation rules type Headers struct { // Header manipulation rules to apply before forwarding a request diff --git a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go index 9447a78e..a187f416 100644 --- a/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go +++ b/pkg/apis/istio/v1alpha3/zz_generated.deepcopy.go @@ -421,6 +421,11 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { *out = new(Destination) (*in).DeepCopyInto(*out) } + if in.MirrorPercentage != nil { + in, out := &in.MirrorPercentage, &out.MirrorPercentage + *out = new(Percent) + **out = **in + } if in.CorsPolicy != nil { in, out := &in.CorsPolicy, &out.CorsPolicy *out = new(CorsPolicy) @@ -628,6 +633,22 @@ func (in *OutlierDetection) DeepCopy() *OutlierDetection { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Percent) DeepCopyInto(out *Percent) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Percent. +func (in *Percent) DeepCopy() *Percent { + if in == nil { + return nil + } + out := new(Percent) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PortSelector) DeepCopyInto(out *PortSelector) { *out = *in From 8242e7691ab51a227f474fe240acd4c08934a77d Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 09:53:53 +0900 Subject: [PATCH 2/9] pkg/router/istio: set mirrorWeight if provided --- pkg/apis/flagger/v1beta1/canary.go | 2 +- pkg/router/istio.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index 51e81c9b..f0d3e905 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -179,7 +179,7 @@ type CanaryAnalysis struct { // +optional Mirror bool `json:"mirror,omitempty"` - // Percentage of the traffic to be mirrored when mirroring is enabled + // Percentage of the traffic to be mirrored in the range of [0.0, 100.0]. // +optional MirrorWeight float64 `json:"mirror_weight,omitempty"` diff --git a/pkg/router/istio.go b/pkg/router/istio.go index c6d43b92..a1c9ddd4 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -304,6 +304,10 @@ func (ir *IstioRouter) SetRoutes( vsCopy.Spec.Http[0].Mirror = &istiov1alpha3.Destination{ Host: canaryName, } + + if mw := canary.Spec.Analysis.MirrorWeight; mw > 0 { + vsCopy.Spec.Http[0].MirrorPercentage = &istiov1alpha3.Percent{Value: mw} + } } // fix routing (A/B testing) From 1f6160148ce33ee9f00cc07f91b3719a1996cbc6 Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 11:25:57 +0900 Subject: [PATCH 3/9] change CanaryAnalysis to Analysis left in tests --- artifacts/flagger/crd.yaml | 2 +- charts/flagger/crds/crd.yaml | 2 +- kustomize/base/flagger/crd.yaml | 2 +- pkg/canary/deployment_fixture_test.go | 2 +- pkg/controller/scheduler_daemonset_fixture_test.go | 6 +++--- pkg/controller/scheduler_daemonset_test.go | 4 ++-- pkg/controller/scheduler_deployment_fixture_test.go | 6 +++--- pkg/controller/scheduler_deployment_test.go | 4 ++-- pkg/controller/scheduler_svc_test.go | 2 +- pkg/router/contour_test.go | 8 ++++---- pkg/router/router_test.go | 10 +++++----- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/artifacts/flagger/crd.yaml b/artifacts/flagger/crd.yaml index c46128f6..3ae25fa8 100644 --- a/artifacts/flagger/crd.yaml +++ b/artifacts/flagger/crd.yaml @@ -529,7 +529,7 @@ spec: description: Mirror traffic to canary type: boolean mirrorWeight: - description: Weight of traffic to be mirrored when + description: Percentage of traffic to be mirrored type: number match: description: A/B testing match conditions diff --git a/charts/flagger/crds/crd.yaml b/charts/flagger/crds/crd.yaml index c46128f6..3ae25fa8 100644 --- a/charts/flagger/crds/crd.yaml +++ b/charts/flagger/crds/crd.yaml @@ -529,7 +529,7 @@ spec: description: Mirror traffic to canary type: boolean mirrorWeight: - description: Weight of traffic to be mirrored when + description: Percentage of traffic to be mirrored type: number match: description: A/B testing match conditions diff --git a/kustomize/base/flagger/crd.yaml b/kustomize/base/flagger/crd.yaml index c46128f6..3ae25fa8 100644 --- a/kustomize/base/flagger/crd.yaml +++ b/kustomize/base/flagger/crd.yaml @@ -529,7 +529,7 @@ spec: description: Mirror traffic to canary type: boolean mirrorWeight: - description: Weight of traffic to be mirrored when + description: Percentage of traffic to be mirrored type: number match: description: A/B testing match conditions diff --git a/pkg/canary/deployment_fixture_test.go b/pkg/canary/deployment_fixture_test.go index 486b3472..b2a0d6a6 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{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, diff --git a/pkg/controller/scheduler_daemonset_fixture_test.go b/pkg/controller/scheduler_daemonset_fixture_test.go index 65570ac8..62b61667 100644 --- a/pkg/controller/scheduler_daemonset_fixture_test.go +++ b/pkg/controller/scheduler_daemonset_fixture_test.go @@ -249,7 +249,7 @@ func newDaemonSetTestCanary() *flaggerv1.Canary { Kind: "DaemonSet", }, Service: flaggerv1.CanaryService{ Port: 9898, - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, @@ -288,7 +288,7 @@ func newDaemonSetTestCanary() *flaggerv1.Canary { func newDaemonSetTestCanaryMirror() *flaggerv1.Canary { cd := newDaemonSetTestCanary() - cd.Spec.CanaryAnalysis.Mirror = true + cd.Spec.Analysis.Mirror = true return cd } @@ -306,7 +306,7 @@ func newDaemonSetTestCanaryAB() *flaggerv1.Canary { Kind: "DaemonSet", }, Service: flaggerv1.CanaryService{ Port: 9898, - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, Iterations: 10, Match: []istiov1alpha3.HTTPMatchRequest{ diff --git a/pkg/controller/scheduler_daemonset_test.go b/pkg/controller/scheduler_daemonset_test.go index 4ed0ea33..3d650f45 100644 --- a/pkg/controller/scheduler_daemonset_test.go +++ b/pkg/controller/scheduler_daemonset_test.go @@ -55,7 +55,7 @@ func TestScheduler_DaemonSetRollback(t *testing.T) { require.NoError(t, err) cd := c.DeepCopy() - cd.Spec.CanaryAnalysis.Metrics = append(c.Spec.CanaryAnalysis.Metrics, flaggerv1.CanaryMetric{ + cd.Spec.Analysis.Metrics = append(c.Spec.Analysis.Metrics, flaggerv1.CanaryMetric{ Name: "fail", Interval: "1m", ThresholdRange: &flaggerv1.CanaryThresholdRange{ @@ -437,7 +437,7 @@ func TestScheduler_DaemonSetAlerts(t *testing.T) { defer ts.Close() canary := newDaemonSetTestCanary() - canary.Spec.CanaryAnalysis.Alerts = []flaggerv1.CanaryAlert{ + canary.Spec.Analysis.Alerts = []flaggerv1.CanaryAlert{ { Name: "slack-dev", Severity: "info", diff --git a/pkg/controller/scheduler_deployment_fixture_test.go b/pkg/controller/scheduler_deployment_fixture_test.go index be7c10dd..77f7f3a5 100644 --- a/pkg/controller/scheduler_deployment_fixture_test.go +++ b/pkg/controller/scheduler_deployment_fixture_test.go @@ -256,7 +256,7 @@ func newDeploymentTestCanary() *flaggerv1.Canary { Kind: "HorizontalPodAutoscaler", }, Service: flaggerv1.CanaryService{ Port: 9898, - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, @@ -295,7 +295,7 @@ func newDeploymentTestCanary() *flaggerv1.Canary { func newDeploymentTestCanaryMirror() *flaggerv1.Canary { cd := newDeploymentTestCanary() - cd.Spec.CanaryAnalysis.Mirror = true + cd.Spec.Analysis.Mirror = true return cd } @@ -318,7 +318,7 @@ func newDeploymentTestCanaryAB() *flaggerv1.Canary { Kind: "HorizontalPodAutoscaler", }, Service: flaggerv1.CanaryService{ Port: 9898, - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &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 d518956e..b65b6447 100644 --- a/pkg/controller/scheduler_deployment_test.go +++ b/pkg/controller/scheduler_deployment_test.go @@ -55,7 +55,7 @@ func TestScheduler_DeploymentRollback(t *testing.T) { c, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get("podinfo", metav1.GetOptions{}) require.NoError(t, err) cd := c.DeepCopy() - cd.Spec.CanaryAnalysis.Metrics = append(c.Spec.CanaryAnalysis.Metrics, flaggerv1.CanaryMetric{ + cd.Spec.Analysis.Metrics = append(c.Spec.Analysis.Metrics, flaggerv1.CanaryMetric{ Name: "fail", Interval: "1m", ThresholdRange: &flaggerv1.CanaryThresholdRange{ @@ -519,7 +519,7 @@ func TestScheduler_DeploymentAlerts(t *testing.T) { defer ts.Close() canary := newDeploymentTestCanary() - canary.Spec.CanaryAnalysis.Alerts = []flaggerv1.CanaryAlert{ + canary.Spec.Analysis.Alerts = []flaggerv1.CanaryAlert{ { Name: "slack-dev", Severity: "info", diff --git a/pkg/controller/scheduler_svc_test.go b/pkg/controller/scheduler_svc_test.go index e552906b..d1214adb 100644 --- a/pkg/controller/scheduler_svc_test.go +++ b/pkg/controller/scheduler_svc_test.go @@ -98,7 +98,7 @@ func newTestServiceCanary() *flaggerv1.Canary { Service: flaggerv1.CanaryService{ Port: 9898, }, - CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, diff --git a/pkg/router/contour_test.go b/pkg/router/contour_test.go index 064073c1..2c0c6c6b 100644 --- a/pkg/router/contour_test.go +++ b/pkg/router/contour_test.go @@ -57,8 +57,8 @@ func TestContourRouter_Reconcile(t *testing.T) { require.NoError(t, err) cdClone = cd.DeepCopy() - cdClone.Spec.CanaryAnalysis.Iterations = 5 - cdClone.Spec.CanaryAnalysis.Match = newTestABTest().Spec.CanaryAnalysis.Match + cdClone.Spec.Analysis.Iterations = 5 + cdClone.Spec.Analysis.Match = newTestABTest().Spec.Analysis.Match canary, err = mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone) require.NoError(t, err) @@ -104,8 +104,8 @@ func TestContourRouter_Routes(t *testing.T) { // test update to A/B cdClone := cd.DeepCopy() - cdClone.Spec.CanaryAnalysis.Iterations = 5 - cdClone.Spec.CanaryAnalysis.Match = newTestABTest().Spec.CanaryAnalysis.Match + cdClone.Spec.Analysis.Iterations = 5 + cdClone.Spec.Analysis.Match = newTestABTest().Spec.Analysis.Match canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(cdClone) require.NoError(t, err) diff --git a/pkg/router/router_test.go b/pkg/router/router_test.go index 205a8ab3..f2c07a48 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{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, @@ -158,7 +158,7 @@ func newTestCanaryAppMesh() *flaggerv1.Canary { PerTryTimeout: "gateway-error", RetryOn: "5s", }, - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, @@ -203,7 +203,7 @@ func newTestSMICanary() *flaggerv1.Canary { }, PortDiscovery: true, }, - CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, @@ -247,7 +247,7 @@ func newTestABTest() *flaggerv1.Canary { Service: flaggerv1.CanaryService{ Port: 9898, MeshName: "global", - }, CanaryAnalysis: &flaggerv1.CanaryAnalysis{ + }, Analysis: &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{ + }, Analysis: &flaggerv1.CanaryAnalysis{ Threshold: 10, StepWeight: 10, MaxWeight: 50, From adff6989f55c4f8087dc4269f79ec7f945b01452 Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 11:42:44 +0900 Subject: [PATCH 4/9] pkg/router/istio: add test for mirrorWeight --- pkg/router/istio_test.go | 109 +++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/pkg/router/istio_test.go b/pkg/router/istio_test.go index e48967f0..a2ac03a2 100644 --- a/pkg/router/istio_test.go +++ b/pkg/router/istio_test.go @@ -91,69 +91,78 @@ func TestIstioRouter_SetRoutes(t *testing.T) { err := router.Reconcile(mocks.canary) require.NoError(t, err) - p, c, m, err := router.GetRoutes(mocks.canary) - require.NoError(t, err) - - p = 60 - c = 40 - m = false - - err = router.SetRoutes(mocks.canary, p, c, m) - require.NoError(t, err) - - vs, err := mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get("podinfo", metav1.GetOptions{}) - require.NoError(t, err) - pHost := fmt.Sprintf("%s-primary", mocks.canary.Spec.TargetRef.Name) cHost := fmt.Sprintf("%s-canary", mocks.canary.Spec.TargetRef.Name) - pRoute := istiov1alpha3.DestinationWeight{} - cRoute := istiov1alpha3.DestinationWeight{} - var mirror *istiov1alpha3.Destination - for _, http := range vs.Spec.Http { - for _, route := range http.Route { - if route.Destination.Host == pHost { - pRoute = route - } - if route.Destination.Host == cHost { - cRoute = route - mirror = http.Mirror + t.Run("normal", func(t *testing.T) { + p, c := 60, 40 + err := router.SetRoutes(mocks.canary, p, c, false) + require.NoError(t, err) + + vs, err := mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get("podinfo", metav1.GetOptions{}) + require.NoError(t, err) + + var pRoute, cRoute istiov1alpha3.DestinationWeight + var mirror *istiov1alpha3.Destination + for _, http := range vs.Spec.Http { + for _, route := range http.Route { + if route.Destination.Host == pHost { + pRoute = route + } + if route.Destination.Host == cHost { + cRoute = route + mirror = http.Mirror + } } } - } - assert.Equal(t, p, pRoute.Weight) - assert.Equal(t, c, cRoute.Weight) - assert.Nil(t, mirror) + assert.Equal(t, p, pRoute.Weight) + assert.Equal(t, c, cRoute.Weight) + assert.Nil(t, mirror) - mirror = nil - p = 100 - c = 0 - m = true + }) - err = router.SetRoutes(mocks.canary, p, c, m) - require.NoError(t, err) + t.Run("mirror", func(t *testing.T) { + for _, w := range []float64{0, 10, 50} { + p, c := 100, 0 - vs, err = mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get("podinfo", metav1.GetOptions{}) - require.NoError(t, err) + // set mirror weight + mocks.canary.Spec.Analysis.MirrorWeight = w + err := router.SetRoutes(mocks.canary, p, c, true) + require.NoError(t, err) - for _, http := range vs.Spec.Http { - for _, route := range http.Route { - if route.Destination.Host == pHost { - pRoute = route + vs, err := mocks.meshClient.NetworkingV1alpha3().VirtualServices("default").Get("podinfo", metav1.GetOptions{}) + require.NoError(t, err) + + var pRoute, cRoute istiov1alpha3.DestinationWeight + var mirror *istiov1alpha3.Destination + var mirrorWeight *istiov1alpha3.Percent + for _, http := range vs.Spec.Http { + for _, route := range http.Route { + if route.Destination.Host == pHost { + pRoute = route + } + if route.Destination.Host == cHost { + cRoute = route + mirror = http.Mirror + mirrorWeight = http.MirrorPercentage + } + } } - if route.Destination.Host == cHost { - cRoute = route - mirror = http.Mirror + + assert.Equal(t, p, pRoute.Weight) + assert.Equal(t, c, cRoute.Weight) + if assert.NotNil(t, mirror) { + assert.Equal(t, cHost, mirror.Host) + } + + if w > 0 && assert.NotNil(t, mirrorWeight) { + assert.Equal(t, w, mirrorWeight.Value) + } else { + assert.Nil(t, mirrorWeight) } } - } - - assert.Equal(t, p, pRoute.Weight) - assert.Equal(t, c, cRoute.Weight) - if assert.NotNil(t, mirror) { - assert.Equal(t, cHost, mirror.Host) - } + }) } func TestIstioRouter_GetRoutes(t *testing.T) { From 3a887afa38ac9d270a740981d97eed77df94b451 Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 14:15:18 +0900 Subject: [PATCH 5/9] fix json key of mirrorWeight --- pkg/apis/flagger/v1beta1/canary.go | 2 +- pkg/apis/istio/v1alpha3/virtual_service.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index f0d3e905..7e33239b 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -181,7 +181,7 @@ type CanaryAnalysis struct { // Percentage of the traffic to be mirrored in the range of [0.0, 100.0]. // +optional - MirrorWeight float64 `json:"mirror_weight,omitempty"` + MirrorWeight float64 `json:"mirrorWeight,omitempty"` // Max traffic percentage routed to canary // +optional diff --git a/pkg/apis/istio/v1alpha3/virtual_service.go b/pkg/apis/istio/v1alpha3/virtual_service.go index 84ca29e2..7718ab07 100644 --- a/pkg/apis/istio/v1alpha3/virtual_service.go +++ b/pkg/apis/istio/v1alpha3/virtual_service.go @@ -328,7 +328,7 @@ type HTTPRoute struct { // Percentage of the traffic to be mirrored by the `mirror` field. // If this field is absent, all the traffic (100%) will be mirrored. // Max value is 100. - MirrorPercentage *Percent `json:"mirror_percentage"` + MirrorPercentage *Percent `json:"mirrorPercentage,omitempty"` // Cross-Origin Resource Sharing policy (CORS). Refer to // https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS From aec0010b14e5692e6d18236a2308e8f7b5ce243c Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 14:54:57 +0900 Subject: [PATCH 6/9] ignore MirrorPercentage in reconcileVirtualService --- pkg/router/istio.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/router/istio.go b/pkg/router/istio.go index a1c9ddd4..4122e821 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -206,7 +206,7 @@ func (ir *IstioRouter) reconcileVirtualService(canary *flaggerv1.Canary) error { newSpec, virtualService.Spec, cmpopts.IgnoreFields(istiov1alpha3.DestinationWeight{}, "Weight"), - cmpopts.IgnoreFields(istiov1alpha3.HTTPRoute{}, "Mirror"), + cmpopts.IgnoreFields(istiov1alpha3.HTTPRoute{}, "Mirror", "MirrorPercentage"), ); diff != "" { vtClone := virtualService.DeepCopy() vtClone.Spec = newSpec From d911e1ddc551a6bef274f7d8b99a68848f78882d Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 15:16:03 +0900 Subject: [PATCH 7/9] docs: add mirrorWeight example --- docs/gitbook/tutorials/istio-progressive-delivery.md | 4 +++- docs/gitbook/usage/deployment-strategies.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/gitbook/tutorials/istio-progressive-delivery.md b/docs/gitbook/tutorials/istio-progressive-delivery.md index 9cc930d6..9764c828 100644 --- a/docs/gitbook/tutorials/istio-progressive-delivery.md +++ b/docs/gitbook/tutorials/istio-progressive-delivery.md @@ -324,6 +324,8 @@ spec: iterations: 10 # enable traffic shadowing mirror: true + # weight of the traffic mirrored to your canary (defaults to 100%) + mirrorWeight: 100.0 metrics: - name: request-success-rate thresholdRange: @@ -357,7 +359,7 @@ With the above configuration, Flagger will run a canary release with the followi * run the acceptance tests * abort the canary release if tests fail * start the load tests -* mirror traffic from primary to canary +* mirror 100% of the traffic from primary to canary * check request success rate and request duration every minute * abort the canary release if the metrics check failure threshold is reached * stop traffic mirroring after the number of iterations is reached diff --git a/docs/gitbook/usage/deployment-strategies.md b/docs/gitbook/usage/deployment-strategies.md index e46bd767..bc70aafa 100644 --- a/docs/gitbook/usage/deployment-strategies.md +++ b/docs/gitbook/usage/deployment-strategies.md @@ -277,6 +277,8 @@ Istio example: threshold: 2 # Traffic shadowing (compatible with Istio only) mirror: true + # Weight of the traffic mirrored to your canary (defaults to 100%) + mirrorWeight: 100.0 ``` Mirroring rollout steps for service mesh: @@ -287,7 +289,7 @@ Mirroring rollout steps for service mesh: * run the acceptance tests * abort the canary release if tests fail * start the load tests -* mirror traffic from primary to canary +* mirror 100% of the traffic from primary to canary * check request success rate and request duration every minute * abort the canary release if the failure threshold is reached * stop traffic mirroring after the number of iterations is reached From 3425d6e965fef33aeb90cde39932614b0837d976 Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 15:28:20 +0900 Subject: [PATCH 8/9] pkg/router/istio: use canary.GetAnalysis to prevent nil pointer --- pkg/router/istio.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/router/istio.go b/pkg/router/istio.go index 4122e821..f38d6b9a 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -305,7 +305,7 @@ func (ir *IstioRouter) SetRoutes( Host: canaryName, } - if mw := canary.Spec.Analysis.MirrorWeight; mw > 0 { + if mw := canary.GetAnalysis().MirrorWeight; mw > 0 { vsCopy.Spec.Http[0].MirrorPercentage = &istiov1alpha3.Percent{Value: mw} } } From 7380dbb8ab7b803ecd0efa2f1e180735a92ad01d Mon Sep 17 00:00:00 2001 From: mathetake Date: Tue, 10 Mar 2020 15:47:46 +0900 Subject: [PATCH 9/9] make MirrorWeight's type int, not float64 --- docs/gitbook/tutorials/istio-progressive-delivery.md | 2 +- docs/gitbook/usage/deployment-strategies.md | 2 +- pkg/apis/flagger/v1beta1/canary.go | 4 ++-- pkg/router/istio.go | 2 +- pkg/router/istio_test.go | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/gitbook/tutorials/istio-progressive-delivery.md b/docs/gitbook/tutorials/istio-progressive-delivery.md index 9764c828..39b6df63 100644 --- a/docs/gitbook/tutorials/istio-progressive-delivery.md +++ b/docs/gitbook/tutorials/istio-progressive-delivery.md @@ -325,7 +325,7 @@ spec: # enable traffic shadowing mirror: true # weight of the traffic mirrored to your canary (defaults to 100%) - mirrorWeight: 100.0 + mirrorWeight: 100 metrics: - name: request-success-rate thresholdRange: diff --git a/docs/gitbook/usage/deployment-strategies.md b/docs/gitbook/usage/deployment-strategies.md index bc70aafa..05cc4fd5 100644 --- a/docs/gitbook/usage/deployment-strategies.md +++ b/docs/gitbook/usage/deployment-strategies.md @@ -278,7 +278,7 @@ Istio example: # Traffic shadowing (compatible with Istio only) mirror: true # Weight of the traffic mirrored to your canary (defaults to 100%) - mirrorWeight: 100.0 + mirrorWeight: 100 ``` Mirroring rollout steps for service mesh: diff --git a/pkg/apis/flagger/v1beta1/canary.go b/pkg/apis/flagger/v1beta1/canary.go index 7e33239b..dd9c891a 100644 --- a/pkg/apis/flagger/v1beta1/canary.go +++ b/pkg/apis/flagger/v1beta1/canary.go @@ -179,9 +179,9 @@ type CanaryAnalysis struct { // +optional Mirror bool `json:"mirror,omitempty"` - // Percentage of the traffic to be mirrored in the range of [0.0, 100.0]. + // Percentage of the traffic to be mirrored in the range of [0, 100]. // +optional - MirrorWeight float64 `json:"mirrorWeight,omitempty"` + MirrorWeight int `json:"mirrorWeight,omitempty"` // Max traffic percentage routed to canary // +optional diff --git a/pkg/router/istio.go b/pkg/router/istio.go index f38d6b9a..3cdfd220 100644 --- a/pkg/router/istio.go +++ b/pkg/router/istio.go @@ -306,7 +306,7 @@ func (ir *IstioRouter) SetRoutes( } if mw := canary.GetAnalysis().MirrorWeight; mw > 0 { - vsCopy.Spec.Http[0].MirrorPercentage = &istiov1alpha3.Percent{Value: mw} + vsCopy.Spec.Http[0].MirrorPercentage = &istiov1alpha3.Percent{Value: float64(mw)} } } diff --git a/pkg/router/istio_test.go b/pkg/router/istio_test.go index a2ac03a2..0b9c3591 100644 --- a/pkg/router/istio_test.go +++ b/pkg/router/istio_test.go @@ -123,7 +123,7 @@ func TestIstioRouter_SetRoutes(t *testing.T) { }) t.Run("mirror", func(t *testing.T) { - for _, w := range []float64{0, 10, 50} { + for _, w := range []int{0, 10, 50} { p, c := 100, 0 // set mirror weight @@ -157,7 +157,7 @@ func TestIstioRouter_SetRoutes(t *testing.T) { } if w > 0 && assert.NotNil(t, mirrorWeight) { - assert.Equal(t, w, mirrorWeight.Value) + assert.Equal(t, w, int(mirrorWeight.Value)) } else { assert.Nil(t, mirrorWeight) }