From 4da6c1b6e4fe2d83e77b710659543c5afe277830 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Thu, 3 Oct 2019 11:43:47 +0300 Subject: [PATCH] Create canary virtual service during App Mesh reconciliation Allows the canary pods to be accessed from inside the mesh during the canary analysis for conformance and load testing --- pkg/router/appmesh.go | 17 ++++++++++++----- pkg/router/appmesh_test.go | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/pkg/router/appmesh.go b/pkg/router/appmesh.go index c8b36ae0..6d25f117 100644 --- a/pkg/router/appmesh.go +++ b/pkg/router/appmesh.go @@ -56,9 +56,16 @@ func (ar *AppMeshRouter) Reconcile(canary *flaggerv1.Canary) error { return err } - // sync virtual service e.g. app.namespace + // sync main virtual service // DNS app.namespace - err = ar.reconcileVirtualService(canary, targetHost) + err = ar.reconcileVirtualService(canary, targetHost, 0) + if err != nil { + return err + } + + // sync canary virtual service + // DNS app-canary.namespace + err = ar.reconcileVirtualService(canary, fmt.Sprintf("%s.%s", canaryName, canary.Namespace), 100) if err != nil { return err } @@ -148,7 +155,7 @@ func (ar *AppMeshRouter) reconcileVirtualNode(canary *flaggerv1.Canary, name str } // reconcileVirtualService creates or updates a virtual service -func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name string) error { +func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name string, canaryWeight int64) error { targetName := canary.Spec.TargetRef.Name canaryVirtualNode := fmt.Sprintf("%s-canary", targetName) primaryVirtualNode := fmt.Sprintf("%s-primary", targetName) @@ -185,11 +192,11 @@ func (ar *AppMeshRouter) reconcileVirtualService(canary *flaggerv1.Canary, name WeightedTargets: []AppmeshV1beta1.WeightedTarget{ { VirtualNodeName: canaryVirtualNode, - Weight: 0, + Weight: canaryWeight, }, { VirtualNodeName: primaryVirtualNode, - Weight: 100, + Weight: 100 - canaryWeight, }, }, }, diff --git a/pkg/router/appmesh_test.go b/pkg/router/appmesh_test.go index 0fbed858..3e261d95 100644 --- a/pkg/router/appmesh_test.go +++ b/pkg/router/appmesh_test.go @@ -37,6 +37,23 @@ func TestAppmeshRouter_Reconcile(t *testing.T) { t.Errorf("Got routes %v wanted %v", targetsCount, 2) } + // check canary virtual service + vsCanaryName := fmt.Sprintf("%s-canary.%s", mocks.appmeshCanary.Spec.TargetRef.Name, mocks.appmeshCanary.Namespace) + vsCanary, err := router.appmeshClient.AppmeshV1beta1().VirtualServices("default").Get(vsCanaryName, metav1.GetOptions{}) + if err != nil { + t.Fatal(err.Error()) + } + + // check if the canary virtual service routes all traffic to the canary virtual node + target := vsCanary.Spec.Routes[0].Http.Action.WeightedTargets[0] + canaryVirtualNodeName := fmt.Sprintf("%s-canary", mocks.appmeshCanary.Spec.TargetRef.Name) + if target.VirtualNodeName != canaryVirtualNodeName { + t.Errorf("Got VirtualNodeName %v wanted %v", target.VirtualNodeName, canaryVirtualNodeName) + } + if target.Weight != 100 { + t.Errorf("Got weight %v wanted %v", target.Weight, 100) + } + // check virtual node vnName := mocks.appmeshCanary.Spec.TargetRef.Name vn, err := router.appmeshClient.AppmeshV1beta1().VirtualNodes("default").Get(vnName, metav1.GetOptions{}) @@ -103,7 +120,7 @@ func TestAppmeshRouter_Reconcile(t *testing.T) { weight := vs.Spec.Routes[0].Http.Action.WeightedTargets[0].Weight if weight != 50 { - t.Errorf("Got weight %v wanted %v", weight, 502) + t.Errorf("Got weight %v wanted %v", weight, 50) } // test URI update