Skip to content

Commit c9d5183

Browse files
committed
feat(apisixupstream): support portLevelSettings
1 parent be91920 commit c9d5183

File tree

7 files changed

+378
-64
lines changed

7 files changed

+378
-64
lines changed

config/rbac/role.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ rules:
102102
- gateways
103103
- grpcroutes
104104
- httproutes
105-
- tcproutes
106105
- referencegrants
106+
- tcproutes
107107
verbs:
108108
- get
109109
- list

internal/adc/translator/apisixroute.go

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -211,30 +211,12 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
211211
)
212212

213213
for _, backend := range rule.Backends {
214-
var backendErr error
215-
upstream := adc.NewDefaultUpstream()
216214
// try to get the apisixupstream with the same name as the backend service to be upstream config.
217215
// err is ignored because it does not care about the externalNodes of the apisixupstream.
218-
auNN := types.NamespacedName{Namespace: ar.GetNamespace(), Name: backend.ServiceName}
219-
if au, ok := tctx.Upstreams[auNN]; ok {
220-
upstream, _ = t.translateApisixUpstream(tctx, au)
221-
}
222-
223-
if backend.ResolveGranularity == apiv2.ResolveGranularityService {
224-
upstream.Nodes, backendErr = t.translateApisixRouteBackendResolveGranularityService(tctx, utils.NamespacedName(ar), backend)
225-
if backendErr != nil {
226-
t.Log.Error(backendErr, "failed to translate ApisixRoute backend with ResolveGranularity Service")
227-
continue
228-
}
229-
} else {
230-
upstream.Nodes, backendErr = t.translateApisixRouteBackendResolveGranularityEndpoint(tctx, utils.NamespacedName(ar), backend)
231-
if backendErr != nil {
232-
t.Log.Error(backendErr, "failed to translate ApisixRoute backend with ResolveGranularity Endpoint")
233-
continue
234-
}
235-
}
236-
if backend.Weight != nil {
237-
upstream.Labels["meta_weight"] = strconv.FormatInt(int64(*backend.Weight), 10)
216+
upstream, err := t.translateApisixRouteHTTPBackend(tctx, ar, backend)
217+
if err != nil {
218+
t.Log.Error(err, "failed to translate ApisixRoute backend", "backend", backend)
219+
continue
238220
}
239221

240222
upstreamName := adc.ComposeUpstreamName(ar.Namespace, backend.ServiceName, backend.Subset, backend.ServicePort, backend.ResolveGranularity)
@@ -253,7 +235,7 @@ func (t *Translator) buildUpstream(tctx *provider.TranslateContext, service *adc
253235
log.Debugw("failed to retrieve ApisixUpstream from tctx", zap.Any("ApisixUpstream", upsNN))
254236
continue
255237
}
256-
upstream, err := t.translateApisixUpstream(tctx, au)
238+
upstream, err := t.translateApisixUpstream(tctx, au, 0)
257239
if err != nil {
258240
t.Log.Error(err, "failed to translate ApisixUpstream", "ApisixUpstream", utils.NamespacedName(au))
259241
continue
@@ -350,6 +332,45 @@ func getPortFromService(svc *v1.Service, backendSvcPort intstr.IntOrString) (int
350332
return port, nil
351333
}
352334

335+
func (t *Translator) translateApisixRouteHTTPBackend(tctx *provider.TranslateContext, ar *apiv2.ApisixRoute, backend apiv2.ApisixRouteHTTPBackend) (*adc.Upstream, error) {
336+
auNN := types.NamespacedName{
337+
Namespace: ar.Namespace,
338+
Name: backend.ServiceName,
339+
}
340+
upstream := adc.NewDefaultUpstream()
341+
if au, ok := tctx.Upstreams[auNN]; ok {
342+
svc := tctx.Services[auNN]
343+
if svc == nil {
344+
return upstream, nil
345+
}
346+
port, err := getPortFromService(svc, backend.ServicePort)
347+
if err != nil {
348+
return nil, err
349+
}
350+
upstream, err = t.translateApisixUpstream(tctx, au, port)
351+
if err != nil {
352+
return nil, err
353+
}
354+
}
355+
var err error
356+
if backend.ResolveGranularity == apiv2.ResolveGranularityService {
357+
upstream.Nodes, err = t.translateApisixRouteBackendResolveGranularityService(tctx, auNN, backend)
358+
if err != nil {
359+
t.Log.Error(err, "failed to translate backend resolve granularity service", "backend", backend)
360+
}
361+
} else {
362+
upstream.Nodes, err = t.translateApisixRouteBackendResolveGranularityEndpoint(tctx, auNN, backend)
363+
if err != nil {
364+
t.Log.Error(err, "failed to translate backend resolve granularity endpoint", "backend", backend)
365+
}
366+
}
367+
368+
if backend.Weight != nil {
369+
upstream.Labels["meta_weight"] = strconv.FormatInt(int64(*backend.Weight), 10)
370+
}
371+
return upstream, nil
372+
}
373+
353374
func (t *Translator) translateApisixRouteBackendResolveGranularityService(tctx *provider.TranslateContext, arNN types.NamespacedName, backend apiv2.ApisixRouteHTTPBackend) (adc.UpstreamNodes, error) {
354375
serviceNN := types.NamespacedName{
355376
Namespace: arNN.Namespace,
@@ -434,9 +455,18 @@ func (t *Translator) translateStreamRule(tctx *provider.TranslateContext, ar *ap
434455
svc.StreamRoutes = append(svc.StreamRoutes, sr)
435456

436457
auNN := types.NamespacedName{Namespace: ar.GetNamespace(), Name: part.Backend.ServiceName}
458+
437459
upstream := adc.NewDefaultUpstream()
438460
if au, ok := tctx.Upstreams[auNN]; ok {
439-
upstream, _ = t.translateApisixUpstream(tctx, au)
461+
service := tctx.Services[auNN]
462+
if service == nil {
463+
return nil, errors.Errorf("service not found, ApisixRoute: %s, Service: %s", utils.NamespacedName(ar), auNN)
464+
}
465+
port, err := getPortFromService(service, part.Backend.ServicePort)
466+
if err != nil {
467+
return nil, err
468+
}
469+
upstream, _ = t.translateApisixUpstream(tctx, au, port)
440470
}
441471
nodes, err := t.translateApisixRouteStreamBackendResolveGranularity(tctx, utils.NamespacedName(ar), part.Backend)
442472
if err != nil {

internal/adc/translator/apisixupstream.go

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package translator
2020
import (
2121
"cmp"
2222
"fmt"
23+
"maps"
2324

2425
"github.com/api7/gopkg/pkg/log"
2526
"github.com/pkg/errors"
@@ -33,50 +34,68 @@ import (
3334
"github.com/apache/apisix-ingress-controller/internal/utils"
3435
)
3536

36-
func (t *Translator) translateApisixUpstream(tctx *provider.TranslateContext, au *apiv2.ApisixUpstream) (ups *adc.Upstream, err error) {
37-
ups = adc.NewDefaultUpstream()
38-
for _, f := range []func(*apiv2.ApisixUpstream, *adc.Upstream) error{
39-
patchApisixUpstreamBasics,
37+
func (t *Translator) translateApisixUpstream(tctx *provider.TranslateContext, au *apiv2.ApisixUpstream, port int32) (*adc.Upstream, error) {
38+
log.Debugw("translating ApisixUpstream", zap.Any("apisixupstream", au), zap.Int32("port", port))
39+
40+
ups := adc.NewDefaultUpstream()
41+
ups.Name = composeExternalUpstreamName(au)
42+
maps.Copy(ups.Labels, au.Labels)
43+
44+
if err := translateApisixUpstreamConfig(tctx, &au.Spec.ApisixUpstreamConfig, ups); err != nil {
45+
return nil, err
46+
}
47+
if err := translateApisixUpstreamExternalNodes(tctx, au, ups); err != nil {
48+
return nil, err
49+
}
50+
51+
// If portLevelSettings is configured, we need to validate the ports in
52+
if len(au.Spec.PortLevelSettings) > 0 && port != 0 {
53+
for _, pls := range au.Spec.PortLevelSettings {
54+
if pls.Port != port {
55+
continue
56+
}
57+
if err := translateApisixUpstreamConfig(tctx, &pls.ApisixUpstreamConfig, ups); err != nil {
58+
return nil, err
59+
}
60+
}
61+
}
62+
63+
log.Debugw("translated ApisixUpstream", zap.Any("upstream", ups))
64+
65+
return ups, nil
66+
}
67+
68+
func translateApisixUpstreamConfig(tctx *provider.TranslateContext, config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) (err error) {
69+
for _, f := range []func(*apiv2.ApisixUpstreamConfig, *adc.Upstream) error{
4070
translateApisixUpstreamScheme,
4171
translateApisixUpstreamLoadBalancer,
4272
translateApisixUpstreamRetriesAndTimeout,
4373
translateApisixUpstreamPassHost,
4474
translateUpstreamHealthCheck,
4575
translateUpstreamDiscovery,
4676
} {
47-
if err = f(au, ups); err != nil {
77+
if err = f(config, ups); err != nil {
4878
return
4979
}
5080
}
51-
for _, f := range []func(*provider.TranslateContext, *apiv2.ApisixUpstream, *adc.Upstream) error{
81+
for _, f := range []func(*provider.TranslateContext, *apiv2.ApisixUpstreamConfig, *adc.Upstream) error{
5282
translateApisixUpstreamClientTLS,
53-
translateApisixUpstreamExternalNodes,
5483
} {
55-
if err = f(tctx, au, ups); err != nil {
84+
if err = f(tctx, config, ups); err != nil {
5685
return
5786
}
5887
}
5988

60-
log.Debugw("translated ApisixUpstream", zap.Any("upstream", ups),
61-
zap.String("namespace", au.Namespace), zap.String("name", au.Name))
6289
return
6390
}
6491

65-
func patchApisixUpstreamBasics(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
66-
ups.Name = composeExternalUpstreamName(au)
67-
for k, v := range au.Labels {
68-
ups.Labels[k] = v
69-
}
70-
return nil
71-
}
72-
73-
func translateApisixUpstreamScheme(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
74-
ups.Scheme = cmp.Or(au.Spec.Scheme, apiv2.SchemeHTTP)
92+
func translateApisixUpstreamScheme(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
93+
ups.Scheme = cmp.Or(config.Scheme, apiv2.SchemeHTTP)
7594
return nil
7695
}
7796

78-
func translateApisixUpstreamLoadBalancer(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
79-
lb := au.Spec.LoadBalancer
97+
func translateApisixUpstreamLoadBalancer(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
98+
lb := config.LoadBalancer
8099
if lb == nil || lb.Type == "" {
81100
ups.Type = apiv2.LbRoundRobin
82101
return nil
@@ -107,9 +126,9 @@ func translateApisixUpstreamLoadBalancer(au *apiv2.ApisixUpstream, ups *adc.Upst
107126
return nil
108127
}
109128

110-
func translateApisixUpstreamRetriesAndTimeout(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
111-
retries := au.Spec.Retries
112-
timeout := au.Spec.Timeout
129+
func translateApisixUpstreamRetriesAndTimeout(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
130+
retries := config.Retries
131+
timeout := config.Timeout
113132

114133
if retries != nil && *retries < 0 {
115134
return errors.New("invalid value retries")
@@ -144,15 +163,15 @@ func translateApisixUpstreamRetriesAndTimeout(au *apiv2.ApisixUpstream, ups *adc
144163
return nil
145164
}
146165

147-
func translateApisixUpstreamClientTLS(tctx *provider.TranslateContext, au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
148-
if au.Spec.TLSSecret == nil {
166+
func translateApisixUpstreamClientTLS(tctx *provider.TranslateContext, config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
167+
if config.TLSSecret == nil {
149168
return nil
150169
}
151170

152171
var (
153172
secretNN = types.NamespacedName{
154-
Namespace: au.Spec.TLSSecret.Namespace,
155-
Name: au.Spec.TLSSecret.Name,
173+
Namespace: config.TLSSecret.Namespace,
174+
Name: config.TLSSecret.Name,
156175
}
157176
)
158177
secret, ok := tctx.Secrets[secretNN]
@@ -173,9 +192,9 @@ func translateApisixUpstreamClientTLS(tctx *provider.TranslateContext, au *apiv2
173192
return nil
174193
}
175194

176-
func translateApisixUpstreamPassHost(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
177-
ups.PassHost = au.Spec.PassHost
178-
ups.UpstreamHost = au.Spec.UpstreamHost
195+
func translateApisixUpstreamPassHost(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
196+
ups.PassHost = config.PassHost
197+
ups.UpstreamHost = config.UpstreamHost
179198

180199
return nil
181200
}
@@ -259,11 +278,8 @@ func translateApisixUpstreamExternalNodesService(tctx *provider.TranslateContext
259278
return nil
260279
}
261280

262-
func translateUpstreamHealthCheck(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
263-
if au == nil {
264-
return nil
265-
}
266-
healcheck := au.Spec.HealthCheck
281+
func translateUpstreamHealthCheck(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
282+
healcheck := config.HealthCheck
267283
if healcheck == nil || (healcheck.Passive == nil && healcheck.Active == nil) {
268284
return nil
269285
}
@@ -346,8 +362,8 @@ func translateUpstreamPassiveHealthCheck(config *apiv2.PassiveHealthCheck) *adc.
346362
return &passive
347363
}
348364

349-
func translateUpstreamDiscovery(au *apiv2.ApisixUpstream, ups *adc.Upstream) error {
350-
discovery := au.Spec.Discovery
365+
func translateUpstreamDiscovery(config *apiv2.ApisixUpstreamConfig, ups *adc.Upstream) error {
366+
discovery := config.Discovery
351367
if discovery == nil {
352368
return nil
353369
}

0 commit comments

Comments
 (0)