diff --git a/pkg/auth/cleanup/service_test.go b/pkg/auth/cleanup/service_test.go index 7aa6978cb16..7f4c5ea1373 100644 --- a/pkg/auth/cleanup/service_test.go +++ b/pkg/auth/cleanup/service_test.go @@ -292,7 +292,6 @@ func newMockCleanupService(t *testing.T, func getSecretControllerMock(ctrl *gomock.Controller, store map[string]*corev1.Secret) wcorev1.SecretController { secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) - secretController.EXPECT().Create(gomock.Any()).DoAndReturn(func(secret *corev1.Secret) (*corev1.Secret, error) { if secret.Name == "" { uniqueIdentifier := md5.Sum([]byte(time.Now().String())) diff --git a/pkg/controllers/management/auth/legacy_grb_cleaner.go b/pkg/controllers/management/auth/legacy_grb_cleaner.go index 926c2b61a74..115f5eeb104 100644 --- a/pkg/controllers/management/auth/legacy_grb_cleaner.go +++ b/pkg/controllers/management/auth/legacy_grb_cleaner.go @@ -31,7 +31,7 @@ func (p *grbCleaner) sync(key string, obj *v3.GlobalRoleBinding) (runtime.Object } cleanedObj := gbrCleanUp(obj) - return p.mgmt.Management.GlobalRoleBindings("").Update(cleanedObj) + return p.mgmt.Wrangler.Mgmt.GlobalRoleBinding().Update(cleanedObj) } // gbrCleanUp returns a clean GlobalRoleBinding based on filters specified within the function diff --git a/pkg/controllers/management/auth/legacy_rt_cleaner.go b/pkg/controllers/management/auth/legacy_rt_cleaner.go index 190f095d6b2..e1a052c8e24 100644 --- a/pkg/controllers/management/auth/legacy_rt_cleaner.go +++ b/pkg/controllers/management/auth/legacy_rt_cleaner.go @@ -2,25 +2,26 @@ package auth import ( "github.com/rancher/rancher/pkg/api/norman/store/roletemplate" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" "k8s.io/apimachinery/pkg/runtime" ) type rtCleaner struct { - clusterLister v3.ClusterLister - mgmt *config.ManagementContext + roleTemplates v3.RoleTemplateController + clusterLister v3.ClusterController } func newLegacyRTCleaner(mgmt *config.ManagementContext) *rtCleaner { return &rtCleaner{ - mgmt: mgmt, - clusterLister: mgmt.Management.Clusters("").Controller().Lister(), + roleTemplates: mgmt.Wrangler.Mgmt.RoleTemplate(), + clusterLister: mgmt.Wrangler.Mgmt.Cluster(), } } // sync cleans up all roleTemplates to drop cluster-scoped lifecycle handler finalizers -func (p *rtCleaner) sync(key string, obj *v3.RoleTemplate) (runtime.Object, error) { +func (p *rtCleaner) sync(key string, obj *wv3.RoleTemplate) (runtime.Object, error) { if key == "" || obj == nil { return nil, nil } @@ -29,11 +30,11 @@ func (p *rtCleaner) sync(key string, obj *v3.RoleTemplate) (runtime.Object, erro } cleanedObj := rtCleanUp(obj) - return p.mgmt.Management.RoleTemplates("").Update(cleanedObj) + return p.roleTemplates.Update(cleanedObj) } // rtCleanUp returns a clean RoleTemplate based on filters specified within the function -func rtCleanUp(obj *v3.RoleTemplate) *v3.RoleTemplate { +func rtCleanUp(obj *wv3.RoleTemplate) *wv3.RoleTemplate { obj.SetFinalizers(cleanFinalizers(obj.GetFinalizers(), "clusterscoped.controller.cattle.io/cluster-roletemplate-sync_")) cleanAnnotations := cleanAnnotations(obj.GetAnnotations(), "lifecycle.cattle.io/create.cluster-roletemplate-sync_") diff --git a/pkg/controllers/management/auth/token.go b/pkg/controllers/management/auth/token.go index fe2504e1347..0fe49a1e501 100644 --- a/pkg/controllers/management/auth/token.go +++ b/pkg/controllers/management/auth/token.go @@ -1,9 +1,10 @@ package auth import ( + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" tokenUtil "github.com/rancher/rancher/pkg/auth/tokens" "github.com/rancher/rancher/pkg/features" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wrangmgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" @@ -14,16 +15,16 @@ const ( ) type TokenController struct { - tokens v3.TokenInterface - userAttributes v3.UserAttributeInterface - userAttributesLister v3.UserAttributeLister + tokens wrangmgmtv3.TokenController + userAttributes wrangmgmtv3.UserAttributeController + userAttributesLister wrangmgmtv3.UserAttributeCache } func newTokenController(mgmt *config.ManagementContext) *TokenController { n := &TokenController{ - tokens: mgmt.Management.Tokens(""), - userAttributes: mgmt.Management.UserAttributes(""), - userAttributesLister: mgmt.Management.UserAttributes("").Controller().Lister(), + tokens: mgmt.Wrangler.Mgmt.Token(), + userAttributes: mgmt.Wrangler.Mgmt.UserAttribute(), + userAttributesLister: mgmt.Wrangler.Mgmt.UserAttribute().Cache(), } return n } @@ -104,7 +105,7 @@ func (t *TokenController) userAttributesNeedsRefresh(user string) (bool, error) return false, nil } - userAttribute, err := t.userAttributesLister.Get("", user) + userAttribute, err := t.userAttributesLister.Get(user) if err != nil { if errors.IsNotFound(err) { return false, nil @@ -115,7 +116,7 @@ func (t *TokenController) userAttributesNeedsRefresh(user string) (bool, error) } func (t *TokenController) triggerUserAttributesRefresh(user string) error { - userAttribute, err := t.userAttributesLister.Get("", user) + userAttribute, err := t.userAttributesLister.Get(user) if err != nil { return err } diff --git a/pkg/controllers/management/auth/token_test.go b/pkg/controllers/management/auth/token_test.go index c9745201b67..78f64bde30d 100644 --- a/pkg/controllers/management/auth/token_test.go +++ b/pkg/controllers/management/auth/token_test.go @@ -9,8 +9,9 @@ import ( tokens2 "github.com/rancher/rancher/pkg/auth/tokens" "github.com/rancher/rancher/pkg/auth/tokens/hashers" "github.com/rancher/rancher/pkg/features" - "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -29,36 +30,53 @@ func TestSync(t *testing.T) { tokens := make(map[string]*v3.Token) userAttributes := make(map[string]*v3.UserAttribute) - testTokenController := TokenController{ - tokens: &fakes.TokenInterfaceMock{ - UpdateFunc: func(token *v3.Token) (*v3.Token, error) { - tokens[token.Name] = token.DeepCopy() + ctrl := gomock.NewController(t) + + // setup tokens mock instance + tokensMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v3.Token, *v3.TokenList](ctrl) + tokensMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + ).AnyTimes() + tokensMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn( + func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { return token, nil - }, - GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { - token, ok := tokens[name] - if ok { - return token, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, - userAttributes: &fakes.UserAttributeInterfaceMock{ - UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { - userAttributes[userAttribute.Name] = userAttribute.DeepCopy() - return userAttribute, nil - }, + ).AnyTimes() + + // setup userAttribute mock instance + userAttributesMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributesMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil }, - userAttributesLister: &fakes.UserAttributeListerMock{ - GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { - userAttribute, ok := userAttributes[name] - if ok { - return userAttribute, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + ) + + // setup userAttributesLister mock instance + userAttributesListerMock := wranglerfake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributesListerMock.EXPECT().Get(gomock.Any()).DoAndReturn( + func(name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, + ).AnyTimes() + + testTokenController := TokenController{ + tokens: tokensMock, + userAttributes: userAttributesMock, + userAttributesLister: userAttributesListerMock, } + testCases := populateTestCases(tokens, userAttributes) for _, testcase := range testCases { testErr := fmt.Sprintf("test case failed: %s", testcase.description) @@ -82,39 +100,53 @@ func TestSync(t *testing.T) { if testcase.inputUserAttribute == nil { continue } - returnUserAttribute, _ := testTokenController.userAttributesLister.Get("", testcase.inputUserAttribute.Name) + returnUserAttribute, _ := testTokenController.userAttributesLister.Get(testcase.inputUserAttribute.Name) assert.Equalf(t, testcase.expectedOutputUserAttribute, returnUserAttribute, fmt.Sprintf("%s", testcase.inputToken.Name), testErr) } // test error from token update - testTokenErrorUpdateController := TokenController{ - tokens: &fakes.TokenInterfaceMock{ - UpdateFunc: func(token *v3.Token) (*v3.Token, error) { - return nil, errors.NewServiceUnavailable("test reason") - }, - GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { - token, ok := tokens[name] - if ok { - return token, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + // setup tokens mock instance + tokensMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.Token, *v3.TokenList](ctrl) + tokensMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(token *v3.Token) (*v3.Token, error) { + return nil, errors.NewServiceUnavailable("test reason") }, - userAttributes: &fakes.UserAttributeInterfaceMock{ - UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { - userAttributes[userAttribute.Name] = userAttribute.DeepCopy() - return userAttribute, nil - }, + ).AnyTimes() + tokensMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn( + func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { + return token, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, - userAttributesLister: &fakes.UserAttributeListerMock{ - GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { - userAttribute, ok := userAttributes[name] - if ok { - return userAttribute, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + ).AnyTimes() + + // setup userAttribute mock instance + userAttributesMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributesMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil + }, + ).AnyTimes() + + // setup userAttributesLister mock instance + userAttributesListerMock = wranglerfake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributesListerMock.EXPECT().Get(gomock.Any()).DoAndReturn( + func(name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, + ).AnyTimes() + + testTokenErrorUpdateController := TokenController{ + tokens: tokensMock, + userAttributes: userAttributesMock, + userAttributesLister: userAttributesListerMock, } genericTestToken := &v3.Token{ ObjectMeta: metav1.ObjectMeta{ @@ -128,35 +160,50 @@ func TestSync(t *testing.T) { assert.NotNilf(t, err, "handler should return err when token client's update function returns error") // test error from userattribute update - testUserAttributeErrorUpdateController := TokenController{ - tokens: &fakes.TokenInterfaceMock{ - UpdateFunc: func(token *v3.Token) (*v3.Token, error) { - tokens[token.Name] = token.DeepCopy() + // setup tokens mock instance + tokensMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.Token, *v3.TokenList](ctrl) + tokensMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + ).AnyTimes() + tokensMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn( + func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { return token, nil - }, - GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { - token, ok := tokens[name] - if ok { - return token, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, - userAttributes: &fakes.UserAttributeInterfaceMock{ - UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { - return nil, errors.NewServiceUnavailable("test reason") - }, + ).AnyTimes() + + // setup userAttribute mock instance + userAttributesMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributesMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + return nil, errors.NewServiceUnavailable("test reason") }, - userAttributesLister: &fakes.UserAttributeListerMock{ - GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { - userAttribute, ok := userAttributes[name] - if ok { - return userAttribute, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + ) + + // setup userAttributesLister mock instance + userAttributesListerMock = wranglerfake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributesListerMock.EXPECT().Get(gomock.Any()).DoAndReturn( + func(name string) (*v3.UserAttribute, error) { + userAttribute, ok := userAttributes[name] + if ok { + return userAttribute, nil + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, + ).AnyTimes() + + testUserAttributeErrorUpdateController := TokenController{ + tokens: tokensMock, + userAttributes: userAttributesMock, + userAttributesLister: userAttributesListerMock, } + genericTestToken = &v3.Token{ ObjectMeta: metav1.ObjectMeta{ Name: "testtoken", @@ -176,32 +223,47 @@ func TestSync(t *testing.T) { assert.NotNilf(t, err, "handler should return err when userattribute client's update function returns error") // test non-notfound error from userattribute lister get - testUserAttributeErrorGetController := TokenController{ - tokens: &fakes.TokenInterfaceMock{ - UpdateFunc: func(token *v3.Token) (*v3.Token, error) { - tokens[token.Name] = token.DeepCopy() + // setup tokens mock instance + tokensMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.Token, *v3.TokenList](ctrl) + tokensMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + ).AnyTimes() + tokensMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn( + func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { return token, nil - }, - GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { - token, ok := tokens[name] - if ok { - return token, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, - userAttributes: &fakes.UserAttributeInterfaceMock{ - UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { - userAttributes[userAttribute.Name] = userAttribute.DeepCopy() - return userAttribute, nil - }, + ).AnyTimes() + + // setup userAttribute mock instance + userAttributesMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributesMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil }, - userAttributesLister: &fakes.UserAttributeListerMock{ - GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { - return nil, errors.NewServiceUnavailable("test reason") - }, + ).AnyTimes() + + // setup userAttributesLister mock instance + userAttributesListerMock = wranglerfake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributesListerMock.EXPECT().Get(gomock.Any()).DoAndReturn( + func(name string) (*v3.UserAttribute, error) { + return nil, errors.NewServiceUnavailable("test reason") }, + ) + + testUserAttributeErrorGetController := TokenController{ + tokens: tokensMock, + userAttributes: userAttributesMock, + userAttributesLister: userAttributesListerMock, } + genericTestToken = &v3.Token{ ObjectMeta: metav1.ObjectMeta{ Name: "testtoken", @@ -213,32 +275,47 @@ func TestSync(t *testing.T) { assert.NotNilf(t, err, "handler should return err when userattribute lister's get function returns non-notfound error") // test notfound error from userattribute lister get - testUserAttributeErrorGetController = TokenController{ - tokens: &fakes.TokenInterfaceMock{ - UpdateFunc: func(token *v3.Token) (*v3.Token, error) { - tokens[token.Name] = token.DeepCopy() + // setup tokens mock instance + tokensMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.Token, *v3.TokenList](ctrl) + tokensMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(token *v3.Token) (*v3.Token, error) { + tokens[token.Name] = token.DeepCopy() + return token, nil + }, + ).AnyTimes() + tokensMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn( + func(name string, opts metav1.GetOptions) (*v3.Token, error) { + token, ok := tokens[name] + if ok { return token, nil - }, - GetFunc: func(name string, opts metav1.GetOptions) (*v3.Token, error) { - token, ok := tokens[name] - if ok { - return token, nil - } - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + } + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, - userAttributes: &fakes.UserAttributeInterfaceMock{ - UpdateFunc: func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { - userAttributes[userAttribute.Name] = userAttribute.DeepCopy() - return userAttribute, nil - }, + ).AnyTimes() + + // setup userAttribute mock instance + userAttributesMock = wranglerfake.NewMockNonNamespacedControllerInterface[*v3.UserAttribute, *v3.UserAttributeList](ctrl) + userAttributesMock.EXPECT().Update(gomock.Any()).DoAndReturn( + func(userAttribute *v3.UserAttribute) (*v3.UserAttribute, error) { + userAttributes[userAttribute.Name] = userAttribute.DeepCopy() + return userAttribute, nil }, - userAttributesLister: &fakes.UserAttributeListerMock{ - GetFunc: func(namespace string, name string) (*v3.UserAttribute, error) { - return nil, errors.NewNotFound(schema.GroupResource{}, name) - }, + ).AnyTimes() + + // setup userAttributesLister mock instance + userAttributesListerMock = wranglerfake.NewMockNonNamespacedCacheInterface[*v3.UserAttribute](ctrl) + userAttributesListerMock.EXPECT().Get(gomock.Any()).DoAndReturn( + func(name string) (*v3.UserAttribute, error) { + return nil, errors.NewNotFound(schema.GroupResource{}, name) }, + ) + + testUserAttributeErrorGetController = TokenController{ + tokens: tokensMock, + userAttributes: userAttributesMock, + userAttributesLister: userAttributesListerMock, } + genericTestToken = &v3.Token{ ObjectMeta: metav1.ObjectMeta{ Name: "testtoken", diff --git a/pkg/controllers/management/auth/user.go b/pkg/controllers/management/auth/user.go index d24d9b9abc5..1279929f15a 100644 --- a/pkg/controllers/management/auth/user.go +++ b/pkg/controllers/management/auth/user.go @@ -8,12 +8,12 @@ import ( "github.com/rancher/rancher/pkg/controllers" "github.com/rancher/rancher/pkg/controllers/management/auth/project_cluster" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/clustermanager" wranglerv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" - v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" "github.com/rancher/rancher/pkg/user" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/sirupsen/logrus" v12 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -23,24 +23,24 @@ import ( ) type userLifecycle struct { - prtb v3.ProjectRoleTemplateBindingInterface - crtb v3.ClusterRoleTemplateBindingInterface + prtb wranglerv3.ProjectRoleTemplateBindingController + crtb wranglerv3.ClusterRoleTemplateBindingController grb wranglerv3.GlobalRoleBindingController - users v3.UserInterface - tokens v3.TokenInterface - namespaces v1.NamespaceInterface - namespaceLister v1.NamespaceLister - secrets v1.SecretInterface - secretsLister v1.SecretLister - prtbLister v3.ProjectRoleTemplateBindingLister - crtbLister v3.ClusterRoleTemplateBindingLister - grbLister v3.GlobalRoleBindingLister + users wranglerv3.UserController + tokens wranglerv3.TokenController + namespaces wcorev1.NamespaceController + namespaceLister wcorev1.NamespaceCache + secrets wcorev1.SecretController + secretsLister wcorev1.SecretCache + prtbLister wranglerv3.ProjectRoleTemplateBindingCache + crtbLister wranglerv3.ClusterRoleTemplateBindingCache + grbLister wranglerv3.GlobalRoleBindingCache prtbIndexer cache.Indexer crtbIndexer cache.Indexer grbIndexer cache.Indexer tokenIndexer cache.Indexer userManager user.Manager - clusterLister v3.ClusterLister + clusterLister wranglerv3.ClusterCache clusterManager *clustermanager.Manager } @@ -54,17 +54,17 @@ const ( func newUserLifecycle(management *config.ManagementContext, clusterManager *clustermanager.Manager) *userLifecycle { lfc := &userLifecycle{ - prtb: management.Management.ProjectRoleTemplateBindings(""), - crtb: management.Management.ClusterRoleTemplateBindings(""), + prtb: management.Wrangler.Mgmt.ProjectRoleTemplateBinding(), + crtb: management.Wrangler.Mgmt.ClusterRoleTemplateBinding(), grb: management.Wrangler.Mgmt.GlobalRoleBinding(), - users: management.Management.Users(""), - tokens: management.Management.Tokens(""), - namespaces: management.Core.Namespaces(""), - secrets: management.Core.Secrets(""), - secretsLister: management.Core.Secrets("").Controller().Lister(), - namespaceLister: management.Core.Namespaces("").Controller().Lister(), + users: management.Wrangler.Mgmt.User(), + tokens: management.Wrangler.Mgmt.Token(), + namespaces: management.Wrangler.Core.Namespace(), + secrets: management.Wrangler.Core.Secret(), + secretsLister: management.Wrangler.Core.Secret().Cache(), + namespaceLister: management.Wrangler.Core.Namespace().Cache(), userManager: management.UserManager, - clusterLister: management.Management.Clusters("").Controller().Lister(), + clusterLister: management.Wrangler.Mgmt.Cluster().Cache(), clusterManager: clusterManager, } @@ -310,13 +310,8 @@ func (l *userLifecycle) getTokensByUserName(username string) ([]*v3.Token, error func (l *userLifecycle) deleteAllCRTB(crtbs []*v3.ClusterRoleTemplateBinding) error { for _, crtb := range crtbs { var err error - if crtb.Namespace == "" { - logrus.Infof("[%v] Deleting clusterRoleTemplateBinding %v for user %v", userController, crtb.Name, crtb.UserName) - err = l.crtb.Delete(crtb.Name, &metav1.DeleteOptions{}) - } else { - logrus.Infof("[%v] Deleting clusterRoleTemplateBinding %v for user %v", userController, crtb.Name, crtb.UserName) - err = l.crtb.DeleteNamespaced(crtb.Namespace, crtb.Name, &metav1.DeleteOptions{}) - } + logrus.Infof("[%v] Deleting clusterRoleTemplateBinding %v for user %v", userController, crtb.Name, crtb.UserName) + err = l.crtb.Delete(crtb.Namespace, crtb.Name, &metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("error deleting cluster role: %v", err) } @@ -328,13 +323,8 @@ func (l *userLifecycle) deleteAllCRTB(crtbs []*v3.ClusterRoleTemplateBinding) er func (l *userLifecycle) deleteAllPRTB(prtbs []*v3.ProjectRoleTemplateBinding) error { for _, prtb := range prtbs { var err error - if prtb.Namespace == "" { - logrus.Infof("[%v] Deleting projectRoleTemplateBinding %v for user %v", userController, prtb.Name, prtb.UserName) - err = l.prtb.Delete(prtb.Name, &metav1.DeleteOptions{}) - } else { - logrus.Infof("[%v] Deleting projectRoleTemplateBinding %v for user %v", userController, prtb.Name, prtb.UserName) - err = l.prtb.DeleteNamespaced(prtb.Namespace, prtb.Name, &metav1.DeleteOptions{}) - } + logrus.Infof("[%v] Deleting projectRoleTemplateBinding %v for user %v", userController, prtb.Name, prtb.UserName) + err = l.prtb.Delete(prtb.Namespace, prtb.Name, &metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("error deleting projet role: %v", err) } @@ -369,7 +359,7 @@ func (l *userLifecycle) deleteClusterUserAttributes(username string, tokens []*v // find the set of clusters associated with a list of tokens set := make(map[string]*v3.Cluster) for _, token := range tokens { - cluster, err := l.clusterLister.Get("", token.ClusterName) + cluster, err := l.clusterLister.Get(token.ClusterName) if err != nil { if errors.IsNotFound(err) { continue @@ -395,7 +385,7 @@ func (l *userLifecycle) deleteClusterUserAttributes(username string, tokens []*v func (l *userLifecycle) deleteAllTokens(tokens []*v3.Token) error { for _, token := range tokens { logrus.Infof("[%v] Deleting token %v for user %v", userController, token.Name, token.UserID) - err := l.tokens.DeleteNamespaced(token.Namespace, token.Name, &metav1.DeleteOptions{}) + err := l.tokens.Delete(token.Name, &metav1.DeleteOptions{}) if err != nil { return fmt.Errorf("error deleting token: %v", err) } @@ -405,7 +395,7 @@ func (l *userLifecycle) deleteAllTokens(tokens []*v3.Token) error { } func (l *userLifecycle) deleteUserNamespace(username string) error { - namespace, err := l.namespaceLister.Get("", username) + namespace, err := l.namespaceLister.Get(username) if err != nil { if errors.IsNotFound(err) { return nil // nothing to delete @@ -437,7 +427,7 @@ func (l *userLifecycle) deleteUserSecret(username string) error { } logrus.Infof("[%v] Deleting secret backing user %v", userController, username) - return l.secrets.DeleteNamespaced("cattle-system", username+"-secret", &metav1.DeleteOptions{}) + return l.secrets.Delete("cattle-system", username+"-secret", &metav1.DeleteOptions{}) } func (l *userLifecycle) removeLegacyFinalizers(user *v3.User) (*v3.User, error) { diff --git a/pkg/controllers/management/auth/user_test.go b/pkg/controllers/management/auth/user_test.go index d896a7fe122..1e7707858f5 100644 --- a/pkg/controllers/management/auth/user_test.go +++ b/pkg/controllers/management/auth/user_test.go @@ -5,14 +5,13 @@ import ( "testing" management "github.com/rancher/rancher/pkg/apis/management.cattle.io" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" fakes "github.com/rancher/rancher/pkg/controllers/management/auth/fakes" "github.com/rancher/rancher/pkg/controllers/management/auth/project_cluster" - coreFakes "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" - managementFakes "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3/fakes" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" - v12 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -258,16 +257,10 @@ func TestUpdated(t *testing.T) { } func Test_deleteAllCRTB(t *testing.T) { - ctrbMock := &managementFakes.ClusterRoleTemplateBindingInterfaceMock{} - - ul := &userLifecycle{ - crtb: ctrbMock, - } - tests := []struct { name string inputCRTB []*v3.ClusterRoleTemplateBinding - mockSetup func() + mockSetup func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) expectedError bool }{ { @@ -279,10 +272,8 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) }, expectedError: false, }, @@ -300,10 +291,8 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) }, expectedError: false, }, @@ -323,10 +312,8 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) }, expectedError: false, }, @@ -345,13 +332,8 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } - ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) }, expectedError: false, }, @@ -370,13 +352,11 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } - ctrbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("namespaced crtb not deleted") - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + gomock.InOrder( + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil), + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("namespaced crtb not deleted")), + ) }, expectedError: true, }, @@ -389,10 +369,8 @@ func Test_deleteAllCRTB(t *testing.T) { }, }, }, - mockSetup: func() { - ctrbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("some error") - } + mockSetup: func(crtbMock *wranglerfake.MockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList]) { + crtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("some error")) }, expectedError: true, }, @@ -400,7 +378,14 @@ func Test_deleteAllCRTB(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.mockSetup() + ctrl := gomock.NewController(t) + crtbMock := wranglerfake.NewMockControllerInterface[*v3.ClusterRoleTemplateBinding, *v3.ClusterRoleTemplateBindingList](ctrl) + + tt.mockSetup(crtbMock) + + ul := &userLifecycle{ + crtb: crtbMock, + } err := ul.deleteAllCRTB(tt.inputCRTB) @@ -414,16 +399,10 @@ func Test_deleteAllCRTB(t *testing.T) { } func Test_deleteAllPRTB(t *testing.T) { - prtbMock := &managementFakes.ProjectRoleTemplateBindingInterfaceMock{} - - ul := &userLifecycle{ - prtb: prtbMock, - } - tests := []struct { name string inputPRTB []*v3.ProjectRoleTemplateBinding - mockSetup func() + mockSetup func(*wranglerfake.MockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList]) expectedError bool }{ { @@ -437,10 +416,8 @@ func Test_deleteAllPRTB(t *testing.T) { }, }, }, - mockSetup: func() { - prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(prtbMock *wranglerfake.MockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList]) { + prtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, expectedError: false, }, @@ -461,13 +438,8 @@ func Test_deleteAllPRTB(t *testing.T) { }, }, }, - mockSetup: func() { - prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return nil - } - prtbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } + mockSetup: func(prtbMock *wranglerfake.MockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList]) { + prtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(2) }, expectedError: false, }, @@ -482,10 +454,8 @@ func Test_deleteAllPRTB(t *testing.T) { }, }, }, - mockSetup: func() { - prtbMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("some error") - } + mockSetup: func(prtbMock *wranglerfake.MockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList]) { + prtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("some error")) }, expectedError: true, }, @@ -499,10 +469,8 @@ func Test_deleteAllPRTB(t *testing.T) { }, }, }, - mockSetup: func() { - prtbMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("some error") - } + mockSetup: func(prtbMock *wranglerfake.MockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList]) { + prtbMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("some error")) }, expectedError: true, }, @@ -510,8 +478,14 @@ func Test_deleteAllPRTB(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tt.mockSetup() + ctrl := gomock.NewController(t) + prtbMock := wranglerfake.NewMockControllerInterface[*v3.ProjectRoleTemplateBinding, *v3.ProjectRoleTemplateBindingList](ctrl) + + tt.mockSetup(prtbMock) + ul := &userLifecycle{ + prtb: prtbMock, + } err := ul.deleteAllPRTB(tt.inputPRTB) if tt.expectedError { @@ -524,8 +498,9 @@ func Test_deleteAllPRTB(t *testing.T) { } func Test_deleteUserNamespace(t *testing.T) { - namespaceMock := &coreFakes.NamespaceInterfaceMock{} - namespaceListerMock := &coreFakes.NamespaceListerMock{} + ctrl := gomock.NewController(t) + namespaceMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v1.Namespace, *v1.NamespaceList](ctrl) + namespaceListerMock := wranglerfake.NewMockNonNamespacedCacheInterface[*v1.Namespace](ctrl) ul := &userLifecycle{ namespaces: namespaceMock, @@ -542,12 +517,8 @@ func Test_deleteUserNamespace(t *testing.T) { name: "delete namespace", username: "testuser", mockSetup: func() { - namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { - return &v12.Namespace{}, nil - } - namespaceMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return nil - } + namespaceListerMock.EXPECT().Get(gomock.Any()).Return(&v1.Namespace{}, nil) + namespaceMock.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(nil) }, expectedError: false, }, @@ -555,9 +526,7 @@ func Test_deleteUserNamespace(t *testing.T) { name: "error getting namespace", username: "testuser", mockSetup: func() { - namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { - return nil, fmt.Errorf("some error") - } + namespaceListerMock.EXPECT().Get(gomock.Any()).Return(nil, fmt.Errorf("some error")) }, expectedError: true, }, @@ -565,12 +534,8 @@ func Test_deleteUserNamespace(t *testing.T) { name: "error deleting namespace", username: "testuser", mockSetup: func() { - namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { - return &v12.Namespace{}, nil - } - namespaceMock.DeleteFunc = func(name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("some error") - } + namespaceListerMock.EXPECT().Get(gomock.Any()).Return(&v1.Namespace{}, nil) + namespaceMock.EXPECT().Delete(gomock.Any(), gomock.Any()).Return(fmt.Errorf("some error")) }, expectedError: true, }, @@ -578,13 +543,11 @@ func Test_deleteUserNamespace(t *testing.T) { name: "namespace is in termination state", username: "testuser", mockSetup: func() { - namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { - return &v12.Namespace{ - Status: v12.NamespaceStatus{ - Phase: v12.NamespaceTerminating, - }, - }, nil - } + namespaceListerMock.EXPECT().Get(gomock.Any()).Return(&v1.Namespace{ + Status: v1.NamespaceStatus{ + Phase: v1.NamespaceTerminating, + }, + }, nil) }, expectedError: false, }, @@ -592,12 +555,10 @@ func Test_deleteUserNamespace(t *testing.T) { name: "namespace was not found", username: "testuser", mockSetup: func() { - namespaceListerMock.GetFunc = func(namespace, name string) (*v12.Namespace, error) { - return nil, errors.NewNotFound(schema.GroupResource{ - Group: management.GroupName, - Resource: "Namespace", - }, "testns") - } + namespaceListerMock.EXPECT().Get(gomock.Any()).Return(nil, errors.NewNotFound(schema.GroupResource{ + Group: management.GroupName, + Resource: "Namespace", + }, "testns")) }, expectedError: false, }, @@ -619,8 +580,9 @@ func Test_deleteUserNamespace(t *testing.T) { } func Test_deleteUserSecret(t *testing.T) { - secretsMock := &coreFakes.SecretInterfaceMock{} - secretsListerMock := &coreFakes.SecretListerMock{} + ctrl := gomock.NewController(t) + secretsMock := wranglerfake.NewMockControllerInterface[*v1.Secret, *v1.SecretList](ctrl) + secretsListerMock := wranglerfake.NewMockCacheInterface[*v1.Secret](ctrl) ul := &userLifecycle{ secrets: secretsMock, @@ -637,12 +599,8 @@ func Test_deleteUserSecret(t *testing.T) { name: "delete secret", username: "testuser", mockSetup: func() { - secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { - return &v12.Secret{}, nil - } - secretsMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return nil - } + secretsListerMock.EXPECT().Get(gomock.Any(), gomock.Any()).Return(&v1.Secret{}, nil) + secretsMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) }, expectedError: false, }, @@ -650,9 +608,7 @@ func Test_deleteUserSecret(t *testing.T) { name: "error getting secret", username: "testuser", mockSetup: func() { - secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { - return nil, fmt.Errorf("some error") - } + secretsListerMock.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("some error")) }, expectedError: true, }, @@ -660,12 +616,8 @@ func Test_deleteUserSecret(t *testing.T) { name: "error deleting secret", username: "testuser", mockSetup: func() { - secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { - return &v12.Secret{}, nil - } - secretsMock.DeleteNamespacedFunc = func(namespace, name string, options *metav1.DeleteOptions) error { - return fmt.Errorf("some error") - } + secretsListerMock.EXPECT().Get(gomock.Any(), gomock.Any()).Return(&v1.Secret{}, nil) + secretsMock.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(fmt.Errorf("some error")) }, expectedError: true, }, @@ -673,12 +625,10 @@ func Test_deleteUserSecret(t *testing.T) { name: "secret not found", username: "testuser", mockSetup: func() { - secretsListerMock.GetFunc = func(namespace, name string) (*v12.Secret, error) { - return nil, errors.NewNotFound(schema.GroupResource{ - Group: management.GroupName, - Resource: "Secrets", - }, "testsecret") - } + secretsListerMock.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, errors.NewNotFound(schema.GroupResource{ + Group: management.GroupName, + Resource: "Secrets", + }, "testsecret")) }, expectedError: false, }, @@ -700,7 +650,9 @@ func Test_deleteUserSecret(t *testing.T) { } func Test_removeLegacyFinalizers(t *testing.T) { - usersMock := &managementFakes.UserInterfaceMock{} + ctrl := gomock.NewController(t) + //usersMock := &managementFakes.UserInterfaceMock{} + usersMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) ul := &userLifecycle{ users: usersMock, @@ -737,16 +689,15 @@ func Test_removeLegacyFinalizers(t *testing.T) { }, }, mockSetup: func() { - usersMock.UpdateFunc = func(in1 *v3.User) (*v3.User, error) { - return &v3.User{ + usersMock.EXPECT().Update(gomock.Any()).Return( + &v3.User{ ObjectMeta: metav1.ObjectMeta{ Name: "testuser", Finalizers: []string{ "controller.cattle.io/test-finalizer", }, }, - }, nil - } + }, nil) }, expectedError: false, }, @@ -762,9 +713,7 @@ func Test_removeLegacyFinalizers(t *testing.T) { }, }, mockSetup: func() { - usersMock.UpdateFunc = func(in1 *v3.User) (*v3.User, error) { - return nil, fmt.Errorf("some error") - } + usersMock.EXPECT().Update(gomock.Any()).Return(nil, fmt.Errorf("some error")) }, expectedError: true, },