Skip to content

Commit 3a4327b

Browse files
committed
documentation, tests
1 parent d9e4328 commit 3a4327b

File tree

8 files changed

+273
-5
lines changed

8 files changed

+273
-5
lines changed

docs/guide/gateway/gateway.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,34 @@ the target group will not be materialized on any ALBs that the route attaches to
130130
An [503 Fixed Response](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/API_FixedResponseActionConfig.html)
131131
will be added to any Listener Rules that would have referenced the invalid backend.
132132

133+
## Specify out-of-band Target Groups
134+
135+
Use an existing AWS Target Group with a Gateway-managed Load Balancer.
136+
This lets you integrate or migrate legacy applications that are already
137+
registered with an AWS Target Group outside the controller's lifecycle.
138+
139+
```yaml
140+
apiVersion: gateway.networking.k8s.io/v1alpha2
141+
kind: TCPRoute
142+
metadata:
143+
name: tcproute
144+
namespace: example-ns
145+
spec:
146+
parentRefs:
147+
- group: gateway.networking.k8s.io
148+
kind: Gateway
149+
name: nlb-gw
150+
sectionName: tls
151+
rules:
152+
- backendRefs:
153+
- group: ""
154+
kind: TargetGroupName
155+
name: test-gw-import123
156+
weight: 1
157+
```
158+
159+
This support exists for all route types managed by the controller.
160+
161+
162+
133163

pkg/gateway/model/model_build_target_group_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package model
22

33
import (
4+
"context"
45
awssdk "github.com/aws/aws-sdk-go-v2/aws"
6+
"github.com/pkg/errors"
57
"github.com/stretchr/testify/assert"
68
corev1 "k8s.io/api/core/v1"
79
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -15,6 +17,7 @@ import (
1517
elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
1618
elbv2modelk8s "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2/k8s"
1719
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_constants"
20+
"sigs.k8s.io/aws-load-balancer-controller/pkg/shared_utils"
1821
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
1922
"testing"
2023
)
@@ -2071,6 +2074,30 @@ func Test_buildTargetGroupBindingMultiClusterFlag(t *testing.T) {
20712074
assert.True(t, builder.buildTargetGroupBindingMultiClusterFlag(props))
20722075
}
20732076

2077+
func Test_buildTargetGroupFromStaticName(t *testing.T) {
2078+
2079+
mockMapper := &shared_utils.MockTargetGroupARNMapper{
2080+
ARN: "my-arn",
2081+
Error: nil,
2082+
}
2083+
impl := targetGroupBuilderImpl{
2084+
targetGroupNameToArnMapper: mockMapper,
2085+
}
2086+
2087+
cfg := routeutils.LiteralTargetGroupConfig{Name: "foo"}
2088+
2089+
result, err := impl.buildTargetGroupFromStaticName(cfg)
2090+
assert.Nil(t, err)
2091+
2092+
resultArn, _ := result.Resolve(context.Background())
2093+
assert.Equal(t, "my-arn", resultArn)
2094+
2095+
mockMapper.Error = errors.New("bad")
2096+
2097+
_, err = impl.buildTargetGroupFromStaticName(cfg)
2098+
assert.Error(t, err)
2099+
}
2100+
20742101
func protocolPtr(protocol elbv2gw.Protocol) *elbv2gw.Protocol {
20752102
return &protocol
20762103
}

pkg/gateway/referencecounter/service_reference_counter.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,17 @@ func (t *serviceReferenceCounter) updateRefCount(svcs sets.Set[types.NamespacedN
6767
func (t *serviceReferenceCounter) IsEligibleForRemoval(svcName types.NamespacedName, expectedGateways []types.NamespacedName) bool {
6868
t.mutex.RLock()
6969
defer t.mutex.RUnlock()
70-
v, ok := t.refCount[svcName]
70+
_, ok := t.refCount[svcName]
7171
// If we have a ref count for this service, we can't remove it.
7272
// updateRefCount should always remove 0 entry services.
7373
if ok {
74-
t.logger.Info("Got a ref count!", "ref", v)
7574
return false
7675
}
7776

7877
// Next we check if the Gateway cache is correctly populated. This prevents premature removal of items
7978
// when the cache is not warm.
8079
for _, gw := range expectedGateways {
8180
if _, exists := t.relations[gw]; !exists {
82-
t.logger.Info("Missing relation", "gateway", gw)
8381
return false
8482
}
8583
}

pkg/gateway/routeutils/backend_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,61 @@ func TestCommonBackendLoader_Service(t *testing.T) {
403403
}
404404
}
405405

406+
func TestCommonBackendLoader_TargetGroupName(t *testing.T) {
407+
testCases := []struct {
408+
name string
409+
expectWarning bool
410+
expectFatal bool
411+
backendRef gwv1.BackendRef
412+
routeIdentifier types.NamespacedName
413+
expected *LiteralTargetGroupConfig
414+
}{
415+
{
416+
name: "invalid backend kind",
417+
expectWarning: true,
418+
backendRef: gwv1.BackendRef{
419+
BackendObjectReference: gwv1.BackendObjectReference{
420+
Kind: (*gwv1.Kind)(awssdk.String("invalid")),
421+
},
422+
},
423+
},
424+
{
425+
name: "valid name",
426+
backendRef: gwv1.BackendRef{
427+
BackendObjectReference: gwv1.BackendObjectReference{
428+
Kind: (*gwv1.Kind)(awssdk.String(TargetGroupNameBackend)),
429+
Name: "foo",
430+
},
431+
},
432+
expected: &LiteralTargetGroupConfig{
433+
Name: "foo",
434+
},
435+
},
436+
}
437+
438+
for _, tc := range testCases {
439+
t.Run(tc.name, func(t *testing.T) {
440+
k8sClient := testutils.GenerateTestClient()
441+
442+
result, warningErr, fatalErr := commonBackendLoader(context.Background(), k8sClient, tc.backendRef, tc.routeIdentifier, HTTPRouteKind)
443+
444+
if tc.expectWarning {
445+
assert.Error(t, warningErr)
446+
assert.NoError(t, fatalErr)
447+
} else if tc.expectFatal {
448+
assert.Error(t, fatalErr)
449+
assert.NoError(t, warningErr)
450+
} else {
451+
assert.NoError(t, warningErr)
452+
assert.NoError(t, fatalErr)
453+
454+
assert.Nil(t, result.ServiceBackend)
455+
assert.Equal(t, tc.expected, result.LiteralTargetGroup)
456+
}
457+
})
458+
}
459+
}
460+
406461
func Test_lookUpTargetGroupConfiguration(t *testing.T) {
407462
testCases := []struct {
408463
name string

pkg/gateway/routeutils/generic_route_rule.go

Lines changed: 0 additions & 1 deletion
This file was deleted.

pkg/gateway/routeutils/tcp_udp_route.go

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package shared_utils
2+
3+
import (
4+
"context"
5+
"k8s.io/apimachinery/pkg/util/cache"
6+
)
7+
8+
type MockTargetGroupARNMapper struct {
9+
ARN string
10+
Error error
11+
}
12+
13+
func (m *MockTargetGroupARNMapper) GetArnByName(_ context.Context, _ string) (string, error) {
14+
return m.ARN, m.Error
15+
}
16+
17+
func (m *MockTargetGroupARNMapper) GetCache() *cache.Expiring {
18+
return nil
19+
}
20+
21+
var _ TargetGroupARNMapper = &MockTargetGroupARNMapper{}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package shared_utils
2+
3+
import (
4+
"context"
5+
"github.com/aws/aws-sdk-go-v2/aws"
6+
elbv2sdk "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
7+
elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
8+
"github.com/golang/mock/gomock"
9+
"github.com/pkg/errors"
10+
"github.com/stretchr/testify/assert"
11+
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
12+
"testing"
13+
"time"
14+
)
15+
16+
func Test_TargetGroupARNMapper(t *testing.T) {
17+
type describeTargetGroupCall struct {
18+
req *elbv2sdk.DescribeTargetGroupsInput
19+
resp []elbv2types.TargetGroup
20+
err error
21+
}
22+
23+
type cachedItem struct {
24+
name string
25+
arn string
26+
}
27+
28+
testCases := []struct {
29+
name string
30+
tgName string
31+
calls []describeTargetGroupCall
32+
cachedItems []cachedItem
33+
expected string
34+
expectErr bool
35+
}{
36+
{
37+
name: "cold cache",
38+
tgName: "foo",
39+
calls: []describeTargetGroupCall{
40+
{
41+
req: &elbv2sdk.DescribeTargetGroupsInput{
42+
Names: []string{"foo"},
43+
},
44+
resp: []elbv2types.TargetGroup{
45+
{
46+
TargetGroupArn: aws.String("my-arn"),
47+
},
48+
},
49+
},
50+
},
51+
expected: "my-arn",
52+
},
53+
{
54+
name: "warm cache",
55+
tgName: "foo",
56+
calls: []describeTargetGroupCall{},
57+
cachedItems: []cachedItem{
58+
{
59+
name: "foo",
60+
arn: "my-arn",
61+
},
62+
},
63+
expected: "my-arn",
64+
},
65+
{
66+
name: "warm cache but wrong name",
67+
tgName: "foo",
68+
calls: []describeTargetGroupCall{
69+
{
70+
req: &elbv2sdk.DescribeTargetGroupsInput{
71+
Names: []string{"foo"},
72+
},
73+
resp: []elbv2types.TargetGroup{
74+
{
75+
TargetGroupArn: aws.String("my-arn"),
76+
},
77+
},
78+
},
79+
},
80+
cachedItems: []cachedItem{
81+
{
82+
name: "baz",
83+
arn: "other-warn",
84+
},
85+
},
86+
expected: "my-arn",
87+
},
88+
{
89+
name: "error",
90+
tgName: "foo",
91+
calls: []describeTargetGroupCall{
92+
{
93+
req: &elbv2sdk.DescribeTargetGroupsInput{
94+
Names: []string{"foo"},
95+
},
96+
resp: []elbv2types.TargetGroup{
97+
{
98+
TargetGroupArn: aws.String("my-arn"),
99+
},
100+
},
101+
err: errors.New("error"),
102+
},
103+
},
104+
cachedItems: []cachedItem{
105+
{
106+
name: "baz",
107+
arn: "other-warn",
108+
},
109+
},
110+
expectErr: true,
111+
},
112+
}
113+
114+
for _, tc := range testCases {
115+
t.Run(tc.name, func(t *testing.T) {
116+
ctrl := gomock.NewController(t)
117+
defer ctrl.Finish()
118+
elbv2Client := services.NewMockELBV2(ctrl)
119+
mapper := NewTargetGroupNameToArnMapper(elbv2Client)
120+
121+
for _, call := range tc.calls {
122+
elbv2Client.EXPECT().DescribeTargetGroupsAsList(gomock.Any(), call.req).Return(call.resp, call.err)
123+
}
124+
125+
for _, ci := range tc.cachedItems {
126+
mapper.GetCache().Set(ci.name, ci.arn, time.Minute)
127+
}
128+
129+
result, err := mapper.GetArnByName(context.Background(), tc.tgName)
130+
131+
if tc.expectErr {
132+
assert.Error(t, err)
133+
} else {
134+
assert.NoError(t, err)
135+
assert.Equal(t, tc.expected, result)
136+
}
137+
})
138+
}
139+
}

0 commit comments

Comments
 (0)