This is an automated email from the ASF dual-hosted git repository. ronething pushed a commit to branch fix/inline_upstream in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
commit 48a4adca9c98eaf3fe9cbc51b02f5c1d6c0b7814 Author: Ashing Zheng <[email protected]> AuthorDate: Mon Sep 8 16:50:49 2025 +0800 fix: r Signed-off-by: Ashing Zheng <[email protected]> --- api/v2/shared_types.go | 53 ++++++++++++++++++++++++++++++++++ internal/adc/translator/apisixroute.go | 11 +++++++ 2 files changed, 64 insertions(+) diff --git a/api/v2/shared_types.go b/api/v2/shared_types.go index 8ea57efa..fa2d7158 100644 --- a/api/v2/shared_types.go +++ b/api/v2/shared_types.go @@ -18,6 +18,8 @@ package v2 import ( + "bytes" + "strconv" "time" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -172,3 +174,54 @@ func SchemeToPort(schema string) int { } return 80 } + +var ( + ResolveGranularity = struct { + Endpoint string + Service string + }{ + Endpoint: "endpoint", + Service: "service", + } +) + +// ComposeUpstreamName uses namespace, name, subset (optional), port, resolveGranularity 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 int32, resolveGranularity string) string { + pstr := strconv.Itoa(int(port)) + // FIXME Use sync.Pool to reuse this buffer if the upstream + // name composing code path is hot. + 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 + } + + 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) + } + + return buf.String() +} + +// ComposeExternalUpstreamName uses ApisixUpstream namespace, name to compose the upstream name. +func ComposeExternalUpstreamName(namespace, name string) string { + return namespace + "_" + name +} diff --git a/internal/adc/translator/apisixroute.go b/internal/adc/translator/apisixroute.go index f4f78144..1ebc1506 100644 --- a/internal/adc/translator/apisixroute.go +++ b/internal/adc/translator/apisixroute.go @@ -226,6 +226,10 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc if backend.Weight != nil { upstream.Labels["meta_weight"] = strconv.FormatInt(int64(*backend.Weight), 10) } + + upstreamName := apiv2.ComposeUpstreamName(ar.Namespace, backend.ServiceName, backend.Subset, int32(backend.ServicePort.IntValue()), backend.ResolveGranularity) + upstream.Name = upstreamName + upstream.ID = id.GenID(upstreamName) upstreams = append(upstreams, upstream) } @@ -248,6 +252,9 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc upstream.Labels["meta_weight"] = strconv.FormatInt(int64(*upstreamRef.Weight), 10) } + upstreamName := apiv2.ComposeExternalUpstreamName(upsNN.Namespace, upsNN.Name) + upstream.Name = upstreamName + upstream.ID = id.GenID(upstreamName) upstreams = append(upstreams, upstream) } @@ -259,6 +266,10 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc // the first valid upstream is used as service.upstream; // the others are configured in the traffic-split plugin service.Upstream = upstreams[0] + // remove the id and name of the service.upstream, adc schema does not need id and name for service.upstream + service.Upstream.ID = "" + service.Upstream.Name = "" + upstreams = upstreams[1:] // Add remaining upstreams to service.Upstreams for independent management
