Skip to content

Commit

Permalink
Rename projectinformer to filteredinformer
Browse files Browse the repository at this point in the history
  • Loading branch information
panslava committed Dec 13, 2024
1 parent 50aed50 commit f598989
Show file tree
Hide file tree
Showing 12 changed files with 432 additions and 432 deletions.
4 changes: 2 additions & 2 deletions pkg/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ var F = struct {
EnableWeightedL4NetLB bool
EnableDiscretePortForwarding bool
EnableMultiProjectMode bool
MultiProjectCRDProjectNameLabel string
ProviderConfigNameLabelKey string
ProviderConfigAPIGroup string
EnableL4ILBMixedProtocol bool
EnableL4NetLBMixedProtocol bool
Expand Down Expand Up @@ -330,10 +330,10 @@ L7 load balancing. CSV values accepted. Example: -node-port-ranges=80,8080,400-5
flag.IntVar(&F.KubeClientBurst, "kube-client-burst", 0, "The burst QPS that the controllers' kube client should adhere to through client side throttling. If zero, client will be created with default settings.")
flag.BoolVar(&F.EnableDiscretePortForwarding, "enable-discrete-port-forwarding", false, "Enable forwarding of individual ports instead of port ranges.")
flag.BoolVar(&F.EnableMultiProjectMode, "enable-multi-project-mode", false, "Enable running in multi-project mode.")
flag.StringVar(&F.MultiProjectCRDProjectNameLabel, "multi-project-crd-project-name-label", "", "The label key for project name of Project in a Project CRD in the Multi-Project cluster.")
flag.BoolVar(&F.EnableL4ILBMixedProtocol, "enable-l4ilb-mixed-protocol", false, "Enable support for mixed protocol L4 internal load balancers.")
flag.BoolVar(&F.EnableL4NetLBMixedProtocol, "enable-l4netlb-mixed-protocol", false, "Enable support for mixed protocol L4 external load balancers.")
flag.StringVar(&F.ProviderConfigAPIGroup, "provider-config-api-group", "", "The API group for the ProviderConfig CRD.")
flag.StringVar(&F.ProviderConfigNameLabelKey, "provider-config-name-label-key", "", "The label key for provider-config name, which is used to identify the provider-config of objects in multi-project mode.")
}

func Validate() {
Expand Down
61 changes: 61 additions & 0 deletions pkg/multiproject/filteredinformer/filteredcache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package filteredinformer

import (
"k8s.io/client-go/tools/cache"
)

// providerConfigFilteredCache implements cache.Store and cache.Indexer with provider config filtering.
type providerConfigFilteredCache struct {
cache.Indexer
providerConfigName string
}

func (pc *providerConfigFilteredCache) ByIndex(indexName, indexedValue string) ([]interface{}, error) {
items, err := pc.Indexer.ByIndex(indexName, indexedValue)
if err != nil {
return nil, err
}
return providerConfigFilteredList(items, pc.providerConfigName), nil
}

func (pc *providerConfigFilteredCache) Index(indexName string, obj interface{}) ([]interface{}, error) {
items, err := pc.Indexer.Index(indexName, obj)
if err != nil {
return nil, err
}
return providerConfigFilteredList(items, pc.providerConfigName), nil
}

func (pc *providerConfigFilteredCache) List() []interface{} {
return providerConfigFilteredList(pc.Indexer.List(), pc.providerConfigName)
}

func (pc *providerConfigFilteredCache) ListKeys() []string {
items := pc.List()
var keys []string
for _, item := range items {
if key, err := cache.MetaNamespaceKeyFunc(item); err == nil {
keys = append(keys, key)
}
}
return keys
}

func (pc *providerConfigFilteredCache) Get(obj interface{}) (item interface{}, exists bool, err error) {
key, err := cache.MetaNamespaceKeyFunc(obj)
if err != nil {
return nil, false, err
}
return pc.GetByKey(key)
}

func (pc *providerConfigFilteredCache) GetByKey(key string) (item interface{}, exists bool, err error) {
item, exists, err = pc.Indexer.GetByKey(key)
if !exists || err != nil {
return nil, exists, err
}
if isObjectInProviderConfig(item, pc.providerConfigName) {
return item, true, nil
}
return nil, false, nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package projectinformer
package filteredinformer

import (
"testing"
Expand All @@ -9,32 +9,32 @@ import (
"k8s.io/ingress-gce/pkg/flags"
)

func TestProjectCache_ByIndex(t *testing.T) {
flags.F.MultiProjectCRDProjectNameLabel = "project-name-label"
func TestProviderConfigFilteredCache_ByIndex(t *testing.T) {
flags.F.ProviderConfigNameLabelKey = "provider-config-name-label"

testCases := []struct {
desc string
cacheProject string
objectsInCache []interface{}
queryName string
expectedItemNames []string
desc string
cacheProviderConfig string
objectsInCache []interface{}
queryName string
expectedItemNames []string
}{
{
desc: "Retrieve items by index in project",
cacheProject: "p123456-abc",
desc: "Retrieve items by index in provider config",
cacheProviderConfig: "cs123456-abc",
objectsInCache: []interface{}{
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"}, Namespace: "p123456-abc-namespace", Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"}, Namespace: "p123456-abc-namespace", Name: "obj2"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p654321-edf"}, Namespace: "p654321-edf-namespace", Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "cs123456-abc"}, Namespace: "cs123456-abc-namespace", Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "cs123456-abc"}, Namespace: "cs123456-abc-namespace", Name: "obj2"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "cs654321-edf"}, Namespace: "cs654321-edf-namespace", Name: "obj1"},
},
queryName: "obj1",
expectedItemNames: []string{"obj1"},
},
{
desc: "No items when index key does not match",
cacheProject: "p123456-abc",
desc: "No items when index key does not match",
cacheProviderConfig: "cs123456-abc",
objectsInCache: []interface{}{
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"}, Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "cs123456-abc"}, Name: "obj1"},
},
queryName: "nonexistent",
expectedItemNames: []string{},
Expand All @@ -53,9 +53,9 @@ func TestProjectCache_ByIndex(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, indexers)
nsCache := &projectCache{
Indexer: indexer,
projectName: tc.cacheProject,
nsCache := &providerConfigFilteredCache{
Indexer: indexer,
providerConfigName: tc.cacheProviderConfig,
}

for _, obj := range tc.objectsInCache {
Expand All @@ -80,29 +80,29 @@ func TestProjectCache_ByIndex(t *testing.T) {
}
}

func TestProjectCache_List(t *testing.T) {
flags.F.MultiProjectCRDProjectNameLabel = "project-name-label"
func TestProviderConfigFilteredCache_List(t *testing.T) {
flags.F.ProviderConfigNameLabelKey = "provider-config-name-label"

testCases := []struct {
desc string
cacheProject string
objectsInCache []interface{}
expectedItemNames []string
desc string
cacheProviderConfig string
objectsInCache []interface{}
expectedItemNames []string
}{
{
desc: "List items in the project",
cacheProject: "p123456-abc",
desc: "List items in the provider config",
cacheProviderConfig: "p123456-abc",
objectsInCache: []interface{}{
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"}, Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p654321-edf"}, Name: "obj2"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p123456-abc"}, Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p654321-edf"}, Name: "obj2"},
},
expectedItemNames: []string{"obj1"},
},
{
desc: "List no items when project has no objects",
cacheProject: "p123456-abc",
desc: "List no items when provider config has no objects",
cacheProviderConfig: "p123456-abc",
objectsInCache: []interface{}{
&v1.ObjectMeta{Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p654321-edf"}, Name: "obj1"},
&v1.ObjectMeta{Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p654321-edf"}, Name: "obj1"},
},
expectedItemNames: []string{},
},
Expand All @@ -112,9 +112,9 @@ func TestProjectCache_List(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, nil)
nsCache := &projectCache{
Indexer: indexer,
projectName: tc.cacheProject,
nsCache := &providerConfigFilteredCache{
Indexer: indexer,
providerConfigName: tc.cacheProviderConfig,
}

for _, obj := range tc.objectsInCache {
Expand All @@ -136,45 +136,45 @@ func TestProjectCache_List(t *testing.T) {
}
}

func TestProjectCache_GetByKey(t *testing.T) {
flags.F.MultiProjectCRDProjectNameLabel = "project-name-label"
func TestProviderConfigFilteredCache_GetByKey(t *testing.T) {
flags.F.ProviderConfigNameLabelKey = "provider-config-name-label"

testCases := []struct {
desc string
cacheProject string
queryKey string
objectsInCache []interface{}
expectedExist bool
expectedName string
desc string
cacheProviderConfig string
queryKey string
objectsInCache []interface{}
expectedExist bool
expectedName string
}{
{
desc: "Get existing item by key in project",
cacheProject: "p123456-abc",
queryKey: "p123456-abc-namespace/obj1",
desc: "Get existing item by key in provider config",
cacheProviderConfig: "p123456-abc",
queryKey: "p123456-abc-namespace/obj1",
objectsInCache: []interface{}{&v1.ObjectMeta{
Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"},
Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p123456-abc"},
Namespace: "p123456-abc-namespace",
Name: "obj1",
}},
expectedExist: true,
expectedName: "obj1",
},
{
desc: "Item exists but in different project",
cacheProject: "p123456-abc",
queryKey: "p654321-edf-namespace/obj1",
desc: "Item exists but in different provider config",
cacheProviderConfig: "p123456-abc",
queryKey: "p654321-edf-namespace/obj1",
objectsInCache: []interface{}{&v1.ObjectMeta{
Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p654321-edf"},
Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p654321-edf"},
Namespace: "p654321-edf-namespace",
Name: "obj1",
}},
expectedExist: false,
},
{
desc: "Item does not exist",
cacheProject: "p123456-abc",
desc: "Item does not exist",
cacheProviderConfig: "p123456-abc",
objectsInCache: []interface{}{&v1.ObjectMeta{
Labels: map[string]string{flags.F.MultiProjectCRDProjectNameLabel: "p123456-abc"},
Labels: map[string]string{flags.F.ProviderConfigNameLabelKey: "p123456-abc"},
Namespace: "p123456-abc-namespace",
Name: "obj1",
}},
Expand All @@ -187,9 +187,9 @@ func TestProjectCache_GetByKey(t *testing.T) {
tc := tc
t.Run(tc.desc, func(t *testing.T) {
indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, nil)
nsCache := &projectCache{
Indexer: indexer,
projectName: tc.cacheProject,
nsCache := &providerConfigFilteredCache{
Indexer: indexer,
providerConfigName: tc.cacheProviderConfig,
}

for _, obj := range tc.objectsInCache {
Expand Down
61 changes: 61 additions & 0 deletions pkg/multiproject/filteredinformer/filteredinformer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package filteredinformer

import (
"time"

"k8s.io/client-go/tools/cache"
)

// ProviderConfigFilteredInformer wraps a SharedIndexInformer to provide a ProviderConfig filtered view.
type ProviderConfigFilteredInformer struct {
cache.SharedIndexInformer
providerConfigName string
}

// NewProviderConfigFilteredInformer creates a new ProviderConfigFilteredInformer.
func NewProviderConfigFilteredInformer(informer cache.SharedIndexInformer, providerConfigName string) cache.SharedIndexInformer {
return &ProviderConfigFilteredInformer{
SharedIndexInformer: informer,
providerConfigName: providerConfigName,
}
}

// AddEventHandler adds an event handler that only processes events for the specified ProviderConfig.
func (i *ProviderConfigFilteredInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
return i.SharedIndexInformer.AddEventHandler(
cache.FilteringResourceEventHandler{
FilterFunc: i.providerConfigFilter,
Handler: handler,
},
)
}

// AddEventHandlerWithResyncPeriod adds an event handler with resync period.
func (i *ProviderConfigFilteredInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, resyncPeriod time.Duration) (cache.ResourceEventHandlerRegistration, error) {
return i.SharedIndexInformer.AddEventHandlerWithResyncPeriod(
cache.FilteringResourceEventHandler{
FilterFunc: i.providerConfigFilter,
Handler: handler,
},
resyncPeriod,
)
}

// providerConfigFilter filters objects based on the provider config.
func (i *ProviderConfigFilteredInformer) providerConfigFilter(obj interface{}) bool {
return isObjectInProviderConfig(obj, i.providerConfigName)
}

func (i *ProviderConfigFilteredInformer) GetStore() cache.Store {
return &providerConfigFilteredCache{
Indexer: i.SharedIndexInformer.GetIndexer(),
providerConfigName: i.providerConfigName,
}
}

func (i *ProviderConfigFilteredInformer) GetIndexer() cache.Indexer {
return &providerConfigFilteredCache{
Indexer: i.SharedIndexInformer.GetIndexer(),
providerConfigName: i.providerConfigName,
}
}
Loading

0 comments on commit f598989

Please sign in to comment.