Skip to content

Commit 7d35cb9

Browse files
committed
feat(conversion): enable best-effort output and silence usage on errors
1 parent e79e5af commit 7d35cb9

File tree

11 files changed

+96
-42
lines changed

11 files changed

+96
-42
lines changed

cmd/print.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,21 @@ func (pr *PrintRunner) PrintGatewayAPIObjects(cmd *cobra.Command, _ []string) er
8989
}
9090

9191
gatewayResources, notificationTablesMap, err := i2gw.ToGatewayAPIResources(cmd.Context(), pr.namespaceFilter, pr.inputFile, pr.providers, pr.getProviderSpecificFlags())
92-
if err != nil {
93-
return err
94-
}
9592

9693
for _, table := range notificationTablesMap {
9794
fmt.Fprintln(os.Stderr, table)
9895
}
9996

97+
// Output partial results even if there are conversion errors (best-effort conversion)
10098
pr.outputResult(gatewayResources)
10199

100+
// Return error after outputting partial results
101+
if err != nil {
102+
// Silence usage on conversion errors since these are not command usage errors
103+
cmd.SilenceUsage = true
104+
return err
105+
}
106+
102107
return nil
103108
}
104109

pkg/i2gw/ingress2gateway.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ func ToGatewayAPIResources(ctx context.Context, namespace string, inputFile stri
8484
}
8585
notificationTablesMap := notifications.NotificationAggr.CreateNotificationTables()
8686
if len(errs) > 0 {
87-
return nil, notificationTablesMap, aggregatedErrs(errs)
87+
// Return partial results along with errors to support best-effort conversion
88+
return gatewayResources, notificationTablesMap, aggregatedErrs(errs)
8889
}
8990

9091
return gatewayResources, notificationTablesMap, nil

pkg/i2gw/providers/apisix/converter.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ func (c *resourcesToIRConverter) convertToIR(storage *storage) (intermediate.IR,
5050
// Convert plain ingress resources to gateway resources, ignoring all
5151
// provider-specific features.
5252
ir, errs := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
53-
if len(errs) > 0 {
54-
return intermediate.IR{}, errs
55-
}
5653

5754
for _, parseFeatureFunc := range c.featureParsers {
5855
// Apply the feature parsing function to the gateway resources, one by one.

pkg/i2gw/providers/cilium/converter.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ func (c *resourcesToIRConverter) convertToIR(storage *storage) (intermediate.IR,
5050
// Convert plain ingress resources to gateway resources, ignoring all
5151
// provider-specific features.
5252
ir, errs := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
53-
if len(errs) > 0 {
54-
return intermediate.IR{}, errs
55-
}
5653

5754
for _, parseFeatureFunc := range c.featureParsers {
5855
// Apply the feature parsing function to the gateway resources, one by one.

pkg/i2gw/providers/common/converter.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ func ToIR(ingresses []networkingv1.Ingress, servicePorts map[types.NamespacedNam
5151
}
5252

5353
routes, gateways, errs := aggregator.toHTTPRoutesAndGateways(options)
54-
if len(errs) > 0 {
55-
return intermediate.IR{}, errs
56-
}
5754

5855
routeByKey := make(map[types.NamespacedName]intermediate.HTTPRouteContext)
5956
for _, routeWithSources := range routes {
@@ -81,7 +78,7 @@ func ToIR(ingresses []networkingv1.Ingress, servicePorts map[types.NamespacedNam
8178
GRPCRoutes: make(map[types.NamespacedName]gatewayv1.GRPCRoute),
8279
BackendTLSPolicies: make(map[types.NamespacedName]gatewayv1.BackendTLSPolicy),
8380
ReferenceGrants: make(map[types.NamespacedName]gatewayv1beta1.ReferenceGrant),
84-
}, nil
81+
}, errs
8582
}
8683

8784
var (

pkg/i2gw/providers/common/converter_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,47 @@ func Test_ToIR(t *testing.T) {
446446
{Namespace: "test", Name: "example2"}: {"http": 8080},
447447
},
448448
expectedIR: intermediate.IR{
449-
Gateways: map[types.NamespacedName]intermediate.GatewayContext{},
450-
HTTPRoutes: map[types.NamespacedName]intermediate.HTTPRouteContext{},
449+
Gateways: map[types.NamespacedName]intermediate.GatewayContext{
450+
{Namespace: "test", Name: "named-ports"}: {
451+
Gateway: gatewayv1.Gateway{
452+
ObjectMeta: metav1.ObjectMeta{Name: "named-ports", Namespace: "test"},
453+
Spec: gatewayv1.GatewaySpec{
454+
GatewayClassName: "named-ports",
455+
Listeners: []gatewayv1.Listener{{
456+
Name: "example-com-http",
457+
Port: 80,
458+
Protocol: gatewayv1.HTTPProtocolType,
459+
Hostname: PtrTo(gatewayv1.Hostname("example.com")),
460+
}},
461+
},
462+
},
463+
},
464+
},
465+
HTTPRoutes: map[types.NamespacedName]intermediate.HTTPRouteContext{
466+
{Namespace: "test", Name: "named-ports-example-com"}: {
467+
HTTPRoute: gatewayv1.HTTPRoute{
468+
ObjectMeta: metav1.ObjectMeta{Name: "named-ports-example-com", Namespace: "test"},
469+
Spec: gatewayv1.HTTPRouteSpec{
470+
CommonRouteSpec: gatewayv1.CommonRouteSpec{
471+
ParentRefs: []gatewayv1.ParentReference{{
472+
Name: "named-ports",
473+
}},
474+
},
475+
Hostnames: []gatewayv1.Hostname{"example.com"},
476+
Rules: []gatewayv1.HTTPRouteRule{{
477+
Matches: []gatewayv1.HTTPRouteMatch{{
478+
Path: &gatewayv1.HTTPPathMatch{
479+
Type: &gPathPrefix,
480+
Value: PtrTo("/foo"),
481+
},
482+
}},
483+
BackendRefs: []gatewayv1.HTTPBackendRef{},
484+
}},
485+
},
486+
},
487+
RuleBackendSources: [][]intermediate.BackendSource{{}},
488+
},
489+
},
451490
},
452491
expectedErrors: field.ErrorList{field.Invalid(field.NewPath(""), "", "")},
453492
},

pkg/i2gw/providers/gce/ir_converter.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,12 @@ func (c *resourcesToIRConverter) convertToIR(storage *storage) (intermediate.IR,
7474

7575
// Convert plain ingress resources to gateway resources, ignoring all
7676
// provider-specific features.
77+
// Continue processing even with errors to support best-effort conversion
7778
ir, errs := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
78-
if len(errs) > 0 {
79-
return intermediate.IR{}, errs
80-
}
8179

82-
errs = setGCEGatewayClasses(ingressList, ir.Gateways)
83-
if len(errs) > 0 {
84-
return intermediate.IR{}, errs
85-
}
80+
// Accumulate errors from setting GCE gateway classes but continue processing
81+
setGCEErrs := setGCEGatewayClasses(ingressList, ir.Gateways)
82+
errs = append(errs, setGCEErrs...)
8683
buildGceGatewayIR(c.ctx, storage, &ir)
8784
buildGceServiceIR(c.ctx, storage, &ir)
8885
return ir, errs

pkg/i2gw/providers/ingressnginx/converter.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,6 @@ func (c *resourcesToIRConverter) convert(storage *storage) (intermediate.IR, fie
4545
// Convert plain ingress resources to gateway resources, ignoring all
4646
// provider-specific features.
4747
ir, errs := common.ToIR(ingressList, storage.ServicePorts, i2gw.ProviderImplementationSpecificOptions{})
48-
if len(errs) > 0 {
49-
return intermediate.IR{}, errs
50-
}
5148

5249
for _, parseFeatureFunc := range c.featureParsers {
5350
// Apply the feature parsing function to the gateway resources, one by one.

pkg/i2gw/providers/ingressnginx/converter_test.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,42 @@ func Test_ToIR(t *testing.T) {
337337
},
338338
},
339339
},
340-
expectedIR: intermediate.IR{},
340+
expectedIR: intermediate.IR{
341+
Gateways: map[types.NamespacedName]intermediate.GatewayContext{
342+
{Namespace: "default", Name: "ingress-nginx"}: {
343+
Gateway: gatewayv1.Gateway{
344+
ObjectMeta: metav1.ObjectMeta{Name: "ingress-nginx", Namespace: "default"},
345+
Spec: gatewayv1.GatewaySpec{
346+
GatewayClassName: "ingress-nginx",
347+
Listeners: []gatewayv1.Listener{{
348+
Name: "test-mydomain-com-http",
349+
Port: 80,
350+
Protocol: gatewayv1.HTTPProtocolType,
351+
Hostname: ptrTo(gatewayv1.Hostname("test.mydomain.com")),
352+
}},
353+
},
354+
},
355+
},
356+
},
357+
HTTPRoutes: map[types.NamespacedName]intermediate.HTTPRouteContext{
358+
{Namespace: "default", Name: "implementation-specific-regex-test-mydomain-com"}: {
359+
HTTPRoute: gatewayv1.HTTPRoute{
360+
ObjectMeta: metav1.ObjectMeta{Name: "implementation-specific-regex-test-mydomain-com", Namespace: "default"},
361+
Spec: gatewayv1.HTTPRouteSpec{
362+
CommonRouteSpec: gatewayv1.CommonRouteSpec{
363+
ParentRefs: []gatewayv1.ParentReference{{
364+
Name: "ingress-nginx",
365+
}},
366+
},
367+
Hostnames: []gatewayv1.Hostname{"test.mydomain.com"},
368+
// Rules is empty because the path conversion failed
369+
Rules: []gatewayv1.HTTPRouteRule{},
370+
},
371+
},
372+
RuleBackendSources: [][]intermediate.BackendSource{},
373+
},
374+
},
375+
},
341376
expectedErrors: field.ErrorList{
342377
{
343378
Type: field.ErrorTypeInvalid,

pkg/i2gw/providers/kong/converter.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ func (c *resourcesToIRConverter) convert(storage *storage) (intermediate.IR, fie
5555
// Convert plain ingress resources to gateway resources, ignoring all
5656
// provider-specific features.
5757
ir, errorList := common.ToIR(ingressList, storage.ServicePorts, c.implementationSpecificOptions)
58-
if len(errorList) > 0 {
59-
return intermediate.IR{}, errorList
60-
}
6158

6259
tcpGatewayIR, notificationsAggregator, errs := crds.TCPIngressToGatewayIR(storage.TCPIngresses)
6360
if len(errs) > 0 {
@@ -66,15 +63,10 @@ func (c *resourcesToIRConverter) convert(storage *storage) (intermediate.IR, fie
6663

6764
dispatchNotification(notificationsAggregator)
6865

69-
if len(errorList) > 0 {
70-
return intermediate.IR{}, errorList
71-
}
72-
73-
ir, errs = intermediate.MergeIRs(ir, tcpGatewayIR)
74-
75-
if len(errs) > 0 {
76-
return intermediate.IR{}, errs
77-
}
66+
// Merge IRs and accumulate errors, continuing best-effort conversion
67+
var mergeErrs field.ErrorList
68+
ir, mergeErrs = intermediate.MergeIRs(ir, tcpGatewayIR)
69+
errorList = append(errorList, mergeErrs...)
7870

7971
for _, parseFeatureFunc := range c.featureParsers {
8072
// Apply the feature parsing function to the gateway resources, one by one.

0 commit comments

Comments
 (0)