Skip to content
Open
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
24 changes: 2 additions & 22 deletions pkg/agentgateway/translator/gateway_collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,6 @@ func (g ParentInfo) Equals(other ParentInfo) bool {
slices.Equal(g.Hostnames, other.Hostnames)
}

type GatewayTransformationFunction func(GatewayCollectionConfig) func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener)

type GatewayCollectionConfigOption func(o *GatewayCollectionConfig)

func WithGatewayTransformationFunc(f GatewayTransformationFunction) GatewayCollectionConfigOption {
return func(o *GatewayCollectionConfig) {
o.transformationFunc = f
}
}

type GatewayCollectionConfig struct {
ControllerName string
Gateways krt.Collection[*gwv1.Gateway]
Expand All @@ -227,22 +217,12 @@ func GatewayCollection(
krt.StatusCollection[*gwv1.Gateway, gwv1.GatewayStatus],
krt.Collection[*GatewayListener],
) {
for _, fn := range opts {
fn(&cfg)
}
cfg.listenerIndex = krt.NewIndex(cfg.ListenerSets, "gatewayParent", func(o ListenerSet) []types.NamespacedName {
return []types.NamespacedName{o.GatewayParent}
})
if cfg.transformationFunc == nil {
cfg.transformationFunc = GatewaysTransformationFunc
}

processGatewayCollectionOptions(&cfg, opts...)
statusCol, gw := krt.NewStatusManyCollection(cfg.Gateways, cfg.transformationFunc(cfg), cfg.KrtOpts.ToOptions("KubernetesGateway")...)

return statusCol, gw
}

func GatewaysTransformationFunc(cfg GatewayCollectionConfig) func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener) {
func GatewayTransformationFunc(cfg GatewayCollectionConfig) func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener) {
return func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener) {
class := krt.FetchOne(ctx, cfg.GatewayClasses, krt.FilterKey(string(obj.Spec.GatewayClassName)))
if class == nil {
Expand Down
29 changes: 29 additions & 0 deletions pkg/agentgateway/translator/option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package translator

import (
"istio.io/istio/pkg/kube/krt"
"k8s.io/apimachinery/pkg/types"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
)

type GatewayTransformationFunction func(GatewayCollectionConfig) func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener)

type GatewayCollectionConfigOption func(o *GatewayCollectionConfig)

func WithGatewayTransformationFunc(f GatewayTransformationFunction) GatewayCollectionConfigOption {
return func(o *GatewayCollectionConfig) {
if f != nil {
o.transformationFunc = f
}
}
}

func processGatewayCollectionOptions(cfg *GatewayCollectionConfig, opts ...GatewayCollectionConfigOption) {
cfg.listenerIndex = krt.NewIndex(cfg.ListenerSets, "gatewayParent", func(o ListenerSet) []types.NamespacedName {
return []types.NamespacedName{o.GatewayParent}
})
cfg.transformationFunc = GatewayTransformationFunc
for _, fn := range opts {
fn(cfg)
}
}
51 changes: 51 additions & 0 deletions pkg/agentgateway/translator/option_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package translator

import (
"testing"

"github.com/stretchr/testify/assert"
"istio.io/istio/pkg/kube/krt"
corev1 "k8s.io/api/core/v1"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"

"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk/krtutil"
)

func TestDefaultGatewayCollectionOptions(t *testing.T) {
cfg := getConfig(t)
processGatewayCollectionOptions(&cfg)

assert.NotNil(t, cfg.listenerIndex)
assert.NotNil(t, cfg.transformationFunc)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

AFAIK go can't test the equivalence of functions (test whether cfg.transformationFunc is the same as GatewayTransformationFunc, the default value), so the second best is to ensure it is not nil

}

func TestWithGatewayTransformationFunc(t *testing.T) {
called := false
customTransformationFunc := func(cfg GatewayCollectionConfig) func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener) {
called = true
return func(ctx krt.HandlerContext, obj *gwv1.Gateway) (*gwv1.GatewayStatus, []*GatewayListener) {
return nil, nil
}
}

GatewayCollection(getConfig(t), WithGatewayTransformationFunc(customTransformationFunc))
assert.True(t, called)
}

func getConfig(t *testing.T) GatewayCollectionConfig {
opts := krtutil.NewKrtOptions(t.Context().Done(), nil)
return GatewayCollectionConfig{
ControllerName: "random-name",
Gateways: krt.NewStaticCollection[*gwv1.Gateway](nil, nil, opts.ToOptions("Gateways")...),
ListenerSets: krt.NewStaticCollection[ListenerSet](nil, nil, opts.ToOptions("ListenerSets")...),
GatewayClasses: krt.NewStaticCollection[GatewayClass](nil, nil, opts.ToOptions("GatewayClasses")...),
Namespaces: krt.NewStaticCollection[*corev1.Namespace](nil, nil, opts.ToOptions("Namespaces")...),
Grants: ReferenceGrants{
collection: krt.NewStaticCollection[ReferenceGrant](nil, nil, opts.ToOptions("Grants")...),
index: nil,
},
Secrets: krt.NewStaticCollection[*corev1.Secret](nil, nil, opts.ToOptions("Secrets")...),
ConfigMaps: krt.NewStaticCollection[*corev1.ConfigMap](nil, nil, opts.ToOptions("ConfigMaps")...),
KrtOpts: opts,
}
}
4 changes: 3 additions & 1 deletion pkg/kgateway/agentgatewaysyncer/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ func processAgentgatewaySyncerOptions(opts ...AgentgatewaySyncerOption) *agentga

func WithGatewayTransformationFunc(f translator.GatewayTransformationFunction) AgentgatewaySyncerOption {
return func(o *agentgatewaySyncerConfig) {
o.GatewayTransformationFunc = f
if f != nil {
o.GatewayTransformationFunc = f
}
}
}
4 changes: 3 additions & 1 deletion pkg/kgateway/proxy_syncer/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func processStatusSyncerOptions(opts ...StatusSyncerOption) *statusSyncerConfig

func WithCustomStatusSync(customSync func(ctx context.Context, rm reports.ReportMap)) StatusSyncerOption {
return func(cfg *statusSyncerConfig) {
cfg.CustomStatusSync = customSync
if customSync != nil {
cfg.CustomStatusSync = customSync
}
}
}
19 changes: 19 additions & 0 deletions pkg/kgateway/proxy_syncer/option_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package proxy_syncer

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk"
"github.com/kgateway-dev/kgateway/v2/pkg/reports"
)

func TestWithCustomStatusSync(t *testing.T) {
customStatusSync := func(ctx context.Context, rm reports.ReportMap) {}
statusSyncer := NewStatusSyncer(nil, pluginsdk.Plugin{}, "controller-name", "agw-controller-name", nil, nil, nil, nil, nil,
WithCustomStatusSync(customStatusSync))

assert.NotNil(t, statusSyncer.customStatusSync)
}
59 changes: 59 additions & 0 deletions pkg/krtcollections/option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package krtcollections

import (
"istio.io/istio/pkg/kube/krt"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
gwxv1a1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"

"github.com/kgateway-dev/kgateway/v2/pkg/kgateway/wellknown"
"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk/ir"
krtpkg "github.com/kgateway-dev/kgateway/v2/pkg/utils/krtutil"
)

type (
GatewaysForDeployerTransformationFunction func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.GatewayForDeployer
GatewaysForEnvoyTransformationFunction func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.Gateway
)

type GatewayIndexConfigOption func(o *GatewayIndexConfig)

func WithGatewayForDeployerTransformationFunc(f GatewaysForDeployerTransformationFunction) GatewayIndexConfigOption {
return func(o *GatewayIndexConfig) {
if f != nil {
o.gatewaysForDeployerTransformationFunc = f
}
}
}

func WithGatewayForEnvoyTransformationFunc(f GatewaysForEnvoyTransformationFunction) GatewayIndexConfigOption {
return func(o *GatewayIndexConfig) {
if f != nil {
o.gatewaysForEnvoyTransformationFunc = f
}
}
}

func processGatewayIndexConfig(config *GatewayIndexConfig, opts ...GatewayIndexConfigOption) {
config.byParentRefIndex = krtpkg.UnnamedIndex(config.ListenerSets, func(in *gwxv1a1.XListenerSet) []TargetRefIndexKey {
pRef := in.Spec.ParentRef
ns := strOr(pRef.Namespace, "")
if ns == "" {
ns = in.GetNamespace()
}
// lookup by the root object
return []TargetRefIndexKey{{
Group: wellknown.GatewayGroup,
Kind: wellknown.GatewayKind,
Name: string(pRef.Name),
Namespace: ns,
// this index intentionally doesn't include sectionName
}}
})

config.gatewaysForDeployerTransformationFunc = GatewaysForDeployerTransformationFunc
config.gatewaysForEnvoyTransformationFunc = GatewaysForEnvoyTransformationFunc

for _, fn := range opts {
fn(config)
}
}
66 changes: 66 additions & 0 deletions pkg/krtcollections/option_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package krtcollections

import (
"testing"

"github.com/stretchr/testify/assert"
"istio.io/istio/pkg/kube/krt"
"istio.io/istio/pkg/util/smallset"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
gwxv1a1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"

"github.com/kgateway-dev/kgateway/v2/api/settings"
"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk/ir"
"github.com/kgateway-dev/kgateway/v2/pkg/pluginsdk/krtutil"
)

func TestDefaultGatewayCollectionOptions(t *testing.T) {
cfg := getConfig(t)
processGatewayIndexConfig(&cfg)

assert.NotNil(t, cfg.byParentRefIndex)
assert.NotNil(t, cfg.gatewaysForDeployerTransformationFunc)
assert.NotNil(t, cfg.gatewaysForEnvoyTransformationFunc)
}

func TestWithGatewayForDeployerTransformationFunc(t *testing.T) {
called := false
customTransformationFunc := func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.GatewayForDeployer {
called = true
return func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.GatewayForDeployer {
return nil
}
}
cfg := getConfig(t)

NewGatewayIndex(cfg, WithGatewayForDeployerTransformationFunc(customTransformationFunc))
assert.True(t, called)
}

func TestWithGatewayForEnvoyTransformationFunc(t *testing.T) {
called := false
customTransformationFunc := func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.Gateway {
called = true
return func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.Gateway {
return nil
}
}
cfg := getConfig(t)

NewGatewayIndex(cfg, WithGatewayForEnvoyTransformationFunc(customTransformationFunc))
assert.True(t, called)
}

func getConfig(t *testing.T) GatewayIndexConfig {
krtOpts := krtutil.NewKrtOptions(t.Context().Done(), nil)
return GatewayIndexConfig{
KrtOpts: krtOpts,
ControllerNames: smallset.New("controller-name"),
EnvoyControllerName: "envoy-controller-name",
PolicyIndex: NewPolicyIndex(krtOpts, nil, settings.Settings{}),
Gateways: krt.NewStaticCollection[*gwv1.Gateway](nil, nil, krtOpts.ToOptions("Gateways")...),
ListenerSets: krt.NewStaticCollection[*gwxv1a1.XListenerSet](nil, nil, krtOpts.ToOptions("ListenerSets")...),
GatewayClasses: krt.NewStaticCollection[*gwv1.GatewayClass](nil, nil, krtOpts.ToOptions("GatewayClasses")...),
Namespaces: krt.NewStaticCollection[NamespaceMetadata](nil, nil, krtOpts.ToOptions("Namespaces")...),
}
}
75 changes: 2 additions & 73 deletions pkg/krtcollections/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,51 +330,6 @@ type GatewayIndex struct {
GatewaysForDeployer krt.Collection[ir.GatewayForDeployer]
}

type (
GatewaysForDeployerTransformationFunction func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.GatewayForDeployer
GatewaysForEnvoyTransformationFunction func(config *GatewayIndexConfig) func(kctx krt.HandlerContext, gw *gwv1.Gateway) *ir.Gateway
)

type GatewayIndexConfigOption func(o *GatewayIndexConfig)

func WithGatewayForDeployerTransformationFunc(f GatewaysForDeployerTransformationFunction) GatewayIndexConfigOption {
return func(o *GatewayIndexConfig) {
o.gatewaysForDeployerTransformationFunc = f
}
}

func WithGatewayForEnvoyTransformationFunc(f GatewaysForEnvoyTransformationFunction) GatewayIndexConfigOption {
return func(o *GatewayIndexConfig) {
o.gatewaysForEnvoyTransformationFunc = f
}
}

func NewGatewayIndexConfig(krtOpts krtutil.KrtOptions,
controllerNames smallset.Set[string],
envoyControllerName string,
policyIndex *PolicyIndex,
gateways krt.Collection[*gwv1.Gateway],
listenerSets krt.Collection[*gwxv1a1.XListenerSet],
gatewayClasses krt.Collection[*gwv1.GatewayClass],
namespaces krt.Collection[NamespaceMetadata],
opts ...GatewayIndexConfigOption,
) GatewayIndexConfig {
gwIC := GatewayIndexConfig{
KrtOpts: krtOpts,
ControllerNames: controllerNames,
EnvoyControllerName: envoyControllerName,
PolicyIndex: policyIndex,
Gateways: gateways,
ListenerSets: listenerSets,
GatewayClasses: gatewayClasses,
Namespaces: namespaces,
}
for _, fn := range opts {
fn(&gwIC)
}
return gwIC
}

type GatewayIndexConfig struct {
KrtOpts krtutil.KrtOptions
ControllerNames smallset.Set[string]
Expand All @@ -390,36 +345,10 @@ type GatewayIndexConfig struct {
byParentRefIndex krt.Index[TargetRefIndexKey, *gwxv1a1.XListenerSet]
}

func processGatewayIndexConfig(config *GatewayIndexConfig) {
config.byParentRefIndex = krtpkg.UnnamedIndex(config.ListenerSets, func(in *gwxv1a1.XListenerSet) []TargetRefIndexKey {
pRef := in.Spec.ParentRef
ns := strOr(pRef.Namespace, "")
if ns == "" {
ns = in.GetNamespace()
}
// lookup by the root object
return []TargetRefIndexKey{{
Group: wellknown.GatewayGroup,
Kind: wellknown.GatewayKind,
Name: string(pRef.Name),
Namespace: ns,
// this index intentionally doesn't include sectionName
}}
})

if config.gatewaysForDeployerTransformationFunc == nil {
config.gatewaysForDeployerTransformationFunc = GatewaysForDeployerTransformationFunc
}
if config.gatewaysForEnvoyTransformationFunc == nil {
config.gatewaysForEnvoyTransformationFunc = GatewaysForEnvoyTransformationFunc
}
}

func NewGatewayIndex(config GatewayIndexConfig) *GatewayIndex {
processGatewayIndexConfig(&config)
func NewGatewayIndex(config GatewayIndexConfig, opts ...GatewayIndexConfigOption) *GatewayIndex {
processGatewayIndexConfig(&config, opts...)

h := &GatewayIndex{}

h.GatewaysForDeployer = krt.NewCollection(config.Gateways, config.gatewaysForDeployerTransformationFunc(&config))
if config.PolicyIndex == nil {
return h
Expand Down
Loading