Skip to content

Commit 312bd89

Browse files
authored
Add support for named ports (#222)
1 parent 36c9792 commit 312bd89

36 files changed

+528
-101
lines changed

pkg/i2gw/provider.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ type GatewayResources struct {
118118
//
119119
// Different FeatureParsers will run in undetermined order. The function must
120120
// modify / create only the required fields of the gateway resources and nothing else.
121-
type FeatureParser func([]networkingv1.Ingress, *intermediate.IR) field.ErrorList
121+
type FeatureParser func([]networkingv1.Ingress, map[types.NamespacedName]map[string]int32, *intermediate.IR) field.ErrorList
122122

123123
var providerSpecificFlagDefinitions = providerSpecificFlags{
124124
flags: make(map[ProviderName]map[string]ProviderSpecificFlag),

pkg/i2gw/providers/apisix/converter.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ func (c *resourcesToIRConverter) convertToIR(storage *storage) (intermediate.IR,
4949
}
5050
// Convert plain ingress resources to gateway resources, ignoring all
5151
// provider-specific features.
52-
ir, errs := common.ToIR(ingressList, c.implementationSpecificOptions)
52+
ir, errs := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
5353
if len(errs) > 0 {
5454
return intermediate.IR{}, errs
5555
}
5656

5757
for _, parseFeatureFunc := range c.featureParsers {
5858
// Apply the feature parsing function to the gateway resources, one by one.
59-
parseErrs := parseFeatureFunc(ingressList, &ir)
59+
parseErrs := parseFeatureFunc(ingressList, storage.ServicePorts, &ir)
6060
// Append the parsing errors to the error list.
6161
errs = append(errs, parseErrs...)
6262
}

pkg/i2gw/providers/apisix/http_to_https.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
3030
)
3131

32-
func httpToHTTPSFeature(ingresses []networkingv1.Ingress, ir *intermediate.IR) field.ErrorList {
32+
func httpToHTTPSFeature(ingresses []networkingv1.Ingress, _ map[types.NamespacedName]map[string]int32, ir *intermediate.IR) field.ErrorList {
3333
var errs field.ErrorList
3434
httpToHTTPSAnnotation := apisixAnnotation("http-to-https")
3535
ruleGroups := common.GetRuleGroups(ingresses)

pkg/i2gw/providers/apisix/http_to_https_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ func Test_httpToHttpsFeature(t *testing.T) {
266266
},
267267
}
268268

269-
errs := httpToHTTPSFeature(ingresses, ir)
269+
errs := httpToHTTPSFeature(ingresses, map[types.NamespacedName]map[string]int32{}, ir)
270270

271271
if len(errs) != len(tc.expectedError) {
272272
t.Errorf("expected %d errors, got %d", len(tc.expectedError), len(errs))

pkg/i2gw/providers/apisix/resource_reader.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,29 @@ func (r *resourceReader) readResourcesFromCluster(ctx context.Context) (*storage
4545
return nil, err
4646
}
4747
storage.Ingresses = ingresses
48+
49+
services, err := common.ReadServicesFromCluster(ctx, r.conf.Client)
50+
if err != nil {
51+
return nil, err
52+
}
53+
storage.ServicePorts = common.GroupServicePortsByPortName(services)
4854
return storage, nil
4955
}
5056

5157
func (r *resourceReader) readResourcesFromFile(filename string) (*storage, error) {
5258
// read apisix related resources from file.
5359
storage := newResourcesStorage()
5460

55-
ingresses, err := common.ReadIngressesFromFile(filename, r.conf.Namespace, sets.New[string](ApisixIngressClass))
61+
ingresses, err := common.ReadIngressesFromFile(filename, r.conf.Namespace, sets.New(ApisixIngressClass))
5662
if err != nil {
5763
return nil, err
5864
}
5965
storage.Ingresses = ingresses
66+
67+
services, err := common.ReadServicesFromFile(filename, r.conf.Namespace)
68+
if err != nil {
69+
return nil, err
70+
}
71+
storage.ServicePorts = common.GroupServicePortsByPortName(services)
6072
return storage, nil
6173
}

pkg/i2gw/providers/apisix/storage.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ import (
2222
)
2323

2424
type storage struct {
25-
Ingresses map[types.NamespacedName]*networkingv1.Ingress
25+
Ingresses map[types.NamespacedName]*networkingv1.Ingress
26+
ServicePorts map[types.NamespacedName]map[string]int32
2627
}
2728

2829
func newResourcesStorage() *storage {
2930
return &storage{
30-
Ingresses: map[types.NamespacedName]*networkingv1.Ingress{},
31+
Ingresses: map[types.NamespacedName]*networkingv1.Ingress{},
32+
ServicePorts: map[types.NamespacedName]map[string]int32{},
3133
}
3234
}

pkg/i2gw/providers/cilium/converter.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ func (c *resourcesToIRConverter) convertToIR(storage *storage) (intermediate.IR,
4949
}
5050
// Convert plain ingress resources to gateway resources, ignoring all
5151
// provider-specific features.
52-
ir, errs := common.ToIR(ingressList, c.implementationSpecificOptions)
52+
ir, errs := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
5353
if len(errs) > 0 {
5454
return intermediate.IR{}, errs
5555
}
5656

5757
for _, parseFeatureFunc := range c.featureParsers {
5858
// Apply the feature parsing function to the gateway resources, one by one.
59-
parseErrs := parseFeatureFunc(ingressList, &ir)
59+
parseErrs := parseFeatureFunc(ingressList, storage.ServicePorts, &ir)
6060
// Append the parsing errors to the error list.
6161
errs = append(errs, parseErrs...)
6262
}

pkg/i2gw/providers/cilium/force_https.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
3030
)
3131

32-
func forceHTTPSFeature(ingresses []networkingv1.Ingress, ir *intermediate.IR) field.ErrorList {
32+
func forceHTTPSFeature(ingresses []networkingv1.Ingress, _ map[types.NamespacedName]map[string]int32, ir *intermediate.IR) field.ErrorList {
3333
var errs field.ErrorList
3434
forceHTTPSAnnotation := ciliumAnnotation("force-https")
3535
ruleGroups := common.GetRuleGroups(ingresses)

pkg/i2gw/providers/cilium/force_https_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ func Test_forceHTTPSFeature(t *testing.T) {
320320
},
321321
}
322322

323-
errs := forceHTTPSFeature(ingresses, ir)
323+
errs := forceHTTPSFeature(ingresses, map[types.NamespacedName]map[string]int32{}, ir)
324324

325325
if len(errs) != len(tc.expectedError) {
326326
t.Errorf("expected %d errors, got %d", len(tc.expectedError), len(errs))

pkg/i2gw/providers/cilium/resource_reader.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ func (r *resourceReader) readResourcesFromCluster(ctx context.Context) (*storage
4545
return nil, err
4646
}
4747
storage.Ingresses = ingresses
48+
49+
services, err := common.ReadServicesFromCluster(ctx, r.conf.Client)
50+
if err != nil {
51+
return nil, err
52+
}
53+
storage.ServicePorts = common.GroupServicePortsByPortName(services)
4854
return storage, nil
4955
}
5056

@@ -57,5 +63,11 @@ func (r *resourceReader) readResourcesFromFile(filename string) (*storage, error
5763
return nil, err
5864
}
5965
storage.Ingresses = ingresses
66+
67+
services, err := common.ReadServicesFromFile(filename, r.conf.Namespace)
68+
if err != nil {
69+
return nil, err
70+
}
71+
storage.ServicePorts = common.GroupServicePortsByPortName(services)
6072
return storage, nil
6173
}

pkg/i2gw/providers/cilium/storage.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ import (
2222
)
2323

2424
type storage struct {
25-
Ingresses map[types.NamespacedName]*networkingv1.Ingress
25+
Ingresses map[types.NamespacedName]*networkingv1.Ingress
26+
ServicePorts map[types.NamespacedName]map[string]int32
2627
}
2728

2829
func newResourcesStorage() *storage {
2930
return &storage{
30-
Ingresses: map[types.NamespacedName]*networkingv1.Ingress{},
31+
Ingresses: map[types.NamespacedName]*networkingv1.Ingress{},
32+
ServicePorts: map[types.NamespacedName]map[string]int32{},
3133
}
3234
}

pkg/i2gw/providers/common/converter.go

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ import (
3434

3535
// ToIR converts the received ingresses to intermediate.IR without taking into
3636
// consideration any provider specific logic.
37-
func ToIR(ingresses []networkingv1.Ingress, options i2gw.ProviderImplementationSpecificOptions) (intermediate.IR, field.ErrorList) {
38-
aggregator := ingressAggregator{ruleGroups: map[ruleGroupKey]*ingressRuleGroup{}}
37+
func ToIR(ingresses []networkingv1.Ingress, servicePorts map[types.NamespacedName]map[string]int32, options i2gw.ProviderImplementationSpecificOptions) (intermediate.IR, field.ErrorList) {
38+
aggregator := ingressAggregator{
39+
ruleGroups: map[ruleGroupKey]*ingressRuleGroup{},
40+
servicePorts: servicePorts,
41+
}
3942

4043
var errs field.ErrorList
4144
for _, ingress := range ingresses {
@@ -105,6 +108,7 @@ type ruleGroupKey string
105108
type ingressAggregator struct {
106109
ruleGroups map[ruleGroupKey]*ingressRuleGroup
107110
defaultBackends []ingressDefaultBackend
111+
servicePorts map[types.NamespacedName]map[string]int32
108112
}
109113

110114
type pathMatchKey string
@@ -201,7 +205,7 @@ func (a *ingressAggregator) toHTTPRoutesAndGateways(options i2gw.ProviderImpleme
201205
}
202206
gwKey := fmt.Sprintf("%s/%s", rg.namespace, rg.ingressClass)
203207
listenersByNamespacedGateway[gwKey] = append(listenersByNamespacedGateway[gwKey], listener)
204-
httpRoute, errs := rg.toHTTPRoute(options)
208+
httpRoute, errs := rg.toHTTPRoute(a.servicePorts, options)
205209
httpRoutes = append(httpRoutes, httpRoute)
206210
errors = append(errors, errs...)
207211
}
@@ -227,7 +231,7 @@ func (a *ingressAggregator) toHTTPRoutesAndGateways(options i2gw.ProviderImpleme
227231
}
228232
httpRoute.SetGroupVersionKind(HTTPRouteGVK)
229233

230-
backendRef, err := toBackendRef(db.backend, field.NewPath(db.name, "paths", "backends").Index(i))
234+
backendRef, err := ToBackendRef(db.namespace, db.backend, a.servicePorts, field.NewPath(db.name, "paths", "backends").Index(i))
231235
if err != nil {
232236
errors = append(errors, err)
233237
} else {
@@ -292,7 +296,7 @@ func (a *ingressAggregator) toHTTPRoutesAndGateways(options i2gw.ProviderImpleme
292296
return httpRoutes, gateways, errors
293297
}
294298

295-
func (rg *ingressRuleGroup) toHTTPRoute(options i2gw.ProviderImplementationSpecificOptions) (gatewayv1.HTTPRoute, field.ErrorList) {
299+
func (rg *ingressRuleGroup) toHTTPRoute(servicePorts map[types.NamespacedName]map[string]int32, options i2gw.ProviderImplementationSpecificOptions) (gatewayv1.HTTPRoute, field.ErrorList) {
296300
ingressPathsByMatchKey := groupIngressPathsByMatchKey(rg.rules)
297301
httpRoute := gatewayv1.HTTPRoute{
298302
ObjectMeta: metav1.ObjectMeta{
@@ -329,7 +333,7 @@ func (rg *ingressRuleGroup) toHTTPRoute(options i2gw.ProviderImplementationSpeci
329333
Matches: []gatewayv1.HTTPRouteMatch{*match},
330334
}
331335

332-
backendRefs, errs := rg.configureBackendRef(paths)
336+
backendRefs, errs := rg.configureBackendRef(servicePorts, paths)
333337
errors = append(errors, errs...)
334338
hrRule.BackendRefs = backendRefs
335339

@@ -339,12 +343,12 @@ func (rg *ingressRuleGroup) toHTTPRoute(options i2gw.ProviderImplementationSpeci
339343
return httpRoute, errors
340344
}
341345

342-
func (rg *ingressRuleGroup) configureBackendRef(paths []ingressPath) ([]gatewayv1.HTTPBackendRef, field.ErrorList) {
346+
func (rg *ingressRuleGroup) configureBackendRef(servicePorts map[types.NamespacedName]map[string]int32, paths []ingressPath) ([]gatewayv1.HTTPBackendRef, field.ErrorList) {
343347
var errors field.ErrorList
344348
var backendRefs []gatewayv1.HTTPBackendRef
345349

346350
for i, path := range paths {
347-
backendRef, err := toBackendRef(path.path.Backend, field.NewPath("paths", "backends").Index(i))
351+
backendRef, err := ToBackendRef(rg.namespace, path.path.Backend, servicePorts, field.NewPath("paths", "backends").Index(i))
348352
if err != nil {
349353
errors = append(errors, err)
350354
continue
@@ -396,25 +400,3 @@ func toHTTPRouteMatch(routePath networkingv1.HTTPIngressPath, path *field.Path,
396400

397401
return match, nil
398402
}
399-
400-
func toBackendRef(ib networkingv1.IngressBackend, path *field.Path) (*gatewayv1.BackendRef, *field.Error) {
401-
if ib.Service != nil {
402-
if ib.Service.Port.Name != "" {
403-
fieldPath := path.Child("service", "port")
404-
return nil, field.Invalid(fieldPath, "name", fmt.Sprintf("named ports not supported: %s", ib.Service.Port.Name))
405-
}
406-
return &gatewayv1.BackendRef{
407-
BackendObjectReference: gatewayv1.BackendObjectReference{
408-
Name: gatewayv1.ObjectName(ib.Service.Name),
409-
Port: (*gatewayv1.PortNumber)(&ib.Service.Port.Number),
410-
},
411-
}, nil
412-
}
413-
return &gatewayv1.BackendRef{
414-
BackendObjectReference: gatewayv1.BackendObjectReference{
415-
Group: (*gatewayv1.Group)(ib.Resource.APIGroup),
416-
Kind: (*gatewayv1.Kind)(&ib.Resource.Kind),
417-
Name: gatewayv1.ObjectName(ib.Resource.Name),
418-
},
419-
}, nil
420-
}

0 commit comments

Comments
 (0)