Skip to content

Commit 036e2a3

Browse files
author
Zijun Wang
committed
Address PR comments: Adding build TLS_PASSTHROUGH listener logic in the model_build_listener
1 parent 5048c7d commit 036e2a3

14 files changed

+426
-146
lines changed

pkg/deploy/lattice/listener_synthesizer.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (l *listenerSynthesizer) Synthesize(ctx context.Context) error {
5050
return err
5151
}
5252

53-
defaultAction, err := l.getLatticeListenerDefaultAction(ctx, listener.Spec.Protocol)
53+
defaultAction, err := l.getLatticeListenerDefaultAction(ctx, listener)
5454
if err != nil {
5555
return err
5656
}
@@ -89,37 +89,37 @@ func (l *listenerSynthesizer) Synthesize(ctx context.Context) error {
8989
return nil
9090
}
9191

92-
func (l *listenerSynthesizer) getLatticeListenerDefaultAction(ctx context.Context, modelListenerProtocol string) (
92+
func (l *listenerSynthesizer) getLatticeListenerDefaultAction(ctx context.Context, stackListener *model.Listener) (
9393
*vpclattice.RuleAction, error,
9494
) {
95-
if modelListenerProtocol != vpclattice.ListenerProtocolTlsPassthrough {
95+
if stackListener.Spec.DefaultAction == nil ||
96+
(stackListener.Spec.DefaultAction.FixedResponseStatusCode == nil && stackListener.Spec.DefaultAction.Forward == nil) {
97+
return nil, fmt.Errorf("invalid listener default action, must be either fixed response or forward")
98+
}
99+
100+
if stackListener.Spec.DefaultAction.FixedResponseStatusCode != nil {
96101
return &vpclattice.RuleAction{
97102
FixedResponse: &vpclattice.FixedResponseAction{
98-
StatusCode: aws.Int64(404),
103+
StatusCode: stackListener.Spec.DefaultAction.FixedResponseStatusCode,
99104
},
100105
}, nil
101106
}
102107

103-
var stackRules []*model.Rule
104-
_ = l.stack.ListResources(&stackRules)
105-
if len(stackRules) != 1 {
106-
return nil, fmt.Errorf("TLS_PASSTHROUGH listener can only have one default action and without any other additional rule, but got %d rules", len(stackRules))
107-
}
108-
if err := l.tgManager.ResolveRuleTgIds(ctx, stackRules[0], l.stack); err != nil {
108+
// If the listener DefaultAction is not fixed response, for example for TLS_PASSTHROUGH listener, it must be a forward action, fill the forward action target group ids for it
109+
if err := l.tgManager.ResolveRuleTgIds(ctx, stackListener.Spec.DefaultAction.Forward, l.stack); err != nil {
109110
return nil, fmt.Errorf("failed to resolve rule tg ids, err = %v", err)
110111
}
111112

112-
// For TLS_PASSTHROUGH listener, we need to fill the stackRules[0].Spec.Action.TargetGroups to the lattice listener's defaultAction ForwardAction TargetGroups
113113
var latticeTGs []*vpclattice.WeightedTargetGroup
114-
for _, modelTG := range stackRules[0].Spec.Action.TargetGroups {
114+
for _, modelTG := range stackListener.Spec.DefaultAction.Forward.TargetGroups {
115115
latticeTG := vpclattice.WeightedTargetGroup{
116116
TargetGroupIdentifier: aws.String(modelTG.LatticeTgId),
117117
Weight: aws.Int64(modelTG.Weight),
118118
}
119119
latticeTGs = append(latticeTGs, &latticeTG)
120120
}
121121

122-
l.log.Debugf("For TLS_PASSTHROUGH listener, forward to default target groups %v", latticeTGs)
122+
l.log.Debugf("DefaultAction Forward target groups: %v", latticeTGs)
123123
return &vpclattice.RuleAction{
124124
Forward: &vpclattice.ForwardAction{
125125
TargetGroups: latticeTGs,

pkg/deploy/lattice/listener_synthesizer_test.go

Lines changed: 94 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ func Test_SynthesizeListenerCreate(t *testing.T) {
3434
ResourceMeta: core.NewResourceMeta(stack, "AWS:VPCServiceNetwork::Listener", "l-id"),
3535
Spec: model.ListenerSpec{
3636
StackServiceId: "stack-svc-id",
37+
DefaultAction: &model.DefaultAction{
38+
FixedResponseStatusCode: aws.Int64(404),
39+
},
3740
},
3841
}
3942
assert.NoError(t, stack.AddResource(l))
@@ -73,6 +76,9 @@ func Test_SynthesizeListener_CreatNewHTTPListener_DeleteStaleHTTPSListener(t *te
7376
StackServiceId: "stack-svc-id",
7477
Protocol: vpclattice.ListenerProtocolHttp,
7578
Port: 80,
79+
DefaultAction: &model.DefaultAction{
80+
FixedResponseStatusCode: aws.Int64(404),
81+
},
7682
},
7783
}
7884
assert.NoError(t, stack.AddResource(l))
@@ -135,9 +141,9 @@ func Test_SynthesizeListener_CreatNewTLSPassthroughListener_DeleteStaleHTTPSList
135141
}
136142
assert.NoError(t, stack.AddResource(rule))
137143
mockTargetGroupManager.EXPECT().ResolveRuleTgIds(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
138-
func(ctx context.Context, rule *model.Rule, stack core.Stack) error {
139-
rule.Spec.Action.TargetGroups[0].LatticeTgId = "lattice-tg-id-1"
140-
rule.Spec.Action.TargetGroups[1].LatticeTgId = "lattice-tg-id-2"
144+
func(ctx context.Context, ruleAction *model.RuleAction, stack core.Stack) error {
145+
ruleAction.TargetGroups[0].LatticeTgId = "lattice-tg-id-1"
146+
ruleAction.TargetGroups[1].LatticeTgId = "lattice-tg-id-2"
141147
return nil
142148
})
143149
l := &model.Listener{
@@ -146,6 +152,7 @@ func Test_SynthesizeListener_CreatNewTLSPassthroughListener_DeleteStaleHTTPSList
146152
StackServiceId: "stack-svc-id",
147153
Protocol: vpclattice.ListenerProtocolTlsPassthrough,
148154
Port: 80,
155+
DefaultAction: &model.DefaultAction{Forward: &model.RuleAction{TargetGroups: rule.Spec.Action.TargetGroups}},
149156
},
150157
}
151158
assert.NoError(t, stack.AddResource(l))
@@ -187,46 +194,60 @@ func Test_SynthesizeListener_CreatNewTLSPassthroughListener_DeleteStaleHTTPSList
187194
}
188195

189196
func Test_listenerSynthesizer_getLatticeListenerDefaultAction_FixedResponse404(t *testing.T) {
190-
fixResponseAction404 := &vpclattice.RuleAction{
197+
latticeFixResponseAction404 := &vpclattice.RuleAction{
191198
FixedResponse: &vpclattice.FixedResponseAction{
192199
StatusCode: aws.Int64(404),
193200
},
194201
}
195202
tests := []struct {
196-
name string
197-
listenerProtocol string
198-
want *vpclattice.RuleAction
199-
wantErr error
203+
name string
204+
stackListenerDefaultAction *model.DefaultAction
205+
listenerProtocol string
206+
want *vpclattice.RuleAction
207+
wantErr error
200208
}{
201209
{
202-
name: "HTTP protocol Listener has the 404 fixed response default action",
203-
listenerProtocol: "HTTP",
204-
want: fixResponseAction404,
205-
wantErr: nil,
210+
name: "HTTP protocol Listener has the 404 fixed response modelListenerDefaultAction, return lattice fixed response 404 DefaultAction",
211+
stackListenerDefaultAction: &model.DefaultAction{FixedResponseStatusCode: aws.Int64(404)},
212+
listenerProtocol: vpclattice.ListenerProtocolHttp,
213+
want: latticeFixResponseAction404,
214+
wantErr: nil,
206215
},
207216
{
208-
name: "HTTPS protocol Listener has the 404 fixed response default action",
209-
listenerProtocol: "HTTPS",
210-
want: fixResponseAction404,
211-
wantErr: nil,
217+
name: "HTTPS protocol Listener has the 404 fixed response modelListenerDefaultAction, return lattice fixed response 404 DefaultAction",
218+
stackListenerDefaultAction: &model.DefaultAction{FixedResponseStatusCode: aws.Int64(404)},
219+
listenerProtocol: vpclattice.ListenerProtocolHttps,
220+
want: latticeFixResponseAction404,
221+
wantErr: nil,
212222
},
213223
}
214224

215225
c := gomock.NewController(t)
216226
defer c.Finish()
217227
mockListenerMgr := NewMockListenerManager(c)
218228
mockTargetGroupManager := NewMockTargetGroupManager(c)
219-
stack := core.NewDefaultStack(core.StackID{Name: "foo", Namespace: "bar"})
220229

221230
for _, tt := range tests {
222231
t.Run(tt.name, func(t *testing.T) {
232+
stack := core.NewDefaultStack(core.StackID{Name: "foo", Namespace: "bar"})
233+
modelListener := &model.Listener{
234+
ResourceMeta: core.NewResourceMeta(stack, "AWS:VPCServiceNetwork::Listener", "modelListener-id"),
235+
Spec: model.ListenerSpec{
236+
StackServiceId: "stack-svc-id",
237+
Protocol: tt.listenerProtocol,
238+
Port: 80,
239+
DefaultAction: tt.stackListenerDefaultAction,
240+
},
241+
}
242+
assert.NoError(t, stack.AddResource(modelListener))
243+
223244
l := &listenerSynthesizer{
224245
log: gwlog.FallbackLogger,
225246
listenerMgr: mockListenerMgr,
226247
tgManager: mockTargetGroupManager,
227248
stack: stack,
228249
}
229-
got, err := l.getLatticeListenerDefaultAction(context.TODO(), tt.listenerProtocol)
250+
got, err := l.getLatticeListenerDefaultAction(context.TODO(), modelListener)
230251

231252
assert.Equalf(t, tt.want, got, "getLatticeListenerDefaultAction() listenerProtocol: %v", tt.listenerProtocol)
232253
assert.Equal(t, tt.wantErr, err)
@@ -245,49 +266,56 @@ func Test_listenerSynthesizer_getLatticeListenerDefaultAction_TLS_PASSTHROUGH_Li
245266
mockListenerMgr := NewMockListenerManager(c)
246267
mockTargetGroupManager := NewMockTargetGroupManager(c)
247268
mockTargetGroupManager.EXPECT().ResolveRuleTgIds(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
248-
func(ctx context.Context, rule *model.Rule, stack core.Stack) error {
249-
rule.Spec.Action.TargetGroups[0].LatticeTgId = "lattice-service-export-tg-id-1"
250-
rule.Spec.Action.TargetGroups[1].LatticeTgId = "lattice-tg-id-2"
251-
rule.Spec.Action.TargetGroups[2].LatticeTgId = model.InvalidBackendRefTgId
269+
func(ctx context.Context, ruleAction *model.RuleAction, stack core.Stack) error {
270+
ruleAction.TargetGroups[0].LatticeTgId = "lattice-service-export-tg-id-1"
271+
ruleAction.TargetGroups[1].LatticeTgId = "lattice-tg-id-2"
272+
ruleAction.TargetGroups[2].LatticeTgId = model.InvalidBackendRefTgId
252273
return nil
253274

254275
})
255276
stack := core.NewDefaultStack(core.StackID{Name: "foo", Namespace: "bar"})
256-
stackRule := &model.Rule{
257-
ResourceMeta: core.NewResourceMeta(stack, "AWS:VPCServiceNetwork::Rule", "rule-id"),
258-
Spec: model.RuleSpec{
259-
Action: model.RuleAction{
260-
TargetGroups: []*model.RuleTargetGroup{
261-
{
262-
SvcImportTG: &model.SvcImportTargetGroup{
263-
K8SClusterName: "cluster-name",
264-
K8SServiceName: "svc-name",
265-
K8SServiceNamespace: "ns",
266-
VpcId: "vpc-id",
277+
278+
modelListener := &model.Listener{
279+
ResourceMeta: core.NewResourceMeta(stack, "AWS:VPCServiceNetwork::Listener", "modelListener-id"),
280+
Spec: model.ListenerSpec{
281+
StackServiceId: "stack-svc-id",
282+
Protocol: vpclattice.ListenerProtocolTlsPassthrough,
283+
Port: 80,
284+
DefaultAction: &model.DefaultAction{
285+
Forward: &model.RuleAction{
286+
TargetGroups: []*model.RuleTargetGroup{
287+
{
288+
SvcImportTG: &model.SvcImportTargetGroup{
289+
K8SClusterName: "cluster-name",
290+
K8SServiceName: "svc-name",
291+
K8SServiceNamespace: "ns",
292+
VpcId: "vpc-id",
293+
},
294+
Weight: 10,
295+
},
296+
{
297+
StackTargetGroupId: "lattice-tg-id-2",
298+
Weight: 30,
299+
},
300+
{
301+
StackTargetGroupId: model.InvalidBackendRefTgId,
302+
Weight: 60,
267303
},
268-
Weight: 10,
269-
},
270-
{
271-
StackTargetGroupId: "stack-tg-id-2",
272-
Weight: 30,
273-
},
274-
{
275-
StackTargetGroupId: model.InvalidBackendRefTgId,
276-
Weight: 60,
277304
},
278305
},
279306
},
280307
},
281308
}
282-
assert.NoError(t, stack.AddResource(stackRule))
309+
assert.NoError(t, stack.AddResource(modelListener))
310+
283311
l := &listenerSynthesizer{
284312
log: gwlog.FallbackLogger,
285313
listenerMgr: mockListenerMgr,
286314
tgManager: mockTargetGroupManager,
287315
stack: stack,
288316
}
289-
gotDefaultAction, err := l.getLatticeListenerDefaultAction(context.TODO(), tlspassthroughListenerProtocol)
290-
wantedListenerDefaultAction := &vpclattice.RuleAction{
317+
gotDefaultAction, err := l.getLatticeListenerDefaultAction(context.TODO(), modelListener)
318+
wantedLatticeListenerDefaultAction := &vpclattice.RuleAction{
291319
Forward: &vpclattice.ForwardAction{
292320
TargetGroups: []*vpclattice.WeightedTargetGroup{
293321
{
@@ -305,15 +333,15 @@ func Test_listenerSynthesizer_getLatticeListenerDefaultAction_TLS_PASSTHROUGH_Li
305333
},
306334
},
307335
}
308-
assert.Equalf(t, wantedListenerDefaultAction, gotDefaultAction, "getLatticeListenerDefaultAction() tlspassthroughListenerProtocol: %v", tlspassthroughListenerProtocol)
336+
assert.Equalf(t, wantedLatticeListenerDefaultAction, gotDefaultAction, "getLatticeListenerDefaultAction() tlspassthroughListenerProtocol: %v", tlspassthroughListenerProtocol)
309337
assert.Nil(t, err)
310338
})
311339

312340
t.Run("ResolveRuleTgIds failed, return err", func(t *testing.T) {
313341
mockListenerMgr := NewMockListenerManager(c)
314342
mockTargetGroupManager := NewMockTargetGroupManager(c)
315343
mockTargetGroupManager.EXPECT().ResolveRuleTgIds(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(
316-
func(ctx context.Context, rule *model.Rule, stack core.Stack) error {
344+
func(ctx context.Context, ruleAction *model.RuleAction, stack core.Stack) error {
317345
return fmt.Errorf("failed to resolve rule tg ids")
318346
})
319347
stack := core.NewDefaultStack(core.StackID{Name: "foo", Namespace: "bar"})
@@ -324,13 +352,31 @@ func Test_listenerSynthesizer_getLatticeListenerDefaultAction_TLS_PASSTHROUGH_Li
324352
},
325353
}
326354
assert.NoError(t, stack.AddResource(stackRule))
355+
modelListener := &model.Listener{
356+
ResourceMeta: core.NewResourceMeta(stack, "AWS:VPCServiceNetwork::Listener", "modelListener-id"),
357+
Spec: model.ListenerSpec{
358+
StackServiceId: "stack-svc-id",
359+
Protocol: vpclattice.ListenerProtocolTlsPassthrough,
360+
Port: 80,
361+
DefaultAction: &model.DefaultAction{
362+
Forward: &model.RuleAction{
363+
TargetGroups: []*model.RuleTargetGroup{
364+
{
365+
StackTargetGroupId: "lattice-tg-id-1",
366+
Weight: 100,
367+
},
368+
},
369+
},
370+
},
371+
},
372+
}
327373
l := &listenerSynthesizer{
328374
log: gwlog.FallbackLogger,
329375
listenerMgr: mockListenerMgr,
330376
tgManager: mockTargetGroupManager,
331377
stack: stack,
332378
}
333-
gotDefaultAction, err := l.getLatticeListenerDefaultAction(context.TODO(), tlspassthroughListenerProtocol)
379+
gotDefaultAction, err := l.getLatticeListenerDefaultAction(context.TODO(), modelListener)
334380
assert.Nil(t, gotDefaultAction)
335381
assert.NotNil(t, err)
336382

pkg/deploy/lattice/rule_synthesizer.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77

88
"github.com/aws/aws-sdk-go/aws"
9-
"github.com/aws/aws-sdk-go/service/vpclattice"
109

1110
"github.com/aws/aws-application-networking-k8s/pkg/model/core"
1211
model "github.com/aws/aws-application-networking-k8s/pkg/model/lattice"
@@ -82,12 +81,7 @@ func (r *ruleSynthesizer) createOrUpdateRules(ctx context.Context, rule *model.R
8281
return err
8382
}
8483

85-
if stackListener.Spec.Protocol == vpclattice.ListenerProtocolTlsPassthrough {
86-
r.log.Debugf("Skip updating rule=%v, since TLS_PASSTHROUGH listener can only have one default action and without any other additional rule", *rule)
87-
return nil
88-
}
89-
90-
err = r.tgManager.ResolveRuleTgIds(ctx, rule, r.stack)
84+
err = r.tgManager.ResolveRuleTgIds(ctx, &rule.Spec.Action, r.stack)
9185
if err != nil {
9286
return err
9387
}

pkg/deploy/lattice/rule_synthesizer_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func Test_SynthesizeRule(t *testing.T) {
4949
StackListenerId: l.ID(),
5050
Priority: 1,
5151
CreateTime: time.Time{},
52+
Action: model.RuleAction{},
5253
},
5354
Status: nil,
5455
}
@@ -72,7 +73,7 @@ func Test_SynthesizeRule(t *testing.T) {
7273
Id: aws.String("rule-id"),
7374
},
7475
}, nil)
75-
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, r, stack).Return(nil)
76+
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, &r.Spec.Action, stack).Return(nil)
7677
rs := NewRuleSynthesizer(gwlog.FallbackLogger, mockRuleMgr, mockTgMgr, stack)
7778
rs.Synthesize(ctx)
7879
})
@@ -99,7 +100,7 @@ func Test_SynthesizeRule(t *testing.T) {
99100
}, nil)
100101

101102
mockRuleMgr.EXPECT().Delete(ctx, "delete-rule-id", "svc-id", "listener-id").Return(nil)
102-
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, r, stack).Return(nil)
103+
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, &r.Spec.Action, stack).Return(nil)
103104

104105
rs := NewRuleSynthesizer(gwlog.FallbackLogger, mockRuleMgr, mockTgMgr, stack)
105106
rs.Synthesize(ctx)
@@ -128,7 +129,7 @@ func Test_SynthesizeRule(t *testing.T) {
128129
assert.Equal(t, 1, len(rules))
129130
return nil
130131
})
131-
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, r, stack).Return(nil)
132+
mockTgMgr.EXPECT().ResolveRuleTgIds(ctx, &r.Spec.Action, stack).Return(nil)
132133

133134
rs := NewRuleSynthesizer(gwlog.FallbackLogger, mockRuleMgr, mockTgMgr, stack)
134135
rs.Synthesize(ctx)

pkg/deploy/lattice/target_group_manager.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type TargetGroupManager interface {
2727
List(ctx context.Context) ([]tgListOutput, error)
2828
IsTargetGroupMatch(ctx context.Context, modelTg *model.TargetGroup, latticeTg *vpclattice.TargetGroupSummary,
2929
latticeTags *model.TargetGroupTagFields) (bool, error)
30-
ResolveRuleTgIds(ctx context.Context, modelRule *model.Rule, stack core.Stack) error
30+
ResolveRuleTgIds(ctx context.Context, modelRuleAction *model.RuleAction, stack core.Stack) error
3131
}
3232

3333
type defaultTargetGroupManager struct {
@@ -456,12 +456,12 @@ func (s *defaultTargetGroupManager) findSvcExportTG(ctx context.Context, svcImpo
456456
}
457457

458458
// ResolveRuleTgIds populates all target group ids in the rule's actions
459-
func (s *defaultTargetGroupManager) ResolveRuleTgIds(ctx context.Context, modelRule *model.Rule, stack core.Stack) error {
460-
if len(modelRule.Spec.Action.TargetGroups) == 0 {
461-
s.log.Debugf("no target groups to resolve for rule %d", modelRule.Spec.Priority)
459+
func (s *defaultTargetGroupManager) ResolveRuleTgIds(ctx context.Context, ruleAction *model.RuleAction, stack core.Stack) error {
460+
if len(ruleAction.TargetGroups) == 0 {
461+
s.log.Debugf("no target groups to resolve for rule")
462462
return nil
463463
}
464-
for i, ruleActionTg := range modelRule.Spec.Action.TargetGroups {
464+
for i, ruleActionTg := range ruleAction.TargetGroups {
465465
if ruleActionTg.StackTargetGroupId == "" && ruleActionTg.SvcImportTG == nil && ruleActionTg.LatticeTgId == "" {
466466
return errors.New("rule TG is missing a required target group identifier")
467467
}

0 commit comments

Comments
 (0)