Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 6 additions & 24 deletions api/adc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"time"

"github.com/incubator4/go-resty-expr/expr"
"k8s.io/apimachinery/pkg/util/intstr"
)

const (
Expand Down Expand Up @@ -816,38 +815,21 @@ var (
}
)

// ComposeUpstreamName uses namespace, name, subset (optional), port, resolveGranularity info to compose
// ComposeUpstreamName uses namespace, name, ruleIndex, backendIndex, serviceName info to compose
// the upstream name.
// the resolveGranularity is not composited in the upstream name when it is endpoint.
// ref: https://github.com/apache/apisix-ingress-controller/blob/10059afe3e84b693cc61e6df7a0040890a9d16eb/pkg/types/apisix/v1/types.go#L595-L598
func ComposeUpstreamName(namespace, name, subset string, port intstr.IntOrString, resolveGranularity string) string {
pstr := port.String()
// FIXME Use sync.Pool to reuse this buffer if the upstream
// name composing code path is hot.
func ComposeUpstreamName(namespace, name, ruleIndex, backendIndex string) string {
var p []byte
plen := len(namespace) + len(name) + len(pstr) + 2
if subset != "" {
plen = plen + len(subset) + 1
}
if resolveGranularity == ResolveGranularity.Service {
plen = plen + len(resolveGranularity) + 1
}
plen := len(namespace) + len(name) + len(ruleIndex) + len(backendIndex) + 3

p = make([]byte, 0, plen)
buf := bytes.NewBuffer(p)
buf.WriteString(namespace)
buf.WriteByte('_')
buf.WriteString(name)
buf.WriteByte('_')
if subset != "" {
buf.WriteString(subset)
buf.WriteByte('_')
}
buf.WriteString(pstr)
if resolveGranularity == ResolveGranularity.Service {
buf.WriteByte('_')
buf.WriteString(resolveGranularity)
}
buf.WriteString(ruleIndex)
buf.WriteByte('_')
buf.WriteString(backendIndex)

return buf.String()
}
Expand Down
8 changes: 4 additions & 4 deletions internal/adc/translator/apisixroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (t *Translator) translateHTTPRule(tctx *provider.TranslateContext, ar *apiv

var enableWebsocket *bool
service := t.buildService(ar, rule, ruleIndex)
t.buildUpstream(tctx, service, ar, rule, &enableWebsocket)
t.buildUpstream(tctx, service, ar, rule, ruleIndex, &enableWebsocket)
t.buildRoute(ar, service, rule, plugins, timeout, vars, &enableWebsocket)
return service, nil
}
Expand Down Expand Up @@ -205,13 +205,13 @@ func (t *Translator) buildRoute(ar *apiv2.ApisixRoute, service *adc.Service, rul
service.Routes = []*adc.Route{route}
}

func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc.Service, ar *apiv2.ApisixRoute, rule apiv2.ApisixRouteHTTP, enableWebsocket **bool) {
func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc.Service, ar *apiv2.ApisixRoute, rule apiv2.ApisixRouteHTTP, ruleIndex int, enableWebsocket **bool) {
var (
upstreams = make([]*adc.Upstream, 0)
weightedUpstreams = make([]adc.TrafficSplitConfigRuleWeightedUpstream, 0)
)

for _, backend := range rule.Backends {
for backendIndex, backend := range rule.Backends {
// try to get the apisixupstream with the same name as the backend service to be upstream config.
// err is ignored because it does not care about the externalNodes of the apisixupstream.
upstream, err := t.translateApisixRouteHTTPBackend(tctx, ar, backend, enableWebsocket)
Expand All @@ -220,7 +220,7 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
continue
}

upstreamName := adc.ComposeUpstreamName(ar.Namespace, backend.ServiceName, backend.Subset, backend.ServicePort, backend.ResolveGranularity)
upstreamName := adc.ComposeUpstreamName(ar.Namespace, ar.Name, fmt.Sprintf("%d", ruleIndex), fmt.Sprintf("%d", backendIndex))
upstream.Name = upstreamName
upstream.ID = id.GenID(upstreamName)
upstreams = append(upstreams, upstream)
Expand Down
71 changes: 71 additions & 0 deletions test/e2e/crds/v2/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -2166,4 +2166,75 @@ spec:
Expect(string(msg)).To(Equal(testMessage), "message content verification")
})
})

Context("Test ApisixRoute with multiple backends", func() {
It("create ApisixRoute with multiple backends", func() {
var httpService = `
apiVersion: v1
kind: Service
metadata:
name: httpbin-service-e2e-test2
spec:
selector:
app: httpbin-deployment-e2e-test
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
`
err := s.CreateResourceFromString(httpService)
Expect(err).ShouldNot(HaveOccurred())
s.EnsureNumEndpointsReady(GinkgoT(), "httpbin-service-e2e-test2", 1)

const apisixRouteSpec = `
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin
spec:
ingressClassName: %s
http:
- name: get
match:
paths:
- /get
backends:
- serviceName: httpbin-service-e2e-test
servicePort: 80
- serviceName: httpbin-service-e2e-test2
servicePort: 80
- name: ip
match:
paths:
- /ip
backends:
- serviceName: httpbin-service-e2e-test
servicePort: 80
- serviceName: httpbin-service-e2e-test2
servicePort: 80
`
By("apply ApisixRoute")
applier.MustApplyAPIv2(types.NamespacedName{Namespace: s.Namespace(), Name: "httpbin"},
&apiv2.ApisixRoute{}, fmt.Sprintf(apisixRouteSpec, s.Namespace()))

By("check upstreams")
upstreams, err := s.DefaultDataplaneResource().Upstream().List(context.Background())
Expect(err).ShouldNot(HaveOccurred())
Expect(upstreams).Should(HaveLen(4))

By("verify ApisixRoute works")
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/get",
Check: scaffold.WithExpectedStatus(http.StatusOK),
})
s.RequestAssert(&scaffold.RequestAssert{
Method: "GET",
Path: "/ip",
Check: scaffold.WithExpectedStatus(http.StatusOK),
})
})
})
})
Loading