AlinsRan commented on code in PR #2500: URL: https://github.com/apache/apisix-ingress-controller/pull/2500#discussion_r2244462673
########## test/e2e/crds/v2/route.go: ########## @@ -1041,4 +1043,263 @@ spec: Expect(string(msg)).To(Equal(testMessage), "message content verification") }) }) + + Context("Test ApisixRoute with External Services", func() { + const ( + externalServiceName = "ext-httpbin" + upstreamName = "httpbin-upstream" + routeName = "httpbin-route" + ) + + createExternalService := func(externalName string) { + By(fmt.Sprintf("create ExternalName service: %s -> %s", externalServiceName, externalName)) + svcSpec := fmt.Sprintf(` +apiVersion: v1 +kind: Service +metadata: + name: %s +spec: + type: ExternalName + externalName: %s +`, externalServiceName, externalName) + err := s.CreateResourceFromString(svcSpec) + Expect(err).ShouldNot(HaveOccurred(), "creating ExternalName service") + } + + createApisixUpstream := func(externalType apiv2.ApisixUpstreamExternalType, name string) { + By(fmt.Sprintf("create ApisixUpstream: type=%s, name=%s", externalType, name)) + upstreamSpec := fmt.Sprintf(` +apiVersion: apisix.apache.org/v2 +kind: ApisixUpstream +metadata: + name: %s +spec: + externalNodes: + - type: %s + name: %s +`, upstreamName, externalType, name) + var upstream apiv2.ApisixUpstream + applier.MustApplyAPIv2( + types.NamespacedName{Namespace: s.Namespace(), Name: upstreamName}, + &upstream, + upstreamSpec, + ) + } + + createApisixRoute := func() { + By("create ApisixRoute referencing ApisixUpstream") + routeSpec := fmt.Sprintf(` +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + name: %s +spec: + ingressClassName: apisix + http: + - name: rule1 + match: + hosts: + - httpbin.org + paths: + - /ip + upstreams: + - name: %s +`, routeName, upstreamName) + var route apiv2.ApisixRoute + applier.MustApplyAPIv2( + types.NamespacedName{Namespace: s.Namespace(), Name: routeName}, + &route, + routeSpec, + ) + } + + createApisixRouteWithHostRewrite := func(host string) { + By("create ApisixRoute with host rewrite") + routeSpec := fmt.Sprintf(` +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + name: %s +spec: + ingressClassName: apisix + http: + - name: rule1 + match: + hosts: + - httpbin.org + paths: + - /ip + upstreams: + - name: %s + plugins: + - name: proxy-rewrite + enable: true + config: + host: %s +`, routeName, upstreamName, host) + var route apiv2.ApisixRoute + applier.MustApplyAPIv2( + types.NamespacedName{Namespace: s.Namespace(), Name: routeName}, + &route, + routeSpec, + ) + } + + verifyAccess := func() { + By("verify access to external service") + request := func() int { + return s.NewAPISIXClient().GET("/ip"). + WithHost("httpbin.org"). + Expect().Raw().StatusCode + } + Eventually(request).WithTimeout(30 * time.Second).ProbeEvery(2 * time.Second). + Should(Equal(http.StatusOK)) + } + + It("access third-party service directly", func() { + createApisixUpstream(apiv2.ExternalTypeDomain, "httpbin.org") + createApisixRoute() + verifyAccess() + }) + + It("access third-party service with host rewrite", func() { + createApisixUpstream(apiv2.ExternalTypeDomain, "httpbin.org") + createApisixRouteWithHostRewrite("httpbin.org") + verifyAccess() + }) + + It("access external domain via ExternalName service", func() { + createExternalService("httpbin.org") + createApisixUpstream(apiv2.ExternalTypeService, externalServiceName) + createApisixRoute() + verifyAccess() + }) + + It("access in-cluster service via ExternalName", func() { + By("create temporary httpbin service") + + By("get FQDN of temporary service") + fqdn := fmt.Sprintf("%s.%s.svc.cluster.local", "httpbin-service-e2e-test", s.Namespace()) + + By("setup external service and route") + createExternalService(fqdn) + createApisixUpstream(apiv2.ExternalTypeService, externalServiceName) + createApisixRoute() + verifyAccess() + }) + + Context("complex scenarios", func() { + It("multiple external services in one upstream", func() { + By("create ApisixUpstream with multiple external nodes") + upstreamSpec := ` +apiVersion: apisix.apache.org/v2 +kind: ApisixUpstream +metadata: + name: httpbin-upstream +spec: + externalNodes: + - type: Domain + name: httpbin.org + - type: Domain + name: postman-echo.com +` + var upstream apiv2.ApisixUpstream + applier.MustApplyAPIv2( + types.NamespacedName{Namespace: s.Namespace(), Name: upstreamName}, + &upstream, + upstreamSpec, + ) + + createApisixRoute() + + By("verify access to multiple services") + time.Sleep(7 * time.Second) Review Comment: The CI time has been getting longer and is about to reach one hour. We need to minimize the number of sleep and IT as much as possible. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@apisix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org