Skip to content

Commit ab15370

Browse files
rakebMazhar Islam
andauthored
Flexible backend group bug fix: if clientPolicy is defined under backends, it does not get converted to sdk VN spec (#651)
* Added primary changes to fix the clientPolicy missing in VN spec * Bug fix: clientPolicy now can be added under backends, which previously does not get converted to AppMesh SDK spec * Bug fix: clientPolicy now can be added under backends, which previously does not get converted to AppMesh SDK spec Co-authored-by: Mazhar Islam <[email protected]>
1 parent 700eb80 commit ab15370

File tree

9 files changed

+111
-32
lines changed

9 files changed

+111
-32
lines changed

apis/appmesh/v1beta2/backendgroup_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ type BackendGroupReference struct {
4848
Name string `json:"name"`
4949
}
5050

51-
//+kubebuilder:object:root=true
51+
// +kubebuilder:object:root=true
5252
// +kubebuilder:resource:categories=all
53-
//+kubebuilder:subresource:status
53+
// +kubebuilder:subresource:status
5454
// +kubebuilder:pruning:PreserveUnknownFields
5555
// BackendGroup is the Schema for the backendgroups API
5656
type BackendGroup struct {

pkg/equality/ignore_left_hand_unset.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88

99
// IgnoreLeftHandUnset is an option that ignores struct fields that are unset on the left hand side of a comparison.
1010
// Note:
11-
// 1. for map and slices, only nil value is considered to be unset, non-nil but empty is not considered as unset.
12-
// 2. for struct pointers, nil value is considered to be unset
11+
// 1. for map and slices, only nil value is considered to be unset, non-nil but empty is not considered as unset.
12+
// 2. for struct pointers, nil value is considered to be unset
1313
func IgnoreLeftHandUnset(typ interface{}, fields ...string) cmp.Option {
1414
t := reflect.TypeOf(typ)
1515
fieldsSet := sets.NewString(fields...)

pkg/inject/sidecar_builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
const envoyTracingConfigVolumeName = "envoy-tracing-config"
1616

1717
// Envoy template variables used by envoys in pod and the envoy in VirtualGateway
18-
//as we use the same envoy image
18+
// as we use the same envoy image
1919
type EnvoyTemplateVariables struct {
2020
AWSRegion string
2121
MeshName string

pkg/virtualnode/resource_manager.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package virtualnode
33
import (
44
"context"
55
"fmt"
6-
76
appmesh "github.com/aws/aws-app-mesh-controller-for-k8s/apis/appmesh/v1beta2"
87
"github.com/aws/aws-app-mesh-controller-for-k8s/pkg/aws/services"
98
"github.com/aws/aws-app-mesh-controller-for-k8s/pkg/conversions"
@@ -343,8 +342,17 @@ func BuildSDKVirtualNodeSpec(vn *appmesh.VirtualNode, vsByKey map[types.Namespac
343342
})
344343
sdkVNSpec := &appmeshsdk.VirtualNodeSpec{}
345344
tempSpec := vn.Spec.DeepCopy()
346-
tempSpec.Backends = []appmesh.Backend{}
347-
for _, vs := range vsByKey {
345+
backendMap := make(map[types.NamespacedName]bool)
346+
347+
for _, backend := range tempSpec.Backends {
348+
vsKey := references.ObjectKeyForVirtualServiceReference(vn, *backend.VirtualService.VirtualServiceRef)
349+
backendMap[vsKey] = true
350+
}
351+
352+
for vsKey, vs := range vsByKey {
353+
if _, ok := backendMap[vsKey]; ok {
354+
continue
355+
}
348356
tempSpec.Backends = append(tempSpec.Backends, appmesh.Backend{
349357
VirtualService: appmesh.VirtualServiceBackend{
350358
VirtualServiceRef: &appmesh.VirtualServiceReference{

pkg/virtualnode/resource_manager_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,3 +593,64 @@ func Test_defaultResourceManager_findVirtualServiceDependencies(t *testing.T) {
593593
})
594594
}
595595
}
596+
597+
/*
598+
This is a bit tricky unit testing. First we created a vn having VirtualServiceRef and ClientPolicy. The VirtualServiceRef key is (ns-1/vs-1).
599+
Later we created two entries of vsByKey having keys (ns-2/vs-2) with a VirtualRouterServiceProvider and (ns-1/vs-1) with an empty body.
600+
The reason behind that, the BuildSDKVirtualNodeSpec function will not modify the vn spec under key (ns-1/vs-1) as it is part of the
601+
Backends. However, VirtualRouterServiceProvider will get wiped out because it is under key (ns-2/vs-2) and will be treated as flexible backend.
602+
*/
603+
func Test_BuildSDKVirtualNodeSpec(t *testing.T) {
604+
vn := &appmesh.VirtualNode{
605+
ObjectMeta: metav1.ObjectMeta{
606+
Name: "vn-1",
607+
},
608+
Spec: appmesh.VirtualNodeSpec{
609+
AWSName: aws.String("app1"),
610+
Backends: []appmesh.Backend{
611+
{
612+
VirtualService: appmesh.VirtualServiceBackend{
613+
VirtualServiceRef: &appmesh.VirtualServiceReference{
614+
Namespace: aws.String("ns-1"),
615+
Name: "vs-1",
616+
},
617+
ClientPolicy: &appmesh.ClientPolicy{
618+
TLS: &appmesh.ClientPolicyTLS{
619+
Enforce: aws.Bool(true),
620+
},
621+
},
622+
}}},
623+
},
624+
}
625+
626+
vsByKey := map[types.NamespacedName]*appmesh.VirtualService{types.NamespacedName{
627+
Namespace: "ns-2", Name: "vs-2"}: &appmesh.VirtualService{
628+
ObjectMeta: metav1.ObjectMeta{
629+
Namespace: "ns-2",
630+
Name: "vs-2",
631+
},
632+
Spec: appmesh.VirtualServiceSpec{
633+
AWSName: aws.String("app2"),
634+
Provider: &appmesh.VirtualServiceProvider{
635+
VirtualRouter: &appmesh.VirtualRouterServiceProvider{
636+
VirtualRouterRef: &appmesh.VirtualRouterReference{
637+
Namespace: aws.String("ns-2"),
638+
Name: "vr-2",
639+
},
640+
},
641+
},
642+
}}}
643+
644+
vsByKey[types.NamespacedName{Namespace: "ns-1", Name: "vs-1"}] = &appmesh.VirtualService{}
645+
646+
ctrl := gomock.NewController(t)
647+
defer ctrl.Finish()
648+
649+
sdkVnSpec, err := BuildSDKVirtualNodeSpec(vn, vsByKey)
650+
if err != nil {
651+
assert.Fail(t, "Could not convert to sdkVn spec", err)
652+
} else {
653+
assert.NotNil(t, sdkVnSpec.Backends[0].VirtualService.ClientPolicy)
654+
assert.Nil(t, sdkVnSpec.Backends[1].VirtualService.ClientPolicy)
655+
}
656+
}

test/e2e/fishapp/dynamic_stack.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ var (
6565

6666
// A dynamic generated stack designed to test app mesh integration :D
6767
// Suppose given configuration below:
68-
// 5 VirtualServicesCount
69-
// 10 VirtualNodesCount
70-
// 2 RoutesCountPerVirtualRouter
71-
// 2 TargetsCountPerRoute
72-
// 4 BackendsCountPerVirtualNode
68+
//
69+
// 5 VirtualServicesCount
70+
// 10 VirtualNodesCount
71+
// 2 RoutesCountPerVirtualRouter
72+
// 2 TargetsCountPerRoute
73+
// 4 BackendsCountPerVirtualNode
74+
//
7375
// We will generate virtual service configuration & virtual node configuration follows:
7476
// =======virtual services =========
77+
//
7578
// vs1 -> /path1 -> vn1(50)
7679
// -> vn2(50)
7780
// -> /path2 -> vn3(50)
@@ -92,11 +95,13 @@ var (
9295
// -> vn8(50)
9396
// -> /path2 -> vn9(50)
9497
// -> vn10(50)
98+
//
9599
// =======virtual nodes =========
96-
// vn1 -> vs1,vs2,vs3,vs4
97-
// vn2 -> vs5,vs1,vs2,vs3
98-
// vn3 -> vs4,vs5,vs1,vs2
99-
// ...
100+
//
101+
// vn1 -> vs1,vs2,vs3,vs4
102+
// vn2 -> vs5,vs1,vs2,vs3
103+
// vn3 -> vs4,vs5,vs1,vs2
104+
// ...
100105
//
101106
// then we validate each virtual node can access each virtual service at every path, and calculates the target distribution
102107
type DynamicStack struct {

test/e2e/fishapp/load/dynamic_stack_load_test.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,16 @@ var (
6969

7070
// A dynamic generated stack designed to test app mesh integration :D
7171
// Suppose given configuration below:
72-
// 5 VirtualServicesCount
73-
// 5 VirtualNodesCount
74-
// 2 RoutesCountPerVirtualRouter
75-
// 2 TargetsCountPerRoute
76-
// 4 BackendsCountPerVirtualNode
72+
//
73+
// 5 VirtualServicesCount
74+
// 5 VirtualNodesCount
75+
// 2 RoutesCountPerVirtualRouter
76+
// 2 TargetsCountPerRoute
77+
// 4 BackendsCountPerVirtualNode
78+
//
7779
// We will generate virtual service configuration & virtual node configuration follows:
7880
// =======virtual services =========
81+
//
7982
// vs1 -> /path1 -> vn1(50)
8083
// -> vn2(50)
8184
// -> /path2 -> vn3(50)
@@ -96,11 +99,13 @@ var (
9699
// -> vn8(50)
97100
// -> /path2 -> vn9(50)
98101
// -> vn10(50)
102+
//
99103
// =======virtual nodes =========
100-
// vn1 -> vs1,vs2,vs3,vs4
101-
// vn2 -> vs5,vs1,vs2,vs3
102-
// vn3 -> vs4,vs5,vs1,vs2
103-
// ...
104+
//
105+
// vn1 -> vs1,vs2,vs3,vs4
106+
// vn2 -> vs5,vs1,vs2,vs3
107+
// vn3 -> vs4,vs5,vs1,vs2
108+
// ...
104109
//
105110
// then we validate each virtual node can access each virtual service at every path, and calculates the target distribution
106111
type DynamicStack struct {

test/integration/timeout/timeout_stack.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (s *TimeoutStack) CleanupTimeoutStack(ctx context.Context, f *framework.Fra
107107
Expect(len(deletionErrors)).To(BeZero())
108108
}
109109

110-
//Check Timeout behavior with and with timeout configured
110+
// Check Timeout behavior with and with timeout configured
111111
func (s *TimeoutStack) CheckTimeoutBehavior(ctx context.Context, f *framework.Framework) {
112112
By(fmt.Sprintf("verify route timesout if it takes more than default 15s w/o listener timeout configured"), func() {
113113
err := s.checkExpectedRouteBehavior(ctx, f, s.FrontEndDP, "defaultroute", false)

test/integration/tls/tls_stack.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ type TLSStack struct {
6666
BackEndVR *appmesh.VirtualRouter
6767
}
6868

69-
//TLS Validation is enabled on the Frontend and Listener TLS is configured on the backend. Frontend looks
70-
//for certs signed by CA1 and backend certs are signed by CA1 as well.
69+
// TLS Validation is enabled on the Frontend and Listener TLS is configured on the backend. Frontend looks
70+
// for certs signed by CA1 and backend certs are signed by CA1 as well.
7171
func (s *TLSStack) DeployTLSStack(ctx context.Context, f *framework.Framework) {
7272
s.createTLSStackMeshAndNamespace(ctx, f)
7373
mb := &manifest.ManifestBuilder{
@@ -80,7 +80,7 @@ func (s *TLSStack) DeployTLSStack(ctx context.Context, f *framework.Framework) {
8080
s.assignBackendVSToFrontEndVN(ctx, f)
8181
}
8282

83-
//Frontend has TLS Validation enabled while TLS is disabled on the backend
83+
// Frontend has TLS Validation enabled while TLS is disabled on the backend
8484
func (s *TLSStack) DeployPartialTLSStack(ctx context.Context, f *framework.Framework) {
8585
s.createTLSStackMeshAndNamespace(ctx, f)
8686
time.Sleep(30 * time.Second)
@@ -94,8 +94,8 @@ func (s *TLSStack) DeployPartialTLSStack(ctx context.Context, f *framework.Frame
9494
s.assignBackendVSToFrontEndVN(ctx, f)
9595
}
9696

97-
//TLS Validation is enabled on the Frontend and Listener TLS is configured on the backend. Frontend looks
98-
//for certs signed by CA2 while backend certs are signed by CA1.
97+
// TLS Validation is enabled on the Frontend and Listener TLS is configured on the backend. Frontend looks
98+
// for certs signed by CA2 while backend certs are signed by CA1.
9999
func (s *TLSStack) DeployTLSValidationStack(ctx context.Context, f *framework.Framework) {
100100
s.createTLSStackMeshAndNamespace(ctx, f)
101101
time.Sleep(30 * time.Second)

0 commit comments

Comments
 (0)