Skip to content
277 changes: 277 additions & 0 deletions test/e2e/gateway/alb_nlb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
package gateway

import (
"context"
"fmt"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
"sigs.k8s.io/aws-load-balancer-controller/test/framework/http"
"sigs.k8s.io/aws-load-balancer-controller/test/framework/verifier"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
gwbeta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
"strings"
"time"
)

var _ = Describe("test combined ALB and NLB gateways with HTTPRoute and TCPRoute", func() {
var (
ctx context.Context
albStack ALBTestStack
nlbStack NLBTestStack
)

BeforeEach(func() {
if !tf.Options.EnableGatewayTests {
Skip("Skipping gateway tests")
}
ctx = context.Background()
albStack = ALBTestStack{}
nlbStack = NLBTestStack{}
})

AfterEach(func() {
albStack.Cleanup(ctx, tf)
nlbStack.Cleanup(ctx, tf)
})

Context("with ALB and NLB gateways using IP targets", func() {
var albDnsName string
var albARN string
var nlbDnsName string
var nlbARN string
var refGrant *gwbeta1.ReferenceGrant
It("should provision both ALB and NLB load balancers with HTTPRoute and TCPRoute", func() {
// ALB Configuration
albInterf := elbv2gw.LoadBalancerSchemeInternal
albLbcSpec := elbv2gw.LoadBalancerConfigurationSpec{
Scheme: &albInterf,
}

// NLB Configuration
nlbInterf := elbv2gw.LoadBalancerSchemeInternetFacing
nlbLbcSpec := elbv2gw.LoadBalancerConfigurationSpec{
Scheme: &nlbInterf,
}

// Configure TLS for both if certificates are available
var hasTLS bool
if len(tf.Options.CertificateARNs) > 0 {
cert := strings.Split(tf.Options.CertificateARNs, ",")[0]

// ALB HTTPS listener
albLsConfig := elbv2gw.ListenerConfiguration{
ProtocolPort: "HTTPS:443",
DefaultCertificate: &cert,
}
albLbcSpec.ListenerConfigurations = &[]elbv2gw.ListenerConfiguration{albLsConfig}
hasTLS = true
}

// IP target type for both
ipTargetType := elbv2gw.TargetTypeIP
tgSpec := elbv2gw.TargetGroupConfigurationSpec{
DefaultConfiguration: elbv2gw.TargetGroupProps{
TargetType: &ipTargetType,
},
}
lrcSpec := elbv2gw.ListenerRuleConfigurationSpec{}

// ALB Gateway listeners
albGwListeners := []gwv1.Listener{
{
Name: "http80",
Port: 80,
Protocol: gwv1.HTTPProtocolType,
},
}
if hasTLS {
albGwListeners = append(albGwListeners, gwv1.Listener{
Name: "https443",
Port: 443,
Protocol: gwv1.HTTPSProtocolType,
})
}

// HTTPRoute for ALB
httpr := buildHTTPRoute([]string{}, []gwv1.HTTPRouteRule{}, nil)

By("deploying ALB stack", func() {
err := albStack.DeployHTTP(ctx, nil, tf, albGwListeners, []*gwv1.HTTPRoute{httpr}, albLbcSpec, tgSpec, lrcSpec, nil, true)
Expect(err).NotTo(HaveOccurred())
})

By("deploying NLB stack", func() {
err := nlbStack.DeployFrontendNLB(ctx, albStack, tf, nlbLbcSpec, hasTLS, true)
Expect(err).NotTo(HaveOccurred())
})
By("checking alb gateway status for lb dns name", func() {
time.Sleep(2 * time.Minute)
albDnsName = albStack.GetLoadBalancerIngressHostName()
Expect(albDnsName).ToNot(BeEmpty())
})
By("querying AWS loadbalancer from the dns name", func() {
var err error
albARN, err = tf.LBManager.FindLoadBalancerByDNSName(ctx, albDnsName)
Expect(err).NotTo(HaveOccurred())
Expect(albARN).ToNot(BeEmpty())
})
By("checking nlb gateway status for lb dns name", func() {
nlbDnsName = nlbStack.GetLoadBalancerIngressHostName()
Expect(nlbDnsName).ToNot(BeEmpty())
})
By("querying AWS loadbalancer from the dns name", func() {
var err error
nlbARN, err = tf.LBManager.FindLoadBalancerByDNSName(ctx, nlbDnsName)
Expect(err).NotTo(HaveOccurred())
Expect(nlbARN).ToNot(BeEmpty())
})
By("verify alb configuration", func() {
expectedTargetGroups := []verifier.ExpectedTargetGroup{
{
Protocol: "HTTP",
Port: 80,
NumTargets: int(*albStack.albResourceStack.commonStack.dps[0].Spec.Replicas),
TargetType: "ip",
TargetGroupHC: DEFAULT_ALB_TARGET_GROUP_HC,
},
}

listenerPortMap := albStack.albResourceStack.getListenersPortMap()

err := verifier.VerifyAWSLoadBalancerResources(ctx, tf, albARN, verifier.LoadBalancerExpectation{
Type: "application",
Scheme: "internal",
Listeners: listenerPortMap,
TargetGroups: expectedTargetGroups,
})
Expect(err).NotTo(HaveOccurred())
})
By("verify nlb configuration", func() {
// No ref grants, means no tg or listener.
expectedTargetGroups := []verifier.ExpectedTargetGroup{}

listenerPortMap := map[string]string{}

err := verifier.VerifyAWSLoadBalancerResources(ctx, tf, nlbARN, verifier.LoadBalancerExpectation{
Type: "network",
Scheme: "internet-facing",
Listeners: listenerPortMap,
TargetGroups: expectedTargetGroups,
})
Expect(err).NotTo(HaveOccurred())
})
By("deploy reference grant that allows nlb <-> alb attachment", func() {
var err error
refGrant, err = nlbStack.CreateFENLBReferenceGrant(ctx, tf, albStack.albResourceStack.commonStack.ns)
Expect(err).NotTo(HaveOccurred())
time.Sleep(2 * time.Minute)
})
By("deploy reference grant that allows nlb <-> alb attachment", func() {
// No ref grants, means no tg or listener.
expectedTargetGroups := []verifier.ExpectedTargetGroup{
{
Protocol: "TCP",
Port: 80,
NumTargets: 1,
TargetType: "alb",
TargetGroupHC: &verifier.TargetGroupHC{
Protocol: "HTTP",
Port: "traffic-port",
Path: "/",
Interval: 15,
Timeout: 5,
HealthyThreshold: 3,
UnhealthyThreshold: 3,
},
},
}

if hasTLS {
expectedTargetGroups = append(expectedTargetGroups, verifier.ExpectedTargetGroup{
Protocol: "TCP",
Port: 443,
NumTargets: 1,
TargetType: "alb",
TargetGroupHC: &verifier.TargetGroupHC{
Protocol: "HTTPS",
Port: "traffic-port",
Path: "/",
Interval: 15,
Timeout: 5,
HealthyThreshold: 3,
UnhealthyThreshold: 3,
},
})
}

fmt.Printf("%+v\n", refGrant)

listenerPortMap := nlbStack.nlbResourceStack.getListenersPortMap()

err := verifier.VerifyAWSLoadBalancerResources(ctx, tf, nlbARN, verifier.LoadBalancerExpectation{
Type: "network",
Scheme: "internet-facing",
Listeners: listenerPortMap,
TargetGroups: expectedTargetGroups,
})
Expect(err).NotTo(HaveOccurred())
})
By("verify port 80 works", func() {
url := fmt.Sprintf("http://%v/any-path", nlbDnsName)
err := tf.HTTPVerifier.VerifyURL(url, http.ResponseCodeMatches(200))
Expect(err).NotTo(HaveOccurred())
})
if hasTLS {
By("verify port 443 works", func() {
url := fmt.Sprintf("https://%v/any-path", nlbDnsName)
urlOptions := http.URLOptions{
InsecureSkipVerify: true,
}
err := tf.HTTPVerifier.VerifyURLWithOptions(url, urlOptions, http.ResponseCodeMatches(200))
Expect(err).NotTo(HaveOccurred())
})
}
By("remove reference grant should remove nlb listener but keep alb listener intact", func() {
err := tf.K8sClient.Delete(ctx, refGrant)
Expect(err).NotTo(HaveOccurred())
time.Sleep(2 * time.Minute)
})
By("verify alb configuration", func() {
expectedTargetGroups := []verifier.ExpectedTargetGroup{
{
Protocol: "HTTP",
Port: 80,
NumTargets: int(*albStack.albResourceStack.commonStack.dps[0].Spec.Replicas),
TargetType: "ip",
TargetGroupHC: DEFAULT_ALB_TARGET_GROUP_HC,
},
}

listenerPortMap := albStack.albResourceStack.getListenersPortMap()

err := verifier.VerifyAWSLoadBalancerResources(ctx, tf, albARN, verifier.LoadBalancerExpectation{
Type: "application",
Scheme: "internal",
Listeners: listenerPortMap,
TargetGroups: expectedTargetGroups,
})
Expect(err).NotTo(HaveOccurred())
})
By("verify nlb configuration", func() {
// No ref grants, means no tg or listener.
expectedTargetGroups := []verifier.ExpectedTargetGroup{}

listenerPortMap := map[string]string{}

err := verifier.VerifyAWSLoadBalancerResources(ctx, tf, nlbARN, verifier.LoadBalancerExpectation{
Type: "network",
Scheme: "internet-facing",
Listeners: listenerPortMap,
TargetGroups: expectedTargetGroups,
})
Expect(err).NotTo(HaveOccurred())
})
})
})
})
Loading