Skip to content

Commit

Permalink
Merge pull request stolostron#327 from ldpliu/abstract-cache
Browse files Browse the repository at this point in the history
acstract cache
  • Loading branch information
openshift-merge-robot authored Apr 21, 2021
2 parents 434684d + a3f2166 commit 1608b12
Show file tree
Hide file tree
Showing 15 changed files with 479 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
clusterinformerv1 "github.com/open-cluster-management/api/client/cluster/informers/externalversions/cluster/v1"
clusterv1lister "github.com/open-cluster-management/api/client/cluster/listers/cluster/v1"
clusterv1 "github.com/open-cluster-management/api/cluster/v1"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/utils"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -38,6 +39,7 @@ func NewClusterCache(clusterInformer clusterinformerv1.ManagedClusterInformer,
"cluster.open-cluster-management.io", "managedclusters",
clusterInformer.Informer(),
clusterCache.ListResources,
utils.GetViewResourceFromClusterRole,
)
clusterCache.cache = authCache

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package cache

import (
"testing"
"time"

clusterfake "github.com/open-cluster-management/api/client/cluster/clientset/versioned/fake"
clusterv1informers "github.com/open-cluster-management/api/client/cluster/informers/externalversions"
clusterv1 "github.com/open-cluster-management/api/cluster/v1"
Expand All @@ -12,8 +15,6 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"testing"
"time"
)

var (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
clusterinformerv1alpha1 "github.com/open-cluster-management/api/client/cluster/informers/externalversions/cluster/v1alpha1"
clusterv1alpha1lister "github.com/open-cluster-management/api/client/cluster/listers/cluster/v1alpha1"
clusterv1alpha1 "github.com/open-cluster-management/api/cluster/v1alpha1"

v1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
Expand All @@ -23,27 +25,27 @@ type ClusterSetLister interface {
}

type ClusterSetCache struct {
cache *AuthCache
Cache *AuthCache
clusterSetLister clusterv1alpha1lister.ManagedClusterSetLister
}

func NewClusterSetCache(clusterSetInformer clusterinformerv1alpha1.ManagedClusterSetInformer,
clusterRoleInformer rbacv1informers.ClusterRoleInformer,
clusterRolebindingInformer rbacv1informers.ClusterRoleBindingInformer,
getResourceNamesFromClusterRole func(*v1.ClusterRole, string, string) (sets.String, bool),
) *ClusterSetCache {
clusterSetCache := &ClusterSetCache{
clusterSetLister: clusterSetInformer.Lister(),
}
authCache := NewAuthCache(clusterRoleInformer, clusterRolebindingInformer,
cache := NewAuthCache(clusterRoleInformer, clusterRolebindingInformer,
"cluster.open-cluster-management.io", "managedclustersets",
clusterSetInformer.Informer(),
clusterSetCache.ListResources,
getResourceNamesFromClusterRole,
)
clusterSetCache.cache = authCache

clusterSetCache.Cache = cache
return clusterSetCache
}

func (c *ClusterSetCache) ListResources() (sets.String, error) {
allClusterSets := sets.String{}
clusterSets, err := c.clusterSetLister.List(labels.Everything())
Expand All @@ -57,8 +59,13 @@ func (c *ClusterSetCache) ListResources() (sets.String, error) {
return allClusterSets, nil
}

// Run begins watching and synchronizing the cache
func (c *ClusterSetCache) Run(period time.Duration) {
go utilwait.Forever(func() { c.Cache.synchronize() }, period)
}

func (c *ClusterSetCache) List(userInfo user.Info, selector labels.Selector) (*clusterv1alpha1.ManagedClusterSetList, error) {
names := c.cache.listNames(userInfo)
names := c.Cache.listNames(userInfo)

clusterSetList := &clusterv1alpha1.ManagedClusterSetList{}
for key := range names {
Expand Down Expand Up @@ -96,14 +103,9 @@ func (c *ClusterSetCache) ConvertResource(name string) runtime.Object {
}

func (c *ClusterSetCache) RemoveWatcher(w CacheWatcher) {
c.cache.RemoveWatcher(w)
c.Cache.RemoveWatcher(w)
}

func (c *ClusterSetCache) AddWatcher(w CacheWatcher) {
c.cache.AddWatcher(w)
}

// Run begins watching and synchronizing the cache
func (c *ClusterSetCache) Run(period time.Duration) {
go utilwait.Forever(func() { c.cache.synchronize() }, period)
c.Cache.AddWatcher(w)
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package cache

import (
"testing"
"time"

clusterfake "github.com/open-cluster-management/api/client/cluster/clientset/versioned/fake"
clusterinformers "github.com/open-cluster-management/api/client/cluster/informers/externalversions"
clusterv1alpha1 "github.com/open-cluster-management/api/cluster/v1alpha1"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/utils"
"github.com/stretchr/testify/assert"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -12,8 +16,6 @@ import (
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"testing"
"time"
)

var (
Expand Down Expand Up @@ -177,6 +179,7 @@ func fakeNewClusterSetCache(stopCh chan struct{}) *ClusterSetCache {
clusterInformers.Cluster().V1alpha1().ManagedClusterSets(),
informers.Rbac().V1().ClusterRoles(),
informers.Rbac().V1().ClusterRoleBindings(),
utils.GetViewResourceFromClusterRole,
)

}
Expand Down Expand Up @@ -228,7 +231,7 @@ func TestClusterSetCacheList(t *testing.T) {
expectedClusterSets: sets.String{},
},
}
clusterSetCache.cache.synchronize()
clusterSetCache.Cache.synchronize()
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
clusterSetList, err := clusterSetCache.List(test.user, labels.Everything())
Expand Down
103 changes: 53 additions & 50 deletions pkg/proxyserver/cache/clusterview.go → pkg/cache/subjectrecord.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package cache

import (
"fmt"
"github.com/openshift/library-go/pkg/authorization/authorizationutil"
"k8s.io/klog/v2"
"strings"
"sync"

"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/cache/rbac"
"github.com/openshift/library-go/pkg/authorization/authorizationutil"
"k8s.io/klog/v2"

rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand All @@ -18,19 +18,19 @@ import (
"k8s.io/client-go/tools/cache"
)

// subjectRecord is a cache record for the set of resources a subject can access
type subjectRecord struct {
subject string
names sets.String
// SubjectRecord is a cache record for the set of resources a subject can access
type SubjectRecord struct {
Subject string
Names sets.String
}

// subjectRecordKeyFn is a key func for subjectRecord objects
// subjectRecordKeyFn is a key func for SubjectRecord objects
func subjectRecordKeyFn(obj interface{}) (string, error) {
subjectRecord, ok := obj.(*subjectRecord)
SubjectRecord, ok := obj.(*SubjectRecord)
if !ok {
return "", fmt.Errorf("expected subjectRecord")
return "", fmt.Errorf("expected SubjectRecord")
}
return subjectRecord.subject, nil
return SubjectRecord.Subject, nil
}

// LastSyncResourceVersioner is any object that can divulge a LastSyncResourceVersion
Expand Down Expand Up @@ -109,7 +109,8 @@ type AuthCache struct {
userSubjectRecordStore cache.Store
groupSubjectRecordStore cache.Store

syncResources func() (sets.String, error)
syncResources func() (sets.String, error)
getResourceNamesFromClusterRole func(*rbacv1.ClusterRole, string, string) (sets.String, bool)

group string
resource string
Expand All @@ -123,6 +124,7 @@ func NewAuthCache(clusterRoleInformer rbacv1informers.ClusterRoleInformer,
group, resource string,
lastSyncResourceVersioner LastSyncResourceVersioner,
syncResourcesFunc func() (sets.String, error),
getResourceNamesFromClusterRole func(*rbacv1.ClusterRole, string, string) (sets.String, bool),
) *AuthCache {
scrLister := syncedClusterRoleLister{
clusterRoleInformer.Lister(),
Expand All @@ -144,8 +146,9 @@ func NewAuthCache(clusterRoleInformer rbacv1informers.ClusterRoleInformer,

userSubjectRecordStore: cache.NewStore(subjectRecordKeyFn),
groupSubjectRecordStore: cache.NewStore(subjectRecordKeyFn),
skip: &statelessSkipSynchronizer{},

skip: &statelessSkipSynchronizer{},
getResourceNamesFromClusterRole: getResourceNamesFromClusterRole,

watchers: []CacheWatcher{},
}
Expand Down Expand Up @@ -198,7 +201,7 @@ func (ac *AuthCache) synchronizeClusterRoleBindings(userSubjectRecordStore cache
if err != nil {
continue
}
resources, all := getResourceNamesFromClusterRole(clusterRole, ac.group, ac.resource)
resources, all := ac.getResourceNamesFromClusterRole(clusterRole, ac.group, ac.resource)
if all {
resources = ac.knownResources
}
Expand Down Expand Up @@ -256,22 +259,48 @@ func (ac *AuthCache) synchronizeClusterRoleBindings(userSubjectRecordStore cache
ac.knownGroups = newAllGroups
}

func (ac *AuthCache) GetUserSubjectRecord() []*SubjectRecord {
if ac == nil || ac.userSubjectRecordStore == nil {
return []*SubjectRecord{}
}
subjectRecordStore := ac.userSubjectRecordStore.List()
var returnSubjectRecord []*SubjectRecord
for _, subjectRecord := range subjectRecordStore {
s := subjectRecord.(*SubjectRecord)
returnSubjectRecord = append(returnSubjectRecord, s)
}
return returnSubjectRecord
}

func (ac *AuthCache) GetGroupSubjectRecord() []*SubjectRecord {
if ac == nil || ac.userSubjectRecordStore == nil {
return []*SubjectRecord{}
}
subjectRecordStore := ac.groupSubjectRecordStore.List()
var returnSubjectRecord []*SubjectRecord
for _, subjectRecord := range subjectRecordStore {
s := subjectRecord.(*SubjectRecord)
returnSubjectRecord = append(returnSubjectRecord, s)
}
return returnSubjectRecord
}

func (ac *AuthCache) listNames(userInfo user.Info) sets.String {
keys := sets.String{}
user := userInfo.GetName()
groups := userInfo.GetGroups()

obj, exists, _ := ac.userSubjectRecordStore.GetByKey(user)
if exists {
subjectRecord := obj.(*subjectRecord)
keys.Insert(subjectRecord.names.List()...)
SubjectRecord := obj.(*SubjectRecord)
keys.Insert(SubjectRecord.Names.List()...)
}

for _, group := range groups {
obj, exists, _ := ac.groupSubjectRecordStore.GetByKey(group)
if exists {
subjectRecord := obj.(*subjectRecord)
keys.Insert(subjectRecord.names.List()...)
SubjectRecord := obj.(*SubjectRecord)
keys.Insert(SubjectRecord.Names.List()...)
}
}

Expand Down Expand Up @@ -311,13 +340,13 @@ func (ac *AuthCache) notifyWatchers(names, users, groups sets.String) {
}

func updateResourcesToSubject(subjectRecordStore cache.Store, subject string, names sets.String) {
var item *subjectRecord
var item *SubjectRecord
obj, exists, _ := subjectRecordStore.GetByKey(subject)
if exists {
item = obj.(*subjectRecord)
item.names = names
item = obj.(*SubjectRecord)
item.Names = names
} else {
item = &subjectRecord{subject: subject, names: names}
item = &SubjectRecord{Subject: subject, Names: names}
subjectRecordStore.Add(item)
}
return
Expand All @@ -326,35 +355,9 @@ func updateResourcesToSubject(subjectRecordStore cache.Store, subject string, na
func deleteSubject(subjectRecordStore cache.Store, subject string) {
obj, exists, _ := subjectRecordStore.GetByKey(subject)
if exists {
subjectRecord := obj.(*subjectRecord)
subjectRecordStore.Delete(subjectRecord)
SubjectRecord := obj.(*SubjectRecord)
subjectRecordStore.Delete(SubjectRecord)
}

return
}

func getResourceNamesFromClusterRole(clusterRole *rbacv1.ClusterRole, group, resource string) (sets.String, bool) {
names := sets.NewString()
all := false
for _, rule := range clusterRole.Rules {
if !rbac.APIGroupMatches(&rule, group) {
continue
}

if !rbac.VerbMatches(&rule, "get") && !rbac.VerbMatches(&rule, "list") && !rbac.VerbMatches(&rule, "*") {
continue
}

if len(rule.ResourceNames) == 0 {
all = true
return names, all
}

if !rbac.ResourceMatches(&rule, resource, "") {
continue
}

names.Insert(rule.ResourceNames...)
}
return names, all
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package cache

import (
"testing"
"time"

clusterfake "github.com/open-cluster-management/api/client/cluster/clientset/versioned/fake"
clusterv1informers "github.com/open-cluster-management/api/client/cluster/informers/externalversions"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/utils"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"testing"
"time"
)

func validateSet(set, expectedSet sets.String) bool {
Expand Down Expand Up @@ -45,6 +47,7 @@ func TestSyncManagedClusterCache(t *testing.T) {
"cluster.open-cluster-management.io", "managedclusters",
clusterInformers.Cluster().V1().ManagedClusters().Informer(),
clusterCache.ListResources,
utils.GetViewResourceFromClusterRole,
)

autheCache.synchronize()
Expand Down
File renamed without changes.
File renamed without changes.
7 changes: 5 additions & 2 deletions pkg/proxyserver/api/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ package api

import (
"context"
"time"

clusterclient "github.com/open-cluster-management/api/client/cluster/clientset/versioned"
clusterinformers "github.com/open-cluster-management/api/client/cluster/informers/externalversions"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/cache"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/cache"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/rest/log"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/rest/managedcluster"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/rest/managedclusterset"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/rest/proxy"
"github.com/open-cluster-management/multicloud-operators-foundation/pkg/utils"
"k8s.io/client-go/informers"
"time"

apisclusterview "github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/apis/clusterview"
clusterviewv1 "github.com/open-cluster-management/multicloud-operators-foundation/pkg/proxyserver/apis/clusterview/v1"
Expand Down Expand Up @@ -82,6 +84,7 @@ func installClusterViewGroup(server *genericapiserver.GenericAPIServer,
clusterInformer.Cluster().V1alpha1().ManagedClusterSets(),
informerFactory.Rbac().V1().ClusterRoles(),
informerFactory.Rbac().V1().ClusterRoleBindings(),
utils.GetViewResourceFromClusterRole,
)

v1alpha1storage := map[string]rest.Storage{
Expand Down
Loading

0 comments on commit 1608b12

Please sign in to comment.