Skip to content

Commit 5ab8d81

Browse files
authored
Merge pull request #4205 from zac-nixon/znixon/gw-integ
[gw api] Add Gateway API integ framework
2 parents a21f588 + e4f3aed commit 5ab8d81

18 files changed

+1092
-72
lines changed

controllers/gateway/utils.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ func updateGatewayClassLastProcessedConfig(ctx context.Context, k8sClient client
3535
return nil
3636
}
3737

38+
if gwClass.Annotations == nil {
39+
gwClass.Annotations = make(map[string]string)
40+
}
41+
3842
gwClassOld := gwClass.DeepCopy()
3943
gwClass.Annotations[gatewayClassAnnotationLastProcessedConfig] = calculatedVersion
4044
gwClass.Annotations[gatewayClassAnnotationLastProcessedConfigTimestamp] = strconv.FormatInt(time.Now().Unix(), 10)

pkg/gateway/routeutils/tcp.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ func (tcpRoute *tcpRouteDescription) loadAttachedRules(ctx context.Context, k8sC
7373

7474
convertedRules = append(convertedRules, convertTCPRouteRule(&rule, convertedBackends))
7575
}
76-
7776
tcpRoute.rules = convertedRules
7877
return tcpRoute, nil
7978
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package gateway
2+
3+
import (
4+
"context"
5+
corev1 "k8s.io/api/core/v1"
6+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
7+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
8+
"sigs.k8s.io/aws-load-balancer-controller/test/framework"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
11+
)
12+
13+
type ALBInstanceTestStack struct {
14+
albResourceStack *albResourceStack
15+
}
16+
17+
func (s *ALBInstanceTestStack) Deploy(ctx context.Context, f *framework.Framework, spec elbv2gw.LoadBalancerConfigurationSpec) error {
18+
dp := buildDeploymentSpec(f.Options.TestImageRegistry)
19+
svc := buildServiceSpec()
20+
gwc := buildGatewayClassSpec("gateway.k8s.aws/alb")
21+
gw := buildBasicGatewaySpec(gwc, gwv1.HTTPProtocolType)
22+
lbc := buildLoadBalancerConfig(spec)
23+
httpr := buildHTTPRoute()
24+
s.albResourceStack = newALBResourceStack(dp, svc, gwc, gw, lbc, httpr, "service-instance-e2e", false)
25+
26+
return s.albResourceStack.Deploy(ctx, f)
27+
}
28+
29+
func (s *ALBInstanceTestStack) ScaleDeployment(ctx context.Context, f *framework.Framework, numReplicas int32) error {
30+
return s.albResourceStack.ScaleDeployment(ctx, f, numReplicas)
31+
}
32+
33+
func (s *ALBInstanceTestStack) Cleanup(ctx context.Context, f *framework.Framework) {
34+
_ = f.K8sClient.Delete(ctx, s.albResourceStack.httpr)
35+
s.albResourceStack.Cleanup(ctx, f)
36+
}
37+
38+
func (s *ALBInstanceTestStack) GetLoadBalancerIngressHostName() string {
39+
return s.albResourceStack.GetLoadBalancerIngressHostname()
40+
}
41+
42+
func (s *ALBInstanceTestStack) GetWorkerNodes(ctx context.Context, f *framework.Framework) ([]corev1.Node, error) {
43+
allNodes := &corev1.NodeList{}
44+
err := f.K8sClient.List(ctx, allNodes)
45+
if err != nil {
46+
return nil, err
47+
}
48+
nodeList := []corev1.Node{}
49+
for _, node := range allNodes.Items {
50+
if _, notarget := node.Labels["node.kubernetes.io/exclude-from-external-load-balancers"]; !notarget {
51+
nodeList = append(nodeList, node)
52+
}
53+
}
54+
return nodeList, nil
55+
}
56+
57+
func (s *ALBInstanceTestStack) ApplyNodeLabels(ctx context.Context, f *framework.Framework, node *corev1.Node, labels map[string]string) error {
58+
f.Logger.Info("applying node labels", "node", k8s.NamespacedName(node))
59+
oldNode := node.DeepCopy()
60+
for key, value := range labels {
61+
node.Labels[key] = value
62+
}
63+
if err := f.K8sClient.Patch(ctx, node, client.MergeFrom(oldNode)); err != nil {
64+
f.Logger.Info("failed to update node", "node", k8s.NamespacedName(node))
65+
return err
66+
}
67+
return nil
68+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package gateway
2+
3+
import (
4+
"context"
5+
"fmt"
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
9+
"sigs.k8s.io/aws-load-balancer-controller/test/framework/http"
10+
"sigs.k8s.io/aws-load-balancer-controller/test/framework/utils"
11+
"sigs.k8s.io/aws-load-balancer-controller/test/framework/verifier"
12+
)
13+
14+
var _ = Describe("test k8s alb gateway reconciled by the aws load balancer controller", func() {
15+
var (
16+
ctx context.Context
17+
stack ALBInstanceTestStack
18+
dnsName string
19+
lbARN string
20+
)
21+
BeforeEach(func() {
22+
if !tf.Options.EnableGatewayTests {
23+
Skip("Skipping gateway tests")
24+
}
25+
ctx = context.Background()
26+
stack = ALBInstanceTestStack{}
27+
})
28+
AfterEach(func() {
29+
stack.Cleanup(ctx, tf)
30+
})
31+
Context("with ALB instance target configuration", func() {
32+
BeforeEach(func() {})
33+
It("should provision internet-facing load balancer resources", func() {
34+
interf := elbv2gw.LoadBalancerSchemeInternetFacing
35+
lbcSpec := elbv2gw.LoadBalancerConfigurationSpec{
36+
Scheme: &interf,
37+
}
38+
By("deploying stack", func() {
39+
err := stack.Deploy(ctx, tf, lbcSpec)
40+
Expect(err).NotTo(HaveOccurred())
41+
})
42+
43+
By("checking service status for lb dns name", func() {
44+
dnsName = stack.GetLoadBalancerIngressHostName()
45+
Expect(dnsName).ToNot(BeEmpty())
46+
})
47+
48+
By("querying AWS loadbalancer from the dns name", func() {
49+
var err error
50+
lbARN, err = tf.LBManager.FindLoadBalancerByDNSName(ctx, dnsName)
51+
Expect(err).NotTo(HaveOccurred())
52+
Expect(lbARN).ToNot(BeEmpty())
53+
})
54+
55+
By("verifying AWS loadbalancer resources", func() {
56+
nodeList, err := stack.GetWorkerNodes(ctx, tf)
57+
Expect(err).ToNot(HaveOccurred())
58+
err = verifier.VerifyAWSLoadBalancerResources(ctx, tf, lbARN, verifier.LoadBalancerExpectation{
59+
Type: "application",
60+
Scheme: "internet-facing",
61+
TargetType: "instance",
62+
Listeners: stack.albResourceStack.getListenersPortMap(),
63+
TargetGroups: stack.albResourceStack.getTargetGroupNodePortMap(),
64+
NumTargets: len(nodeList),
65+
TargetGroupHC: &verifier.TargetGroupHC{
66+
Protocol: "HTTP",
67+
Port: "traffic-port",
68+
Path: "/",
69+
Interval: 15,
70+
Timeout: 5,
71+
HealthyThreshold: 3,
72+
UnhealthyThreshold: 3,
73+
},
74+
})
75+
Expect(err).NotTo(HaveOccurred())
76+
})
77+
By("waiting for target group targets to be healthy", func() {
78+
nodeList, err := stack.GetWorkerNodes(ctx, tf)
79+
Expect(err).ToNot(HaveOccurred())
80+
err = verifier.WaitUntilTargetsAreHealthy(ctx, tf, lbARN, len(nodeList))
81+
Expect(err).NotTo(HaveOccurred())
82+
})
83+
By("waiting until DNS name is available", func() {
84+
err := utils.WaitUntilDNSNameAvailable(ctx, dnsName)
85+
Expect(err).NotTo(HaveOccurred())
86+
})
87+
By("sending http request to the lb", func() {
88+
url := fmt.Sprintf("http://%v/any-path", dnsName)
89+
err := tf.HTTPVerifier.VerifyURL(url, http.ResponseCodeMatches(200))
90+
Expect(err).NotTo(HaveOccurred())
91+
})
92+
})
93+
})
94+
})
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package gateway
2+
3+
import (
4+
"context"
5+
appsv1 "k8s.io/api/apps/v1"
6+
corev1 "k8s.io/api/core/v1"
7+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
8+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
9+
"sigs.k8s.io/aws-load-balancer-controller/test/framework"
10+
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
11+
)
12+
13+
func newALBResourceStack(dp *appsv1.Deployment, svc *corev1.Service, gwc *gwv1.GatewayClass, gw *gwv1.Gateway, lbc *elbv2gw.LoadBalancerConfiguration, httpr *gwv1.HTTPRoute, baseName string, enablePodReadinessGate bool) *albResourceStack {
14+
15+
commonStack := newCommonResourceStack(dp, svc, gwc, gw, lbc, baseName, enablePodReadinessGate)
16+
return &albResourceStack{
17+
httpr: httpr,
18+
commonStack: commonStack,
19+
}
20+
}
21+
22+
// resourceStack containing the deployment and service resources
23+
type albResourceStack struct {
24+
commonStack *commonResourceStack
25+
httpr *gwv1.HTTPRoute
26+
}
27+
28+
func (s *albResourceStack) Deploy(ctx context.Context, f *framework.Framework) error {
29+
return s.commonStack.Deploy(ctx, f, func(ctx context.Context, f *framework.Framework, namespace string) error {
30+
s.httpr.Namespace = namespace
31+
return s.createHTTPRoute(ctx, f)
32+
})
33+
}
34+
35+
func (s *albResourceStack) ScaleDeployment(ctx context.Context, f *framework.Framework, numReplicas int32) error {
36+
return s.commonStack.ScaleDeployment(ctx, f, numReplicas)
37+
}
38+
39+
func (s *albResourceStack) Cleanup(ctx context.Context, f *framework.Framework) {
40+
s.commonStack.Cleanup(ctx, f)
41+
}
42+
43+
func (s *albResourceStack) GetLoadBalancerIngressHostname() string {
44+
return s.commonStack.GetLoadBalancerIngressHostname()
45+
}
46+
47+
func (s *albResourceStack) GetStackName() string {
48+
return s.commonStack.GetStackName()
49+
}
50+
51+
func (s *albResourceStack) getListenersPortMap() map[string]string {
52+
return s.commonStack.getListenersPortMap()
53+
}
54+
55+
func (s *albResourceStack) getTargetGroupNodePortMap() map[string]string {
56+
res := s.commonStack.getTargetGroupNodePortMap()
57+
58+
for p := range res {
59+
// TODO - kinda a hack to get HTTP to work.
60+
if res[p] == string(corev1.ProtocolTCP) {
61+
res[p] = "HTTP"
62+
}
63+
}
64+
65+
return res
66+
}
67+
68+
func (s *albResourceStack) getHealthCheckNodePort() string {
69+
return s.commonStack.getHealthCheckNodePort()
70+
}
71+
72+
func (s *albResourceStack) waitUntilDeploymentReady(ctx context.Context, f *framework.Framework) error {
73+
return s.commonStack.waitUntilDeploymentReady(ctx, f)
74+
}
75+
76+
func (s *albResourceStack) createHTTPRoute(ctx context.Context, f *framework.Framework) error {
77+
f.Logger.Info("creating http route", "httpr", k8s.NamespacedName(s.httpr))
78+
return f.K8sClient.Create(ctx, s.httpr)
79+
}
80+
81+
func (s *albResourceStack) deleteHTTPRoute(ctx context.Context, f *framework.Framework) error {
82+
return f.K8sClient.Delete(ctx, s.httpr)
83+
}

0 commit comments

Comments
 (0)