Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More AIGateway rename changes #107

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
out/
.DS_Store
.terraform
.idea
*for_tests.yaml

# Files and directories to ignore in the site directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (
)

const (
managedByLabel = "app.kubernetes.io/managed-by"
expProcConfigFileName = "extproc-config.yaml"
k8sClientIndexBackendToReferencingLLMRoute = "BackendToReferencingLLMRoute"
managedByLabel = "app.kubernetes.io/managed-by"
expProcConfigFileName = "extproc-config.yaml"
k8sClientIndexBackendToReferencingAIGatewayRoute = "BackendToReferencingAIGatewayRoute"
)

func aiGatewayRouteIndexFunc(o client.Object) []string {
Expand All @@ -41,7 +41,7 @@ func aiGatewayRouteIndexFunc(o client.Object) []string {

// aiGatewayRouteController implements [reconcile.TypedReconciler].
//
// This handles the LLMRoute resource and creates the necessary resources for the external process.
// This handles the AIGatewayRoute resource and creates the necessary resources for the external process.
type aiGatewayRouteController struct {
client client.Client
kube kubernetes.Interface
Expand All @@ -67,17 +67,17 @@ func NewAIGatewayRouteController(

// Reconcile implements [reconcile.TypedReconciler].
//
// This only creates the external process deployment and service for the LLMRoute as well as the extension policy.
// This only creates the external process deployment and service for the AIGatewayRoute as well as the extension policy.
// The actual HTTPRoute and the extproc configuration will be created in the config sink since we need
// not only the LLMRoute but also the AIServiceBackend and other resources to create the full configuration.
// not only the AIGatewayRoute but also the AIServiceBackend and other resources to create the full configuration.
func (c *aiGatewayRouteController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
logger := log.FromContext(ctx)
logger.Info("Reconciling LLMRoute", "namespace", req.Namespace, "name", req.Name)
logger.Info("Reconciling AIGatewayRoute", "namespace", req.Namespace, "name", req.Name)

var aiGatewayRoute aigv1a1.AIGatewayRoute
if err := c.client.Get(ctx, req.NamespacedName, &aiGatewayRoute); err != nil {
if client.IgnoreNotFound(err) == nil {
c.logger.Info("Deleting LLMRoute",
c.logger.Info("Deleting AIGatewayRoute",
"namespace", req.Namespace, "name", req.Name)
return ctrl.Result{}, nil
}
Expand All @@ -92,7 +92,7 @@ func (c *aiGatewayRouteController) Reconcile(ctx context.Context, req reconcile.
if !unversioned && len(gvks) == 1 {
aiGatewayRoute.SetGroupVersionKind(gvks[0])
}
ownerRef := ownerReferenceForLLMRoute(&aiGatewayRoute)
ownerRef := ownerReferenceForAIGatewayRoute(&aiGatewayRoute)

if err := c.ensuresExtProcConfigMapExists(ctx, &aiGatewayRoute, ownerRef); err != nil {
logger.Error(err, "Failed to reconcile extProc config map")
Expand Down Expand Up @@ -271,7 +271,7 @@ func extProcName(route *aigv1a1.AIGatewayRoute) string {
return fmt.Sprintf("ai-gateway-ai-gateway-route-extproc-%s", route.Name)
}

func ownerReferenceForLLMRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) []metav1.OwnerReference {
func ownerReferenceForAIGatewayRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) []metav1.OwnerReference {
return []metav1.OwnerReference{{
APIVersion: aiGatewayRoute.APIVersion,
Kind: aiGatewayRoute.Kind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func Test_extProcName(t *testing.T) {
require.Equal(t, "ai-gateway-ai-gateway-route-extproc-myroute", actual)
}

func TestLLMRouteController_ensuresExtProcConfigMapExists(t *testing.T) {
func TestAIGatewayRouteController_ensuresExtProcConfigMapExists(t *testing.T) {
c := &aiGatewayRouteController{client: fake.NewClientBuilder().WithScheme(scheme).Build()}
c.kube = fake2.NewClientset()

Expand All @@ -52,7 +52,7 @@ func TestLLMRouteController_ensuresExtProcConfigMapExists(t *testing.T) {
require.NoError(t, err)
}

func TestLLMRouteController_reconcileExtProcDeployment(t *testing.T) {
func TestAIGatewayRouteController_reconcileExtProcDeployment(t *testing.T) {
c := &aiGatewayRouteController{client: fake.NewClientBuilder().WithScheme(scheme).Build()}
c.kube = fake2.NewClientset()

Expand Down Expand Up @@ -103,7 +103,7 @@ func TestLLMRouteController_reconcileExtProcDeployment(t *testing.T) {
require.Equal(t, int32(456), *deployment.Spec.Replicas)
}

func TestLLMRouteController_reconcileExtProcExtensionPolicy(t *testing.T) {
func TestAIGatewayRouteController_reconcileExtProcExtensionPolicy(t *testing.T) {
c := &aiGatewayRouteController{client: fake.NewClientBuilder().WithScheme(scheme).Build()}
ownerRef := []metav1.OwnerReference{{APIVersion: "v1", Kind: "Kind", Name: "Name"}}
aiGatewayRoute := &aigv1a1.AIGatewayRoute{
Expand Down Expand Up @@ -189,10 +189,10 @@ func Test_aiGatewayRouteIndexFunc(t *testing.T) {

c := fake.NewClientBuilder().
WithScheme(scheme).
WithIndex(&aigv1a1.AIGatewayRoute{}, k8sClientIndexBackendToReferencingLLMRoute, aiGatewayRouteIndexFunc).
WithIndex(&aigv1a1.AIGatewayRoute{}, k8sClientIndexBackendToReferencingAIGatewayRoute, aiGatewayRouteIndexFunc).
Build()

// Create a LLMRoute.
// Create a AIGatewayRoute.
aiGatewayRoute := &aigv1a1.AIGatewayRoute{
ObjectMeta: metav1.ObjectMeta{
Name: "myroute",
Expand All @@ -218,13 +218,13 @@ func Test_aiGatewayRouteIndexFunc(t *testing.T) {

var aiGatewayRoutes aigv1a1.AIGatewayRouteList
err := c.List(context.Background(), &aiGatewayRoutes,
client.MatchingFields{k8sClientIndexBackendToReferencingLLMRoute: "backend1.default"})
client.MatchingFields{k8sClientIndexBackendToReferencingAIGatewayRoute: "backend1.default"})
require.NoError(t, err)
require.Len(t, aiGatewayRoutes.Items, 1)
require.Equal(t, aiGatewayRoute.Name, aiGatewayRoutes.Items[0].Name)

err = c.List(context.Background(), &aiGatewayRoutes,
client.MatchingFields{k8sClientIndexBackendToReferencingLLMRoute: "backend2.default"})
client.MatchingFields{k8sClientIndexBackendToReferencingAIGatewayRoute: "backend2.default"})
require.NoError(t, err)
require.Len(t, aiGatewayRoutes.Items, 1)
require.Equal(t, aiGatewayRoute.Name, aiGatewayRoutes.Items[0].Name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
aigv1a1 "github.com/envoyproxy/ai-gateway/api/v1alpha1"
)

func TestLlmBackendController_Reconcile(t *testing.T) {
func TestAIServiceBackendController_Reconcile(t *testing.T) {
ch := make(chan ConfigSinkEvent, 100)
cl := fake.NewClientBuilder().WithScheme(scheme).Build()
c := NewAIServiceBackendController(cl, fake2.NewClientset(), ctrl.Log, ch)
Expand Down
6 changes: 3 additions & 3 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func StartControllers(ctx context.Context, config *rest.Config, logger logr.Logg

sink := newConfigSink(c, kubernetes.NewForConfigOrDie(config), logger, sinkChan)

// Before starting the manager, initialize the config sink to sync all AIServiceBackend and LLMRoute objects in the cluster.
// Before starting the manager, initialize the config sink to sync all AIServiceBackend and AIGatewayRoute objects in the cluster.
logger.Info("Initializing config sink")
if err = sink.init(ctx); err != nil {
return fmt.Errorf("failed to initialize config sink: %w", err)
Expand All @@ -98,9 +98,9 @@ func StartControllers(ctx context.Context, config *rest.Config, logger logr.Logg

func applyIndexing(indexer client.FieldIndexer) error {
err := indexer.IndexField(context.Background(), &aigv1a1.AIGatewayRoute{},
k8sClientIndexBackendToReferencingLLMRoute, aiGatewayRouteIndexFunc)
k8sClientIndexBackendToReferencingAIGatewayRoute, aiGatewayRouteIndexFunc)
if err != nil {
return fmt.Errorf("failed to index field for LLMRoute: %w", err)
return fmt.Errorf("failed to index field for AIGatewayRoute: %w", err)
}
return nil
}
30 changes: 15 additions & 15 deletions internal/controller/sink.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import (
const selectedBackendHeaderKey = "x-envoy-ai-gateway-selected-backend"

// ConfigSinkEvent is the interface for the events that the configSink can handle.
// It can be either an AIServiceBackend, an LLMRoute, or a deletion event.
// It can be either an AIServiceBackend, an AIGatewayRoute, or a deletion event.
//
// Exported for internal testing purposes.
type ConfigSinkEvent any

// configSink centralizes the LLMRoute and AIServiceBackend objects handling
// configSink centralizes the AIGatewayRoute and AIServiceBackend objects handling
// which requires to be done in a single goroutine since we need to
// consolidate the information from both objects to generate the ExtProcConfig
// and HTTPRoute objects.
Expand Down Expand Up @@ -58,7 +58,7 @@ func (c *configSink) backend(namespace, name string) (*aigv1a1.AIServiceBackend,
return backend, nil
}

// init caches all AIServiceBackend and LLMRoute objects in the cluster after the controller gets the leader election,
// init caches all AIServiceBackend and AIGatewayRoute objects in the cluster after the controller gets the leader election,
// and starts a goroutine to handle the events from the controllers.
func (c *configSink) init(ctx context.Context) error {
go func() {
Expand All @@ -81,13 +81,13 @@ func (c *configSink) handleEvent(event ConfigSinkEvent) {
case *aigv1a1.AIServiceBackend:
c.syncAIServiceBackend(e)
case *aigv1a1.AIGatewayRoute:
c.syncLLMRoute(e)
c.syncAIGatewayRoute(e)
default:
panic(fmt.Sprintf("unexpected event type: %T", e))
}
}

func (c *configSink) syncLLMRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) {
func (c *configSink) syncAIGatewayRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) {
// Check if the HTTPRoute exists.
var httpRoute gwapiv1.HTTPRoute
err := c.client.Get(context.Background(), client.ObjectKey{Name: aiGatewayRoute.Name, Namespace: aiGatewayRoute.Namespace}, &httpRoute)
Expand All @@ -97,20 +97,20 @@ func (c *configSink) syncLLMRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) {
return
}
if !existingRoute {
// This means that this LLMRoute is a new one.
// This means that this AIGatewayRoute is a new one.
httpRoute = gwapiv1.HTTPRoute{
ObjectMeta: metav1.ObjectMeta{
Name: aiGatewayRoute.Name,
Namespace: aiGatewayRoute.Namespace,
OwnerReferences: ownerReferenceForLLMRoute(aiGatewayRoute),
OwnerReferences: ownerReferenceForAIGatewayRoute(aiGatewayRoute),
},
Spec: gwapiv1.HTTPRouteSpec{},
}
}

// Update the HTTPRoute with the new LLMRoute.
// Update the HTTPRoute with the new AIGatewayRoute.
if err := c.newHTTPRoute(&httpRoute, aiGatewayRoute); err != nil {
c.logger.Error(err, "failed to update HTTPRoute with LLMRoute", "namespace", aiGatewayRoute.Namespace, "name", aiGatewayRoute.Name)
c.logger.Error(err, "failed to update HTTPRoute with AIGatewayRoute", "namespace", aiGatewayRoute.Namespace, "name", aiGatewayRoute.Name)
return
}

Expand All @@ -136,21 +136,21 @@ func (c *configSink) syncLLMRoute(aiGatewayRoute *aigv1a1.AIGatewayRoute) {
func (c *configSink) syncAIServiceBackend(aiBackend *aigv1a1.AIServiceBackend) {
key := fmt.Sprintf("%s.%s", aiBackend.Name, aiBackend.Namespace)
var aiGatewayRoutes aigv1a1.AIGatewayRouteList
err := c.client.List(context.Background(), &aiGatewayRoutes, client.MatchingFields{k8sClientIndexBackendToReferencingLLMRoute: key})
err := c.client.List(context.Background(), &aiGatewayRoutes, client.MatchingFields{k8sClientIndexBackendToReferencingAIGatewayRoute: key})
if err != nil {
c.logger.Error(err, "failed to list LLMRoutes", "backend", key)
c.logger.Error(err, "failed to list AIGatewayRoute", "backend", key)
return
}
for _, aiGatewayRoute := range aiGatewayRoutes.Items {
c.syncLLMRoute(&aiGatewayRoute)
c.syncAIGatewayRoute(&aiGatewayRoute)
}
}

// updateExtProcConfigMap updates the external process configmap with the new LLMRoute.
// updateExtProcConfigMap updates the external process configmap with the new AIGatewayRoute.
func (c *configSink) updateExtProcConfigMap(aiGatewayRoute *aigv1a1.AIGatewayRoute) error {
configMap, err := c.kube.CoreV1().ConfigMaps(aiGatewayRoute.Namespace).Get(context.Background(), extProcName(aiGatewayRoute), metav1.GetOptions{})
if err != nil {
// This is a bug since we should have created the configmap before sending the LLMRoute to the configSink.
// This is a bug since we should have created the configmap before sending the AIGatewayRoute to the configSink.
panic(fmt.Errorf("failed to get configmap %s: %w", extProcName(aiGatewayRoute), err))
}

Expand Down Expand Up @@ -197,7 +197,7 @@ func (c *configSink) updateExtProcConfigMap(aiGatewayRoute *aigv1a1.AIGatewayRou
return nil
}

// newHTTPRoute updates the HTTPRoute with the new LLMRoute.
// newHTTPRoute updates the HTTPRoute with the new AIGatewayRoute.
func (c *configSink) newHTTPRoute(dst *gwapiv1.HTTPRoute, aiGatewayRoute *aigv1a1.AIGatewayRoute) error {
var backends []*aigv1a1.AIServiceBackend
dedup := make(map[string]struct{})
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/sink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestConfigSink_init(t *testing.T) {
require.NotNil(t, s)
}

func TestConfigSink_syncLLMRoute(t *testing.T) {
func TestConfigSink_syncAIGatewayRoute(t *testing.T) {
fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build()
kube := fake2.NewClientset()

Expand Down Expand Up @@ -80,7 +80,7 @@ func TestConfigSink_syncLLMRoute(t *testing.T) {
require.NoError(t, err)

// Then sync.
s.syncLLMRoute(route)
s.syncAIGatewayRoute(route)
// Referencing backends should be updated.
// Also HTTPRoute should be updated.
var updatedHTTPRoute gwapiv1.HTTPRoute
Expand Down
2 changes: 1 addition & 1 deletion tests/cel-validation/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
//go:embed testdata
var testdata embed.FS

func TestLLMRoutes(t *testing.T) {
func TestAIGatewayRoutes(t *testing.T) {
c, _, _ := tests.NewEnvTest(t)
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(30*time.Second))
defer cancel()
Expand Down
2 changes: 1 addition & 1 deletion tests/cel-validation/testdata/aigatewayroutes/basic.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: aigateway.envoyproxy.io/v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure how this was not caught by CI in the previous PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah super weird...

metadata:
name: apple
namespace: default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: aigateway.envoyproxy.io/v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
metadata:
name: apple
namespace: default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: aigateway.envoyproxy.io/v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
metadata:
name: apple
namespace: default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: aigateway.envoyproxy.io/v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
metadata:
name: apple
namespace: default
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/init/envoygateway/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ data:
resources:
- group: aigateway.envoyproxy.io
version: v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
# Envoy Gateway will watch these resource kinds and use them as extension policies
# which can be attached to Gateway resources.
policyResources:
- group: aigateway.envoyproxy.io
version: v1alpha1
kind: LLMRoute
kind: AIGatewayRoute
hooks:
# The type of hooks that should be invoked
xdsTranslator:
Expand Down
Loading