Skip to content

Commit bbb7330

Browse files
committed
Working on #11966 enhancing agw backend status support
Signed-off-by: Markus Kobler <[email protected]>
1 parent 6f2324e commit bbb7330

File tree

6 files changed

+150
-64
lines changed

6 files changed

+150
-64
lines changed

pkg/agentgateway/translator/backend_translator.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package translator
22

33
import (
4-
"github.com/agentgateway/agentgateway/go/api"
54
"k8s.io/apimachinery/pkg/runtime/schema"
65

7-
"github.com/kgateway-dev/kgateway/v2/api/v1alpha1/agentgateway"
8-
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/plugins"
9-
agwbackend "github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/backend"
106
sdk "github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk"
117
"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk/ir"
128
)
@@ -28,11 +24,3 @@ func NewAgwBackendTranslator(extensions sdk.Plugin) *AgwBackendTranslator {
2824
}
2925
return translator
3026
}
31-
32-
// TranslateBackend converts a BackendObjectIR to agent gateway Backend and Policy resources
33-
func (t *AgwBackendTranslator) TranslateBackend(
34-
ctx plugins.PolicyCtx,
35-
backend *agentgateway.AgentgatewayBackend,
36-
) ([]*api.Backend, error) {
37-
return agwbackend.BuildAgwBackend(ctx, backend)
38-
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
apiVersion: agentgateway.dev/v1alpha1
2+
kind: AgentgatewayBackend
3+
metadata:
4+
name: openai-backend
5+
namespace: default
6+
spec:
7+
policies:
8+
auth:
9+
secretRef:
10+
name: missing-secret
11+
ai:
12+
provider:
13+
openai:
14+
model: gpt-4
15+
---
16+
# Output
17+
output:
18+
- gateway:
19+
Name: ""
20+
Namespace: ""
21+
resource:
22+
backend:
23+
ai:
24+
providerGroups:
25+
- providers:
26+
- name: backend
27+
openai:
28+
model: gpt-4
29+
key: default/openai-backend
30+
name:
31+
name: openai-backend
32+
namespace: default
33+
status:
34+
conditions:
35+
- lastTransitionTime: fake
36+
message: Backend successfully accepted
37+
reason: Accepted
38+
status: "True"
39+
type: Accepted
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
apiVersion: agentgateway.dev/v1alpha1
2+
kind: AgentgatewayBackend
3+
metadata:
4+
name: anthropic-backend
5+
namespace: default
6+
spec:
7+
ai:
8+
provider:
9+
anthropic:
10+
model: claude-4-5-sonnet
11+
policies:
12+
auth:
13+
secretRef:
14+
name: valid-secret
15+
---
16+
apiVersion: v1
17+
kind: Secret
18+
metadata:
19+
name: valid-secret
20+
namespace: default
21+
data:
22+
Authorization: QmVhcmVyIHRlc3Q=
23+
---
24+
# Output
25+
output:
26+
- gateway:
27+
Name: ""
28+
Namespace: ""
29+
resource:
30+
backend:
31+
ai:
32+
providerGroups:
33+
- providers:
34+
- anthropic:
35+
model: claude-4-5-sonnet
36+
name: backend
37+
inlinePolicies:
38+
- auth:
39+
key:
40+
secret: test
41+
key: default/anthropic-backend
42+
name:
43+
name: anthropic-backend
44+
namespace: default
45+
status:
46+
conditions:
47+
- lastTransitionTime: fake
48+
message: Backend successfully accepted
49+
reason: Accepted
50+
status: "True"
51+
type: Accepted

pkg/kgateway/agentgatewaysyncer/backend/translate.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66

77
"github.com/agentgateway/agentgateway/go/api"
8+
"istio.io/istio/pilot/pkg/model/kstatus"
89
"istio.io/istio/pkg/kube/krt"
910
"istio.io/istio/pkg/ptr"
1011
corev1 "k8s.io/api/core/v1"
@@ -13,7 +14,9 @@ import (
1314

1415
apiannotations "github.com/kgateway-dev/kgateway/v2/api/annotations"
1516
"github.com/kgateway-dev/kgateway/v2/api/v1alpha1/agentgateway"
17+
agwir "github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/ir"
1618
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/plugins"
19+
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/translator"
1720
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/utils"
1821
"github.com/kgateway-dev/kgateway/v2/pkg/logging"
1922
"github.com/kgateway-dev/kgateway/v2/pkg/utils/kubeutils"
@@ -68,6 +71,47 @@ func BuildAgwBackend(
6871
return nil, errors.New("unknown backend")
6972
}
7073

74+
func TranslateAgwBackend(
75+
ctx plugins.PolicyCtx,
76+
backend *agentgateway.AgentgatewayBackend,
77+
) (*agentgateway.AgentgatewayBackendStatus, []agwir.AgwResource) {
78+
var results []agwir.AgwResource
79+
backends, err := BuildAgwBackend(ctx, backend)
80+
if err != nil {
81+
logger.Error("failed to translate backend", "backend", backend.Name, "namespace", backend.Namespace, "error", err)
82+
return &agentgateway.AgentgatewayBackendStatus{
83+
Conditions: kstatus.UpdateConditionIfChanged(backend.Status.Conditions, metav1.Condition{
84+
Type: "Accepted",
85+
Status: metav1.ConditionFalse,
86+
Reason: "TranslationError",
87+
Message: fmt.Sprintf("failed to translate backend %v", err),
88+
ObservedGeneration: backend.Generation,
89+
LastTransitionTime: metav1.Now(),
90+
}),
91+
}, results
92+
}
93+
// handle all backends created as an MCPBackend backend may create multiple backends
94+
for _, backend := range backends {
95+
logger.Debug("creating backend", "backend", backend.Name)
96+
resourceWrapper := translator.ToResourceGlobal(&api.Resource{
97+
Kind: &api.Resource_Backend{
98+
Backend: backend,
99+
},
100+
})
101+
results = append(results, resourceWrapper)
102+
}
103+
return &agentgateway.AgentgatewayBackendStatus{
104+
Conditions: kstatus.UpdateConditionIfChanged(backend.Status.Conditions, metav1.Condition{
105+
Type: "Accepted",
106+
Status: metav1.ConditionTrue,
107+
Reason: "Accepted",
108+
Message: "Backend successfully accepted",
109+
ObservedGeneration: backend.Generation,
110+
LastTransitionTime: metav1.Now(),
111+
}),
112+
}, results
113+
}
114+
71115
func translateMCPBackends(ctx plugins.PolicyCtx, be *agentgateway.AgentgatewayBackend, inlinePolicies []*api.BackendPolicySpec) ([]*api.Backend, error) {
72116
mcp := be.Spec.MCP
73117
var mcpTargets []*api.MCPTarget

pkg/kgateway/agentgatewaysyncer/backend/translate_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,20 @@ import (
1515
"sigs.k8s.io/yaml"
1616

1717
"github.com/kgateway-dev/kgateway/v2/api/v1alpha1/agentgateway"
18+
agwir "github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/ir"
1819
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/plugins"
1920
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/testutils"
2021
agentgatewaybackend "github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/backend"
2122
"github.com/kgateway-dev/kgateway/v2/pkg/utils/kubeutils"
2223
)
2324

25+
func TestTranslateAgwBackend(t *testing.T) {
26+
testutils.RunForDirectory(t, "testdata/backend", func(t *testing.T, ctx plugins.PolicyCtx) (*agentgateway.AgentgatewayBackendStatus, []agwir.AgwResource) {
27+
backend := testutils.GetTestResource(t, ctx.Collections.Backends)
28+
return agentgatewaybackend.TranslateAgwBackend(ctx, backend)
29+
})
30+
}
31+
2432
func TestBuildMCP(t *testing.T) {
2533
tests := []struct {
2634
name string

pkg/kgateway/agentgatewaysyncer/syncer.go

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ import (
77
"sync/atomic"
88

99
"github.com/agentgateway/agentgateway/go/api"
10-
"istio.io/istio/pilot/pkg/model/kstatus"
1110
"istio.io/istio/pkg/config"
1211
"istio.io/istio/pkg/kube/krt"
1312
"istio.io/istio/pkg/ptr"
1413
"istio.io/istio/pkg/slices"
1514
"istio.io/istio/pkg/util/sets"
16-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1715
"k8s.io/apimachinery/pkg/runtime/schema"
1816
"k8s.io/apimachinery/pkg/types"
1917
"k8s.io/client-go/tools/cache"
@@ -28,6 +26,7 @@ import (
2826
"github.com/kgateway-dev/kgateway/v2/pkg/agentgateway/utils"
2927
"github.com/kgateway-dev/kgateway/v2/pkg/apiclient"
3028
"github.com/kgateway-dev/kgateway/v2/pkg/deployer"
29+
agentgatewaybackend "github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/backend"
3130
"github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/krtxds"
3231
"github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/nack"
3332
"github.com/kgateway-dev/kgateway/v2/pkg/kgateway/agentgatewaysyncer/status"
@@ -317,63 +316,20 @@ func (s *Syncer) buildListenerFromGateway(obj *translator.GatewayListener) *agwi
317316
}, translator.AgwListener{l}))
318317
}
319318

320-
// buildBackendFromBackendIR creates a backend resource from Backend
321-
func (s *Syncer) buildBackendFromBackend(ctx krt.HandlerContext, backend *agentgateway.AgentgatewayBackend) ([]agwir.AgwResource, *agentgateway.AgentgatewayBackendStatus) {
322-
var results []agwir.AgwResource
323-
var backendStatus *agentgateway.AgentgatewayBackendStatus
324-
pc := plugins.PolicyCtx{
325-
Krt: ctx,
326-
Collections: s.agwCollections,
327-
}
328-
backends, err := s.translator.BackendTranslator().TranslateBackend(pc, backend)
329-
if err != nil {
330-
logger.Error("failed to translate backend", "backend", backend.Name, "namespace", backend.Namespace, "error", err)
331-
backendStatus = &agentgateway.AgentgatewayBackendStatus{
332-
Conditions: kstatus.UpdateConditionIfChanged(backend.Status.Conditions, metav1.Condition{
333-
Type: "Accepted",
334-
Status: metav1.ConditionFalse,
335-
Reason: "TranslationError",
336-
Message: fmt.Sprintf("failed to translate backend %v", err),
337-
ObservedGeneration: backend.Generation,
338-
LastTransitionTime: metav1.Now(),
339-
}),
340-
}
341-
return results, backendStatus
342-
}
343-
// handle all backends created as an MCPBackend backend may create multiple backends
344-
for _, backend := range backends {
345-
logger.Debug("creating backend", "backend", backend.Name)
346-
resourceWrapper := translator.ToResourceGlobal(&api.Resource{
347-
Kind: &api.Resource_Backend{
348-
Backend: backend,
349-
},
350-
})
351-
results = append(results, resourceWrapper)
352-
}
353-
backendStatus = &agentgateway.AgentgatewayBackendStatus{
354-
Conditions: kstatus.UpdateConditionIfChanged(backend.Status.Conditions, metav1.Condition{
355-
Type: "Accepted",
356-
Status: metav1.ConditionTrue,
357-
Reason: "Accepted",
358-
Message: "Backend successfully accepted",
359-
ObservedGeneration: backend.Generation,
360-
LastTransitionTime: metav1.Now(),
361-
}),
362-
}
363-
return results, backendStatus
364-
}
365-
366-
// newADPBackendCollection creates the ADP backend collection for agent gateway resources
319+
// newAgwBackendCollection creates the ADP backend collection for agent gateway resources
367320
func (s *Syncer) newAgwBackendCollection(finalBackends krt.Collection[*agentgateway.AgentgatewayBackend], krtopts krtutil.KrtOptions) (
368321
krt.StatusCollection[*agentgateway.AgentgatewayBackend, agentgateway.AgentgatewayBackendStatus],
369322
krt.Collection[agwir.AgwResource],
370323
) {
371-
return krt.NewStatusManyCollection(finalBackends, func(krtctx krt.HandlerContext, backend *agentgateway.AgentgatewayBackend) (
324+
return krt.NewStatusManyCollection(finalBackends, func(ctx krt.HandlerContext, backend *agentgateway.AgentgatewayBackend) (
372325
*agentgateway.AgentgatewayBackendStatus,
373326
[]agwir.AgwResource,
374327
) {
375-
resources, status := s.buildBackendFromBackend(krtctx, backend)
376-
return status, resources
328+
pc := plugins.PolicyCtx{
329+
Krt: ctx,
330+
Collections: s.agwCollections,
331+
}
332+
return agentgatewaybackend.TranslateAgwBackend(pc, backend)
377333
}, krtopts.ToOptions("Backends")...)
378334
}
379335

0 commit comments

Comments
 (0)