diff --git a/pkg/agent/clean/adunmigration/ldap.go b/pkg/agent/clean/adunmigration/ldap.go index 1169c6d1562..ef377a84544 100644 --- a/pkg/agent/clean/adunmigration/ldap.go +++ b/pkg/agent/clean/adunmigration/ldap.go @@ -2,6 +2,7 @@ package adunmigration import ( "bytes" + "context" "crypto/x509" "fmt" "os" @@ -11,6 +12,12 @@ import ( ldapv3 "github.com/go-ldap/ldap/v3" "github.com/pkg/errors" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + "github.com/rancher/rancher/pkg/auth/providers/common" + "github.com/rancher/rancher/pkg/auth/providers/common/ldap" + v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" + "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -18,12 +25,6 @@ import ( "k8s.io/apimachinery/pkg/util/wait" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - - v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" - "github.com/rancher/rancher/pkg/auth/providers/common" - "github.com/rancher/rancher/pkg/auth/providers/common/ldap" - v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" - "github.com/rancher/rancher/pkg/types/config" ) // Rancher 2.7.5 serialized binary GUIDs from LDAP using this pattern, so this @@ -183,7 +184,7 @@ func findLdapUser(guid string, lConn *ldapv3.Conn, adConfig *v3.ActiveDirectoryC func adConfiguration(sc *config.ScaledContext) (*v3.ActiveDirectoryConfig, error) { authConfigs := sc.Management.AuthConfigs("") - secrets := sc.Core.Secrets("") + secrets := sc.Wrangler.Core.Secret() authConfigObj, err := authConfigs.ObjectClient().UnstructuredClient().Get("activedirectory", metav1.GetOptions{}) if err != nil { @@ -260,6 +261,11 @@ func prepareClientContexts(clientConfig *restclient.Config) (*config.ScaledConte logrus.Errorf("[%v] failed to create scaled context: %v", migrateAdUserOperation, err) return nil, nil, err } + wc, err := wrangler.NewContext(context.Background(), nil, clientConfig) + if err != nil { + logrus.Errorf("[%v] failed to create wrangler context: %v", migrateAdUserOperation, err) + } + sc.Wrangler = wc adConfig, err := adConfiguration(sc) if err != nil { logrus.Errorf("[%v] failed to acquire ad configuration: %v", migrateAdUserOperation, err) diff --git a/pkg/auth/api/secrets/cleanup.go b/pkg/auth/api/secrets/cleanup.go index 8ad155a7d7d..17156f0e517 100644 --- a/pkg/auth/api/secrets/cleanup.go +++ b/pkg/auth/api/secrets/cleanup.go @@ -7,14 +7,14 @@ import ( "github.com/rancher/rancher/pkg/auth/providers/common" "github.com/rancher/rancher/pkg/auth/tokens" "github.com/rancher/rancher/pkg/catalog/utils" - corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // CleanupClientSecrets tries to delete common client secrets for each auth provider. -func CleanupClientSecrets(secretInterface corev1.SecretInterface, config *v3.AuthConfig) error { +func CleanupClientSecrets(secretInterface wcorev1.SecretController, config *v3.AuthConfig) error { if config == nil { return fmt.Errorf("cannot delete auth provider secrets if its config is nil") } @@ -61,8 +61,8 @@ func CleanupClientSecrets(secretInterface corev1.SecretInterface, config *v3.Aut // It is not possible to filter secrets easily by presence of specific key(s) in the data object. The method fetches all // Opaque secrets in the relevant namespace and looks at the target key in the data to find a secret that stores a user's // access token to delete. -func CleanupOAuthTokens(secretInterface corev1.SecretInterface, key string) error { - opaqueSecrets, err := secretInterface.ListNamespaced(tokens.SecretNamespace, metav1.ListOptions{FieldSelector: "type=Opaque"}) +func CleanupOAuthTokens(secretInterface wcorev1.SecretController, key string) error { + opaqueSecrets, err := secretInterface.List(tokens.SecretNamespace, metav1.ListOptions{FieldSelector: "type=Opaque"}) if err != nil && !apierrors.IsNotFound(err) { return fmt.Errorf("failed to fetch secrets to clean up: %w", err) } @@ -71,7 +71,7 @@ func CleanupOAuthTokens(secretInterface corev1.SecretInterface, key string) erro for i := range opaqueSecrets.Items { secret := &opaqueSecrets.Items[i] if _, keyPresent := secret.Data[key]; keyPresent { - err := secretInterface.DeleteNamespaced(tokens.SecretNamespace, secret.Name, &metav1.DeleteOptions{}) + err := secretInterface.Delete(tokens.SecretNamespace, secret.Name, &metav1.DeleteOptions{}) if err != nil && !apierrors.IsNotFound(err) { result = errors.Join(result, err) } diff --git a/pkg/auth/api/secrets/cleanup_test.go b/pkg/auth/api/secrets/cleanup_test.go index 8843644b7d7..9af29c64ec7 100644 --- a/pkg/auth/api/secrets/cleanup_test.go +++ b/pkg/auth/api/secrets/cleanup_test.go @@ -14,9 +14,11 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" - "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -24,13 +26,15 @@ import ( ) func TestCleanupClientSecretsNilConfig(t *testing.T) { - secrets := getSecretInterfaceMock(map[string]*corev1.Secret{}) + ctrl := gomock.NewController(t) + secrets := getSecretControllerMock(ctrl, map[string]*corev1.Secret{}) err := CleanupClientSecrets(secrets, nil) require.Error(t, err) } func TestCleanupClientSecretsUnknownConfig(t *testing.T) { - secrets := getSecretInterfaceMock(map[string]*corev1.Secret{}) + ctrl := gomock.NewController(t) + secrets := getSecretControllerMock(ctrl, map[string]*corev1.Secret{}) config := &v3.AuthConfig{ ObjectMeta: metav1.ObjectMeta{Name: "unknownConfig"}, @@ -57,7 +61,8 @@ func TestCleanupClientSecretsKnownConfig(t *testing.T) { oauthSecretName := "user123-secret" initialStore := map[string]*corev1.Secret{} - secrets := getSecretInterfaceMock(initialStore) + ctrl := gomock.NewController(t) + secrets := getSecretControllerMock(ctrl, initialStore) _, err := secrets.Create(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -87,30 +92,30 @@ func TestCleanupClientSecretsKnownConfig(t *testing.T) { }) assert.NoError(t, err) - s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + s, err := secrets.Get(common.SecretsNamespace, secretName1, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName1) - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName2, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName2) - s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + s, err = secrets.Get(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", oauthSecretName) err = CleanupClientSecrets(secrets, config) assert.NoError(t, err) t.Run("Cleanup deletes provider secrets", func(t *testing.T) { - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName1, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName1) assert.Nil(t, s, "expected the secret to be nil") - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName2, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName2) assert.Nil(t, s, "expected the secret to be nil") }) t.Run("Cleanup deletes OAuth secrets", func(t *testing.T) { - s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + s, err = secrets.Get(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", oauthSecretName) assert.Nil(t, s, "expected the secret to be nil") }) @@ -125,7 +130,8 @@ func TestCleanupDeprecatedSecretsKnownConfig(t *testing.T) { secretName := fmt.Sprintf("%s-%s", strings.ToLower(config.Name), "access-token") initialStore := map[string]*corev1.Secret{} - secrets := getSecretInterfaceMock(initialStore) + ctrl := gomock.NewController(t) + secrets := getSecretControllerMock(ctrl, initialStore) _, err := secrets.Create(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -135,58 +141,60 @@ func TestCleanupDeprecatedSecretsKnownConfig(t *testing.T) { }) assert.NoError(t, err) - s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName, metav1.GetOptions{}) + s, err := secrets.Get(common.SecretsNamespace, secretName, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName) err = CleanupClientSecrets(secrets, config) assert.NoError(t, err) - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName) assert.Nil(t, s, "expected the secret to be nil") } -func getSecretInterfaceMock(store map[string]*corev1.Secret) v1.SecretInterface { - secretInterfaceMock := &fakes.SecretInterfaceMock{} +func getSecretControllerMock(ctrl *gomock.Controller, store map[string]*corev1.Secret) wcorev1.SecretController { + secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) - secretInterfaceMock.CreateFunc = func(secret *corev1.Secret) (*corev1.Secret, error) { + secretController.EXPECT().Create(gomock.Any()).DoAndReturn(func(secret *corev1.Secret) (*corev1.Secret, error) { if secret.Name == "" { uniqueIdentifier := md5.Sum([]byte(time.Now().String())) secret.Name = hex.EncodeToString(uniqueIdentifier[:]) } store[fmt.Sprintf("%s:%s", secret.Namespace, secret.Name)] = secret return secret, nil - } + }).AnyTimes() - secretInterfaceMock.GetNamespacedFunc = func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { - secret, ok := store[fmt.Sprintf("%s:%s", namespace, name)] - if ok { + secretController.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + key := fmt.Sprintf("%s:%s", namespace, name) + if secret, ok := store[key]; ok { return secret, nil } return nil, errors.New("secret not found") - } + }).AnyTimes() - secretInterfaceMock.DeleteNamespacedFunc = func(namespace string, name string, options *metav1.DeleteOptions) error { + secretController.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, options *metav1.DeleteOptions) error { key := fmt.Sprintf("%s:%s", namespace, name) if _, ok := store[key]; !ok { return apierrors.NewNotFound(schema.GroupResource{ - Group: v1.SecretGroupVersionKind.Group, - Resource: v1.SecretGroupVersionResource.Resource, + Group: v1.SchemeGroupVersion.Group, + Resource: "secrets", }, key) } delete(store, key) return nil - } + }).AnyTimes() - secretInterfaceMock.ListNamespacedFunc = func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { + secretController.EXPECT().List(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { var secrets []corev1.Secret - for _, s := range store { - secrets = append(secrets, *s) + for _, secret := range store { + if secret.Namespace == namespace { + secrets = append(secrets, *secret) + } } return &corev1.SecretList{Items: secrets}, nil - } + }).AnyTimes() - return secretInterfaceMock + return secretController } func TestCleanupClientSecretsOKTAConfig(t *testing.T) { @@ -201,7 +209,8 @@ func TestCleanupClientSecretsOKTAConfig(t *testing.T) { oauthSecretName := "user123-secret" initialStore := map[string]*corev1.Secret{} - secrets := getSecretInterfaceMock(initialStore) + ctrl := gomock.NewController(t) + secrets := getSecretControllerMock(ctrl, initialStore) _, err := secrets.Create(&v1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -231,24 +240,24 @@ func TestCleanupClientSecretsOKTAConfig(t *testing.T) { }) assert.NoError(t, err) - s, err := secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + s, err := secrets.Get(common.SecretsNamespace, secretName1, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName1) - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName2, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", secretName2) - s, err = secrets.GetNamespaced(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) + s, err = secrets.Get(tokens.SecretNamespace, oauthSecretName, metav1.GetOptions{}) assert.NoErrorf(t, err, "expected to find the secret %s belonging to the disabled auth provider", oauthSecretName) err = CleanupClientSecrets(secrets, config) assert.NoError(t, err) t.Run("Cleanup deletes provider secrets", func(t *testing.T) { - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName1, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName1, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName1) assert.Nil(t, s, "expected the secret to be nil") - s, err = secrets.GetNamespaced(common.SecretsNamespace, secretName2, metav1.GetOptions{}) + s, err = secrets.Get(common.SecretsNamespace, secretName2, metav1.GetOptions{}) assert.Errorf(t, err, "expected to not find the secret %s belonging to the disabled auth provider", secretName2) assert.Nil(t, s, "expected the secret to be nil") }) diff --git a/pkg/auth/api/secrets/store.go b/pkg/auth/api/secrets/store.go index f5519d2814e..82412c6494d 100644 --- a/pkg/auth/api/secrets/store.go +++ b/pkg/auth/api/secrets/store.go @@ -8,10 +8,10 @@ import ( "github.com/rancher/norman/types/convert" "github.com/rancher/norman/types/values" "github.com/rancher/rancher/pkg/auth/providers/common" - corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" ) -func Wrap(store types.Store, secrets corev1.SecretInterface) types.Store { +func Wrap(store types.Store, secrets wcorev1.SecretController) types.Store { return &Store{ Store: store, Secrets: secrets, @@ -20,7 +20,7 @@ func Wrap(store types.Store, secrets corev1.SecretInterface) types.Store { type Store struct { types.Store - Secrets corev1.SecretInterface + Secrets wcorev1.SecretController } func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) { diff --git a/pkg/auth/cleanup/service.go b/pkg/auth/cleanup/service.go index f7bc564db8f..a40f2af0d9a 100644 --- a/pkg/auth/cleanup/service.go +++ b/pkg/auth/cleanup/service.go @@ -9,7 +9,7 @@ import ( v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/api/secrets" controllers "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" - corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -19,7 +19,7 @@ var errAuthConfigNil = errors.New("cannot get auth provider if its config is nil // Service performs cleanup of resources associated with an auth provider. type Service struct { - secretsInterface corev1.SecretInterface + secretsInterface wcorev1.SecretController userClient controllers.UserClient @@ -37,7 +37,7 @@ type Service struct { } // NewCleanupService creates and returns a new auth provider cleanup service. -func NewCleanupService(secretsInterface corev1.SecretInterface, c controllers.Interface) *Service { +func NewCleanupService(secretsInterface wcorev1.SecretController, c controllers.Interface) *Service { return &Service{ secretsInterface: secretsInterface, diff --git a/pkg/auth/cleanup/service_test.go b/pkg/auth/cleanup/service_test.go index 23ecb02bad9..7aa6978cb16 100644 --- a/pkg/auth/cleanup/service_test.go +++ b/pkg/auth/cleanup/service_test.go @@ -14,8 +14,9 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" - "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/v3/pkg/generic/fake" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -276,7 +277,7 @@ func newMockCleanupService(t *testing.T, }).AnyTimes() return Service{ - secretsInterface: getSecretInterfaceMock(secretStore), + secretsInterface: getSecretControllerMock(ctrl, secretStore), globalRoleBindingsCache: grbCache, globalRoleBindingsClient: grbClient, projectRoleTemplateBindingsCache: prtbCache, @@ -289,19 +290,19 @@ func newMockCleanupService(t *testing.T, } } -func getSecretInterfaceMock(store map[string]*corev1.Secret) v1.SecretInterface { - secretInterfaceMock := &fakes.SecretInterfaceMock{} +func getSecretControllerMock(ctrl *gomock.Controller, store map[string]*corev1.Secret) wcorev1.SecretController { + secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) - secretInterfaceMock.CreateFunc = func(secret *corev1.Secret) (*corev1.Secret, error) { + secretController.EXPECT().Create(gomock.Any()).DoAndReturn(func(secret *corev1.Secret) (*corev1.Secret, error) { if secret.Name == "" { uniqueIdentifier := md5.Sum([]byte(time.Now().String())) secret.Name = hex.EncodeToString(uniqueIdentifier[:]) } store[fmt.Sprintf("%s:%s", secret.Namespace, secret.Name)] = secret return secret, nil - } + }).AnyTimes() - secretInterfaceMock.ListNamespacedFunc = func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { + secretController.EXPECT().List(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace string, opts metav1.ListOptions) (*corev1.SecretList, error) { var secrets []corev1.Secret for _, secret := range store { if secret.Namespace == namespace { @@ -311,20 +312,20 @@ func getSecretInterfaceMock(store map[string]*corev1.Secret) v1.SecretInterface return &corev1.SecretList{ Items: secrets, }, nil - } + }).AnyTimes() - secretInterfaceMock.GetNamespacedFunc = func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + secretController.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, opts metav1.GetOptions) (*corev1.Secret, error) { secret, ok := store[fmt.Sprintf("%s:%s", namespace, name)] if ok { return secret, nil } return nil, errors.New("secret not found") - } + }).AnyTimes() - secretInterfaceMock.DeleteNamespacedFunc = func(namespace string, name string, options *metav1.DeleteOptions) error { + secretController.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, options *metav1.DeleteOptions) error { delete(store, fmt.Sprintf("%s:%s", namespace, name)) return nil - } + }).AnyTimes() - return secretInterfaceMock + return secretController } diff --git a/pkg/auth/providers/activedirectory/activedirectory_provider.go b/pkg/auth/providers/activedirectory/activedirectory_provider.go index 2c7ddbcb2bc..42eea466b56 100644 --- a/pkg/auth/providers/activedirectory/activedirectory_provider.go +++ b/pkg/auth/providers/activedirectory/activedirectory_provider.go @@ -6,23 +6,21 @@ import ( "fmt" "strings" - "github.com/rancher/norman/httperror" - "github.com/pkg/errors" + "github.com/rancher/norman/httperror" "github.com/rancher/norman/types" - "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/providers/common" "github.com/rancher/rancher/pkg/auth/tokens" v3client "github.com/rancher/rancher/pkg/client/generated/management/v3" client "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" ) const ( @@ -49,8 +47,8 @@ var scopes = []string{UserScope, GroupScope} type adProvider struct { ctx context.Context authConfigs v3.AuthConfigInterface - configMaps corev1.ConfigMapLister - secrets corev1.SecretInterface + configMaps wcorev1.ConfigMapCache + secrets wcorev1.SecretController userMGR user.Manager certs string caPool *x509.CertPool @@ -61,8 +59,8 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. return &adProvider{ ctx: ctx, authConfigs: mgmtCtx.Management.AuthConfigs(""), - configMaps: mgmtCtx.Core.ConfigMaps("").Controller().Lister(), - secrets: mgmtCtx.Core.Secrets(""), + configMaps: mgmtCtx.Wrangler.Core.ConfigMap().Cache(), + secrets: mgmtCtx.Wrangler.Core.Secret(), userMGR: userMGR, tokenMGR: tokenMGR, } diff --git a/pkg/auth/providers/azure/azure_actions.go b/pkg/auth/providers/azure/azure_actions.go index 59ff4639f40..1a9c6386261 100644 --- a/pkg/auth/providers/azure/azure_actions.go +++ b/pkg/auth/providers/azure/azure_actions.go @@ -70,7 +70,7 @@ func (ap *Provider) testAndApply(request *types.APIContext) error { // cached without having sufficient API permissions. Rancher has no precise control over when this secret is cached. defer func() { if err != nil { - if err = ap.secrets.DeleteNamespaced(common.SecretsNamespace, clients.AccessTokenSecretName, &metav1.DeleteOptions{}); err != nil { + if err = ap.secrets.Delete(common.SecretsNamespace, clients.AccessTokenSecretName, &metav1.DeleteOptions{}); err != nil { logrus.Errorf("Failed to delete the Azure AD access token secret from Kubernetes") } } diff --git a/pkg/auth/providers/azure/azure_provider.go b/pkg/auth/providers/azure/azure_provider.go index 6895e74bfa1..684a9e4a9a0 100644 --- a/pkg/auth/providers/azure/azure_provider.go +++ b/pkg/auth/providers/azure/azure_provider.go @@ -18,11 +18,11 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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/settings" "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" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -41,7 +41,7 @@ type Provider struct { ctx context.Context authConfigs v3.AuthConfigInterface Retriever unstructuredGetter - secrets corev1.SecretInterface + secrets wcorev1.SecretController userMGR user.Manager tokenMGR *tokens.Manager } @@ -58,7 +58,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. ctx: ctx, Retriever: mgmtCtx.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), authConfigs: mgmtCtx.Management.AuthConfigs(""), - secrets: mgmtCtx.Core.Secrets(""), + secrets: mgmtCtx.Wrangler.Core.Secret(), userMGR: userMGR, tokenMGR: tokenMGR, } diff --git a/pkg/auth/providers/azure/clients/client.go b/pkg/auth/providers/azure/clients/client.go index 4ecdf8cde9c..468ce08d8bd 100644 --- a/pkg/auth/providers/azure/clients/client.go +++ b/pkg/auth/providers/azure/clients/client.go @@ -2,8 +2,8 @@ package clients import ( v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" - corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" ) // Name is the identifier for the Azure AD auth provider. @@ -25,7 +25,7 @@ type AzureClient interface { // NewAzureClientFromCredential returns a new client to be used for first-time authentication. This means it does not need any // externally stored secrets with tokens, as is the case when a client is created to use an existing access token. -func NewAzureClientFromCredential(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, credential *v32.AzureADLogin, secrets corev1.SecretInterface) (AzureClient, error) { +func NewAzureClientFromCredential(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, credential *v32.AzureADLogin, secrets wcorev1.SecretController) (AzureClient, error) { if useDeprecatedAzureADClient { return NewADGraphClientFromCredential(config, credential) } @@ -34,7 +34,7 @@ func NewAzureClientFromCredential(config *v32.AzureADConfig, useDeprecatedAzureA // NewAzureClientFromSecret returns a new client to be used for search and other activities after initial authentication. // The client would fetch the access token from either a refresh token or secret contents passed in. -func NewAzureClientFromSecret(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, secret string, secrets corev1.SecretInterface) (AzureClient, error) { +func NewAzureClientFromSecret(config *v32.AzureADConfig, useDeprecatedAzureADClient bool, secret string, secrets wcorev1.SecretController) (AzureClient, error) { if useDeprecatedAzureADClient { return NewAzureADGraphClientFromADALToken(config, secret) } diff --git a/pkg/auth/providers/azure/clients/ms_graph_client.go b/pkg/auth/providers/azure/clients/ms_graph_client.go index 0028834f610..e4c0f247913 100644 --- a/pkg/auth/providers/azure/clients/ms_graph_client.go +++ b/pkg/auth/providers/azure/clients/ms_graph_client.go @@ -22,8 +22,8 @@ import ( msgraphusers "github.com/microsoftgraph/msgraph-sdk-go/users" v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/providers/common" - normancorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -43,7 +43,7 @@ const ( // It first tries to fetch the token from the refresh token, if the access token is found in the database. // If that fails, it tries to acquire it directly from the auth provider with the credential (application secret in Azure). // It also checks that the access token has the necessary permissions. -func NewMSGraphClient(config *v32.AzureADConfig, secrets normancorev1.SecretInterface) (*AzureMSGraphClient, error) { +func NewMSGraphClient(config *v32.AzureADConfig, secrets wcorev1.SecretController) (*AzureMSGraphClient, error) { cred, err := confidential.NewCredFromSecret(config.ApplicationSecret) if err != nil { return nil, fmt.Errorf("could not create a cred from a secret: %w", err) @@ -416,7 +416,7 @@ func oidFromAuthCode(token string, config *v32.AzureADConfig) (string, error) { // // WARNING: The tokens are stored in plain-text in Kubernetes secrets. type accessTokenCache struct { - Secrets normancorev1.SecretInterface + Secrets wcorev1.SecretController } // Replace fetches the access token from a secret in Kubernetes. diff --git a/pkg/auth/providers/azure/clients/ms_graph_client_test.go b/pkg/auth/providers/azure/clients/ms_graph_client_test.go index b63a0a0772e..d7a2c180a3c 100644 --- a/pkg/auth/providers/azure/clients/ms_graph_client_test.go +++ b/pkg/auth/providers/azure/clients/ms_graph_client_test.go @@ -5,10 +5,11 @@ import ( "testing" apismgmtv3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" - normancorev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" - "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" mgmtv3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -27,7 +28,9 @@ import ( // TEST_AZURE_APPLICATION_SECRET func TestMSGraphClient_GetUser(t *testing.T) { - client := newTestClient(t) + ctrl := gomock.NewController(t) + secrets := newTestSecretsClient(ctrl) + client := newTestClientWithSecretsClient(t, secrets) user, err := client.GetUser("testuser6@ranchertest.onmicrosoft.com") if err != nil { @@ -171,10 +174,11 @@ func TestMSGraphClient_ListGroupMemberships_with_filter(t *testing.T) { func newTestClient(t *testing.T) *AzureMSGraphClient { t.Helper() - return newTestClientWithSecretsClient(t, newTestSecretsClient()) + ctrl := gomock.NewController(t) + return newTestClientWithSecretsClient(t, newTestSecretsClient(ctrl)) } -func newTestClientWithSecretsClient(t *testing.T, secrets normancorev1.SecretInterface) *AzureMSGraphClient { +func newTestClientWithSecretsClient(t *testing.T, secrets wcorev1.SecretController) *AzureMSGraphClient { t.Helper() tenantID, applicationID, applicationSecret := os.Getenv("TEST_AZURE_TENANT_ID"), os.Getenv("TEST_AZURE_APPLICATION_ID"), os.Getenv("TEST_AZURE_APPLICATION_SECRET") @@ -197,66 +201,58 @@ func newTestClientWithSecretsClient(t *testing.T, secrets normancorev1.SecretInt return client } -func newTestSecretsClient() normancorev1.SecretInterface { - return newTestSecretsClientWithMap(map[types.NamespacedName]*corev1.Secret{}) -} +func newTestSecretsClient(ctrl *gomock.Controller) *wranglerfake.MockControllerInterface[*corev1.Secret, *corev1.SecretList] { + secrets := map[types.NamespacedName]*corev1.Secret{} -func newTestSecretsClientWithMap(secrets map[types.NamespacedName]*corev1.Secret) normancorev1.SecretInterface { - sm := &fakes.SecretInterfaceMock{ - GetNamespacedFunc: func(namespace, name string, opts metav1.GetOptions) (*corev1.Secret, error) { - namespacedName := types.NamespacedName{Namespace: namespace, Name: name} - if s, ok := secrets[namespacedName]; ok { - return s, nil - } + secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) - return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) - }, + secretController.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string, opts metav1.GetOptions) (*corev1.Secret, error) { + namespacedName := types.NamespacedName{Namespace: namespace, Name: name} + if s, ok := secrets[namespacedName]; ok { + return s, nil + } + return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) + }).AnyTimes() - CreateFunc: func(in1 *corev1.Secret) (*corev1.Secret, error) { - if in1.StringData != nil { - if in1.Data == nil { - in1.Data = map[string][]byte{} - } - for k, v := range in1.StringData { - in1.Data[k] = []byte(v) - } - in1.StringData = nil + secretController.EXPECT().Create(gomock.Any()).DoAndReturn(func(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.StringData != nil { + if secret.Data == nil { + secret.Data = map[string][]byte{} } - secrets[client.ObjectKeyFromObject(in1)] = in1 - return in1, nil - }, - - UpdateFunc: func(in1 *corev1.Secret) (*corev1.Secret, error) { - if in1.StringData != nil { - if in1.Data == nil { - in1.Data = map[string][]byte{} - } - for k, v := range in1.StringData { - in1.Data[k] = []byte(v) - } - in1.StringData = nil + for k, v := range secret.StringData { + secret.Data[k] = []byte(v) } - secrets[client.ObjectKeyFromObject(in1)] = in1 - return in1, nil - }, - - ControllerFunc: func() normancorev1.SecretController { - return &fakes.SecretControllerMock{ - ListerFunc: func() normancorev1.SecretLister { - return &fakes.SecretListerMock{ - GetFunc: func(namespace, name string) (*corev1.Secret, error) { - namespacedName := types.NamespacedName{Namespace: namespace, Name: name} - if s, ok := secrets[namespacedName]; ok { - return s, nil - } - - return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) - }, - } - }, + secret.StringData = nil + } + secrets[client.ObjectKeyFromObject(secret)] = secret + return secret, nil + }).AnyTimes() + + secretController.EXPECT().Update(gomock.Any()).DoAndReturn(func(secret *corev1.Secret) (*corev1.Secret, error) { + if secret.StringData != nil { + if secret.Data == nil { + secret.Data = map[string][]byte{} } - }, - } + for k, v := range secret.StringData { + secret.Data[k] = []byte(v) + } + secret.StringData = nil + } + secrets[client.ObjectKeyFromObject(secret)] = secret + return secret, nil + }).AnyTimes() + + secretCache := wranglerfake.NewMockCacheInterface[*corev1.Secret](ctrl) + + secretCache.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(func(namespace, name string) (*corev1.Secret, error) { + namespacedName := types.NamespacedName{Namespace: namespace, Name: name} + if s, ok := secrets[namespacedName]; ok { + return s, nil + } + return nil, apierrors.NewNotFound(core.Resource("Secret"), namespacedName.String()) + }).AnyTimes() + + secretController.EXPECT().Cache().Return(secretCache).AnyTimes() - return sm + return secretController } diff --git a/pkg/auth/providers/common/password.go b/pkg/auth/providers/common/password.go index 83aa7052453..ce9f2e64dc2 100644 --- a/pkg/auth/providers/common/password.go +++ b/pkg/auth/providers/common/password.go @@ -5,8 +5,8 @@ import ( "reflect" "strings" - corev1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" "github.com/rancher/rancher/pkg/namespace" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -16,7 +16,7 @@ const SecretsNamespace = namespace.GlobalNamespace // NameForSecret returns a string with the namespace:name for the provided // Secret. -func NameForSecret(s *corev1.Secret) string { +func NameForSecret(s *v1.Secret) string { return fmt.Sprintf("%s:%s", s.GetNamespace(), s.GetName()) } @@ -30,7 +30,7 @@ func NameForSecret(s *corev1.Secret) string { // desired state it is overwritten. // // It returns a string with the namespace:name of the created Secret. -func CreateOrUpdateSecrets(secrets corev1.SecretInterface, secretInfo, field, authType string) (string, error) { +func CreateOrUpdateSecrets(secrets wcorev1.SecretController, secretInfo, field, authType string) (string, error) { if secretInfo == "" { return "", nil } @@ -45,7 +45,7 @@ func CreateOrUpdateSecrets(secrets corev1.SecretInterface, secretInfo, field, au Type: v1.SecretTypeOpaque, } - curr, err := secrets.Controller().Lister().Get(SecretsNamespace, name) + curr, err := secrets.Cache().Get(SecretsNamespace, name) if err != nil && !apierrors.IsNotFound(err) { return "", fmt.Errorf("error getting secret for %s : %w", name, err) } @@ -65,7 +65,7 @@ func CreateOrUpdateSecrets(secrets corev1.SecretInterface, secretInfo, field, au return NameForSecret(secret), nil } -func ReadFromSecret(secrets corev1.SecretInterface, secretInfo string, field string) (string, error) { +func ReadFromSecret(secrets wcorev1.SecretController, secretInfo string, field string) (string, error) { if strings.HasPrefix(secretInfo, SecretsNamespace) { data, err := ReadFromSecretData(secrets, secretInfo) if err != nil { @@ -80,11 +80,11 @@ func ReadFromSecret(secrets corev1.SecretInterface, secretInfo string, field str return secretInfo, nil } -func ReadFromSecretData(secrets corev1.SecretInterface, secretInfo string) (map[string][]byte, error) { +func ReadFromSecretData(secrets wcorev1.SecretController, secretInfo string) (map[string][]byte, error) { if strings.HasPrefix(secretInfo, SecretsNamespace) { split := strings.SplitN(secretInfo, ":", 2) if len(split) == 2 { - secret, err := secrets.GetNamespaced(split[0], split[1], metav1.GetOptions{}) + secret, err := secrets.Get(split[0], split[1], metav1.GetOptions{}) if err != nil { return nil, fmt.Errorf("error getting secret %s: %w", secretInfo, err) } @@ -101,12 +101,12 @@ func GetFullSecretName(configType string, field string) string { } // DeleteSecret deletes a secret associated with an auth provider. -func DeleteSecret(secrets corev1.SecretInterface, configType string, field string) error { +func DeleteSecret(secrets wcorev1.SecretController, configType string, field string) error { secretName := fmt.Sprintf("%s-%s", strings.ToLower(configType), strings.ToLower(field)) - return secrets.DeleteNamespaced(SecretsNamespace, secretName, &metav1.DeleteOptions{}) + return secrets.Delete(SecretsNamespace, secretName, &metav1.DeleteOptions{}) } // SavePasswordSecret creates a secret out of a password, config type, and field name. -func SavePasswordSecret(secrets corev1.SecretInterface, password string, fieldName string, authType string) (string, error) { +func SavePasswordSecret(secrets wcorev1.SecretController, password string, fieldName string, authType string) (string, error) { return CreateOrUpdateSecrets(secrets, password, strings.ToLower(fieldName), strings.ToLower(authType)) } diff --git a/pkg/auth/providers/common/password_test.go b/pkg/auth/providers/common/password_test.go index 43a94ddd31a..5df6658de7b 100644 --- a/pkg/auth/providers/common/password_test.go +++ b/pkg/auth/providers/common/password_test.go @@ -1,19 +1,17 @@ package common import ( - "errors" "testing" + clientv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - - clientv3 "github.com/rancher/rancher/pkg/client/generated/management/v3" - v1 "github.com/rancher/rancher/pkg/generated/norman/core/v1" - "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" - fake1 "github.com/rancher/rancher/pkg/generated/norman/core/v1/fakes" ) const ( @@ -21,36 +19,39 @@ const ( appSecretValue = "superSecret" ) -type testPair struct { +var tests = []struct { in string out string -} - -var tests = []testPair{ +}{ {in: "potato", out: "potato"}, {in: SecretsNamespace + "-foo", out: SecretsNamespace + "-foo"}, {in: SecretsNamespace + ":bar", out: appSecretValue}, {in: "bad:thing", out: "bad:thing"}, + {in: SecretsNamespace + ":baz", out: "error"}, // expecting an error or different output for 'baz' + } func TestReadFromSecret(t *testing.T) { - secretInterface := fake1.SecretInterfaceMock{ - GetNamespacedFunc: func(namespace string, name string, opts metav1.GetOptions) (*corev1.Secret, error) { - s := corev1.Secret{ - Data: make(map[string][]byte), - } - if name == "bar" { - s.Data[appSecretKey] = []byte(appSecretValue) - return &s, nil - } - return nil, errors.New("secret not found") + ctrl := gomock.NewController(t) + + secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) + secretController.EXPECT().Get("cattle-global-data", "bar", gomock.Any()).Return(&corev1.Secret{ + Data: map[string][]byte{ + appSecretKey: []byte(appSecretValue), }, - } + }, nil).AnyTimes() + + // If the secret name is not "bar" return an error + secretController.EXPECT().Get(gomock.Any(), gomock.Not("bar"), gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "secret not found")).AnyTimes() for _, pair := range tests { - info, err := ReadFromSecret(&secretInterface, pair.in, appSecretKey) - assert.Nil(t, err) - assert.Equal(t, pair.out, info) + info, err := ReadFromSecret(secretController, pair.in, appSecretKey) + if pair.out == "error" { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, pair.out, info) + } } } @@ -73,14 +74,6 @@ func TestNameForSecret(t *testing.T) { } func TestSavePasswordSecret(t *testing.T) { - secrets := &secretFake{} - secretInterface := newSecretInterfaceMock(secrets) - - name, err := SavePasswordSecret(secretInterface, "test-password", - clientv3.LdapConfigFieldServiceAccountPassword, - "shibbolethConfig") - assert.NoError(t, err) - wantSecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "shibbolethconfig-serviceaccountpassword", @@ -91,31 +84,22 @@ func TestSavePasswordSecret(t *testing.T) { }, Type: corev1.SecretTypeOpaque, } - assert.Equal(t, []*corev1.Secret{wantSecret}, secrets.Created) - assert.Equal(t, wantSecret.Namespace+":"+wantSecret.Name, name) -} -type secretFake struct { - Created []*corev1.Secret -} + ctrl := gomock.NewController(t) + secretController := wranglerfake.NewMockControllerInterface[*corev1.Secret, *corev1.SecretList](ctrl) + var createdSecret *v1.Secret + secretController.EXPECT().Create(gomock.Any()).DoAndReturn(func(secret *v1.Secret) (*v1.Secret, error) { + createdSecret = secret + return secret, nil + }) + secretsCache := wranglerfake.NewMockCacheInterface[*corev1.Secret](ctrl) + secretsCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil, apierrors.NewNotFound(schema.GroupResource{}, "test-password")) + secretController.EXPECT().Cache().Return(secretsCache) -func newSecretInterfaceMock(secrets *secretFake) v1.SecretInterface { - controller := &fakes.SecretControllerMock{ - ListerFunc: func() v1.SecretLister { - return &fakes.SecretListerMock{ - GetFunc: func(ns string, name string) (*corev1.Secret, error) { - return nil, apierrors.NewNotFound(schema.GroupResource{}, name) - }, - } - }, - } - return &fakes.SecretInterfaceMock{ - ControllerFunc: func() v1.SecretController { - return controller - }, - CreateFunc: func(in1 *corev1.Secret) (*v1.Secret, error) { - secrets.Created = append(secrets.Created, in1) - return in1, nil - }, - } + name, err := SavePasswordSecret(secretController, "test-password", + clientv3.LdapConfigFieldServiceAccountPassword, + "shibbolethConfig") + assert.NoError(t, err) + assert.Equal(t, wantSecret.Namespace+":"+wantSecret.Name, name) + assert.Equal(t, wantSecret, createdSecret) } diff --git a/pkg/auth/providers/common/provider.go b/pkg/auth/providers/common/provider.go index 82775070629..09e48af26df 100644 --- a/pkg/auth/providers/common/provider.go +++ b/pkg/auth/providers/common/provider.go @@ -4,7 +4,7 @@ import ( "context" "github.com/rancher/norman/types" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" ) const ( diff --git a/pkg/auth/providers/common/usermanager.go b/pkg/auth/providers/common/usermanager.go index c92fae251fe..a3a4a42a17f 100644 --- a/pkg/auth/providers/common/usermanager.go +++ b/pkg/auth/providers/common/usermanager.go @@ -9,17 +9,16 @@ import ( "strings" "time" - v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" - "github.com/pkg/errors" "github.com/rancher/norman/types" "github.com/rancher/norman/types/slice" + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/tokens" tokenUtil "github.com/rancher/rancher/pkg/auth/tokens" - v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" - rbacv1 "github.com/rancher/rancher/pkg/generated/norman/rbac.authorization.k8s.io/v1" + wrangmgmtv3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" "github.com/rancher/rancher/pkg/user" + wrangrbacv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/rbac/v1" "github.com/rancher/wrangler/v3/pkg/randomtoken" "github.com/sirupsen/logrus" k8srbacv1 "k8s.io/api/rbac/v1" @@ -41,20 +40,14 @@ const ( ) func NewUserManagerNoBindings(scaledContext *config.ScaledContext) (user.Manager, error) { - userInformer := scaledContext.Management.Users("").Controller().Informer() - userIndexers := map[string]cache.IndexFunc{ - userByPrincipalIndex: userByPrincipal, - } - if err := userInformer.AddIndexers(userIndexers); err != nil { - return nil, err - } + userInformer := scaledContext.Wrangler.Mgmt.User().Informer() return &userManager{ - users: scaledContext.Management.Users(""), + users: scaledContext.Wrangler.Mgmt.User(), userIndexer: userInformer.GetIndexer(), - tokens: scaledContext.Management.Tokens(""), - tokenLister: scaledContext.Management.Tokens("").Controller().Lister(), - rbacClient: scaledContext.RBAC, + tokens: scaledContext.Wrangler.Mgmt.Token(), + tokenLister: scaledContext.Wrangler.Mgmt.Token().Cache(), + rbacClient: scaledContext.Wrangler.RBAC, }, nil } @@ -66,7 +59,7 @@ var backoff = wait.Backoff{ } func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { - userInformer := scaledContext.Management.Users("").Controller().Informer() + userInformer := scaledContext.Wrangler.Mgmt.User().Informer() userIndexers := map[string]cache.IndexFunc{ userByPrincipalIndex: userByPrincipal, } @@ -74,7 +67,7 @@ func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { return nil, err } - crtbInformer := scaledContext.Management.ClusterRoleTemplateBindings("").Controller().Informer() + crtbInformer := scaledContext.Wrangler.Mgmt.ClusterRoleTemplateBinding().Informer() crtbIndexers := map[string]cache.IndexFunc{ crtbsByPrincipalAndUserIndex: crtbsByPrincipalAndUser, } @@ -82,7 +75,7 @@ func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { return nil, err } - prtbInformer := scaledContext.Management.ProjectRoleTemplateBindings("").Controller().Informer() + prtbInformer := scaledContext.Wrangler.Mgmt.ProjectRoleTemplateBinding().Informer() prtbIndexers := map[string]cache.IndexFunc{ prtbsByPrincipalAndUserIndex: prtbsByPrincipalAndUser, } @@ -90,7 +83,7 @@ func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { return nil, err } - grbInformer := scaledContext.Management.GlobalRoleBindings("").Controller().Informer() + grbInformer := scaledContext.Wrangler.Mgmt.GlobalRoleBinding().Informer() grbIndexers := map[string]cache.IndexFunc{ grbByUserIndex: grbByUser, } @@ -100,36 +93,36 @@ func NewUserManager(scaledContext *config.ScaledContext) (user.Manager, error) { return &userManager{ manageBindings: true, - users: scaledContext.Management.Users(""), + users: scaledContext.Wrangler.Mgmt.User(), userIndexer: userInformer.GetIndexer(), crtbIndexer: crtbInformer.GetIndexer(), prtbIndexer: prtbInformer.GetIndexer(), - tokens: scaledContext.Management.Tokens(""), - tokenLister: scaledContext.Management.Tokens("").Controller().Lister(), - globalRoleBindings: scaledContext.Management.GlobalRoleBindings(""), - globalRoleLister: scaledContext.Management.GlobalRoles("").Controller().Lister(), + tokens: scaledContext.Wrangler.Mgmt.Token(), + tokenLister: scaledContext.Wrangler.Mgmt.Token().Cache(), + globalRoleBindings: scaledContext.Wrangler.Mgmt.GlobalRoleBinding(), + globalRoleLister: scaledContext.Wrangler.Mgmt.GlobalRole().Cache(), grbIndexer: grbInformer.GetIndexer(), - clusterRoleLister: scaledContext.RBAC.ClusterRoles("").Controller().Lister(), - clusterRoleBindingLister: scaledContext.RBAC.ClusterRoleBindings("").Controller().Lister(), - rbacClient: scaledContext.RBAC, + clusterRoleLister: scaledContext.Wrangler.RBAC.ClusterRole().Cache(), + clusterRoleBindingLister: scaledContext.Wrangler.RBAC.ClusterRoleBinding().Cache(), + rbacClient: scaledContext.Wrangler.RBAC, }, nil } type userManager struct { // manageBinding means whether or not we gr, grb, crtb, and prtb exist in the cluster manageBindings bool - users v3.UserInterface - globalRoleBindings v3.GlobalRoleBindingInterface - globalRoleLister v3.GlobalRoleLister + users wrangmgmtv3.UserController + globalRoleBindings wrangmgmtv3.GlobalRoleBindingController + globalRoleLister wrangmgmtv3.GlobalRoleCache grbIndexer cache.Indexer userIndexer cache.Indexer crtbIndexer cache.Indexer prtbIndexer cache.Indexer - tokenLister v3.TokenLister - tokens v3.TokenInterface - clusterRoleLister rbacv1.ClusterRoleLister - clusterRoleBindingLister rbacv1.ClusterRoleBindingLister - rbacClient rbacv1.Interface + tokenLister wrangmgmtv3.TokenCache + tokens wrangmgmtv3.TokenController + clusterRoleLister wrangrbacv1.ClusterRoleCache + clusterRoleBindingLister wrangrbacv1.ClusterRoleBindingCache + rbacClient wrangrbacv1.Interface } func (m *userManager) SetPrincipalOnCurrentUser(apiContext *types.APIContext, principal v3.Principal) (*v3.User, error) { @@ -241,7 +234,7 @@ func (m *userManager) EnsureClusterToken(clusterName string, input user.TokenInp var err error var token *v3.Token if !input.Randomize { - token, err = m.tokenLister.Get("", input.TokenName) + token, err = m.tokenLister.Get(input.TokenName) if err != nil && !apierrors.IsNotFound(err) { return "", err } @@ -420,7 +413,7 @@ func (m *userManager) EnsureUser(principalName, displayName string) (*v3.User, e return user, nil } - if v32.UserConditionInitialRolesPopulated.IsTrue(user) { + if v3.UserConditionInitialRolesPopulated.IsTrue(user) { // The users global role bindings were already created. They can differ // from what is in the annotation if they were updated manually. return user, nil @@ -486,7 +479,7 @@ func (m *userManager) CreateNewUserClusterRoleBinding(userName string, userUID a UID: userUID, } - cr, err := m.clusterRoleLister.Get("", roleName) + cr, err := m.clusterRoleLister.Get(roleName) if err != nil { if !apierrors.IsNotFound(err) { return err @@ -506,7 +499,7 @@ func (m *userManager) CreateNewUserClusterRoleBinding(userName string, userUID a Rules: []k8srbacv1.PolicyRule{rule}, } - cr, err = m.rbacClient.ClusterRoles("").Create(role) + cr, err = m.rbacClient.ClusterRole().Create(role) if err != nil { if !apierrors.IsAlreadyExists(err) { return err @@ -514,7 +507,7 @@ func (m *userManager) CreateNewUserClusterRoleBinding(userName string, userUID a } } - _, err = m.clusterRoleBindingLister.Get("", bindingName) + _, err = m.clusterRoleBindingLister.Get(bindingName) if err != nil { if !apierrors.IsNotFound(err) { return err @@ -536,7 +529,7 @@ func (m *userManager) CreateNewUserClusterRoleBinding(userName string, userUID a Name: cr.Name, }, } - _, err = m.rbacClient.ClusterRoleBindings("").Create(crb) + _, err = m.rbacClient.ClusterRoleBinding().Create(crb) if err != nil { if !apierrors.IsAlreadyExists(err) { return err @@ -610,7 +603,7 @@ func (m *userManager) createUsersBindings(user *v3.User) error { user.Annotations[roleTemplatesRequired] = rtr if reflect.DeepEqual(roleMap["required"], createdRoles) { - v32.UserConditionInitialRolesPopulated.True(user) + v3.UserConditionInitialRolesPopulated.True(user) } _, err = m.users.Update(user) @@ -636,7 +629,7 @@ func (m *userManager) createUsersRoleAnnotation() (map[string]string, error) { roleMap := make(map[string][]string) - roles, err := m.globalRoleLister.List("", labels.NewSelector()) + roles, err := m.globalRoleLister.List(labels.NewSelector()) if err != nil { return nil, err } diff --git a/pkg/auth/providers/common/usermanager_test.go b/pkg/auth/providers/common/usermanager_test.go new file mode 100644 index 00000000000..940e7aca441 --- /dev/null +++ b/pkg/auth/providers/common/usermanager_test.go @@ -0,0 +1,236 @@ +package common + +import ( + "errors" + "testing" + + v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" + wranglerfake "github.com/rancher/wrangler/v3/pkg/generic/fake" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/tools/cache" +) + +func TestSetPrincipalOnCurrentUserByUserID(t *testing.T) { + testCases := []struct { + name string + userID string + principal v3.Principal + existingUser *v3.User + existingError error + principalUser *v3.User + principalError error + expectedUser *v3.User + expectedError error + expectedToUpdate bool + }{ + { + name: "successfully add principal to user", + userID: "user1", + principal: v3.Principal{ + ObjectMeta: v1.ObjectMeta{ + Name: "github_user1", + }, + DisplayName: "github_user1", + Provider: "github", + }, + existingUser: &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "user1", + UID: "uid1", + }, + PrincipalIDs: []string{"local://user"}, + }, + principalUser: nil, + principalError: nil, + expectedUser: &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "user1", + UID: "uid1", + }, + PrincipalIDs: []string{"local://user", "github_user1"}, + }, + expectedError: nil, + expectedToUpdate: true, + }, + { + name: "user retrieval fails", + userID: "user1", + principal: v3.Principal{ + ObjectMeta: v1.ObjectMeta{ + Name: "user1", + }, + Provider: "github", + }, + existingUser: nil, + existingError: errors.New("user not found"), + expectedError: errors.New("user not found"), + expectedToUpdate: false, + }, + { + name: "principal conflict with another user", + userID: "user1", + principal: v3.Principal{ + ObjectMeta: v1.ObjectMeta{ + Name: "github_user1", + }, + DisplayName: "github_user1", + Provider: "github", + }, + existingUser: &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "user1", + UID: "uid1", + }, + PrincipalIDs: []string{"local://user"}, + }, + principalUser: &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "user2", + UID: "uid2", + }, + PrincipalIDs: []string{"local://user", "github_user1"}, + }, + principalError: nil, + expectedUser: &v3.User{ + ObjectMeta: v1.ObjectMeta{ + Name: "user1", + UID: "uid1", + }, + PrincipalIDs: []string{"local://user"}, + }, + expectedError: errors.New("refusing to set principal on user that is already bound to another user"), + expectedToUpdate: false, + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + userControllerMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + mockUserIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + indexers := map[string]cache.IndexFunc{ + userByPrincipalIndex: userByPrincipal, + } + mockUserIndexer.AddIndexers(indexers) + + userControllerMock.EXPECT().Get(test.userID, gomock.Any()).Return(test.existingUser, test.existingError) + if test.principalUser != nil { + userControllerMock.EXPECT().List(gomock.Any()).Return(&v3.UserList{Items: []v3.User{*test.principalUser}}, test.principalError).AnyTimes() + } else { + userControllerMock.EXPECT().List(gomock.Any()).Return(&v3.UserList{}, test.principalError).AnyTimes() + } + userControllerMock.EXPECT().Update(gomock.Any()).AnyTimes().DoAndReturn(func(user *v3.User) (*v3.User, error) { + u := user.DeepCopy() + return u, nil + }) + + um := &userManager{ + users: userControllerMock, + userIndexer: mockUserIndexer, + } + + result, err := um.SetPrincipalOnCurrentUserByUserID(test.userID, test.principal) + + if test.expectedError != nil { + assert.EqualError(t, err, test.expectedError.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedUser, result) + } + }) + } +} + +func TestCheckAccess(t *testing.T) { + testCases := []struct { + name string + accessMode string + allowedPrincipalIDs []string + userPrincipalID string + groups []v3.Principal + user *v3.User + userErr error + expectedResult bool + expectedError error + }{ + { + name: "Unrestricted access, should allow", + accessMode: "unrestricted", + allowedPrincipalIDs: []string{}, + userPrincipalID: "local://user", + expectedResult: true, + expectedError: nil, + }, + { + name: "Required access, principal allowed", + accessMode: "required", + allowedPrincipalIDs: []string{"local://user", "github://user1"}, + userPrincipalID: "local://user", + user: &v3.User{ + PrincipalIDs: []string{"local://user", "github://user1"}, + }, + expectedResult: true, + expectedError: nil, + }, + { + name: "Restricted access, no matching principal", + accessMode: "restricted", + allowedPrincipalIDs: []string{"github://user2"}, + userPrincipalID: "local://user", + user: &v3.User{ + PrincipalIDs: []string{"local://user"}, + }, + groups: []v3.Principal{ + { + ObjectMeta: v1.ObjectMeta{ + Name: "github://group1", + }, + }, + }, + expectedResult: false, + expectedError: nil, + }, + { + name: "Unsupported accessMode", + accessMode: "unknown", + allowedPrincipalIDs: []string{"local://user"}, + userPrincipalID: "local://user", + expectedResult: false, + expectedError: errors.New("Unsupported accessMode: unknown"), + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + mockUserIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + indexers := map[string]cache.IndexFunc{ + userByPrincipalIndex: userByPrincipal, + } + mockUserIndexer.AddIndexers(indexers) + + userControllerMock := wranglerfake.NewMockNonNamespacedControllerInterface[*v3.User, *v3.UserList](ctrl) + um := &userManager{ + users: userControllerMock, + userIndexer: mockUserIndexer, + } + + userControllerMock.EXPECT().Get(gomock.Any(), gomock.Any()).DoAndReturn(func(name string, options v1.GetOptions) (*v3.User, error) { + return test.user, test.userErr + }).AnyTimes() + + result, err := um.CheckAccess(test.accessMode, test.allowedPrincipalIDs, test.userPrincipalID, test.groups) + + if test.expectedError != nil { + assert.EqualError(t, err, test.expectedError.Error()) + } else { + assert.NoError(t, err) + assert.Equal(t, test.expectedResult, result) + } + }) + } +} diff --git a/pkg/auth/providers/genericoidc/genericoidc_provider.go b/pkg/auth/providers/genericoidc/genericoidc_provider.go index d97850b293c..ebf7c953a0b 100644 --- a/pkg/auth/providers/genericoidc/genericoidc_provider.go +++ b/pkg/auth/providers/genericoidc/genericoidc_provider.go @@ -34,7 +34,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. Type: client.GenericOIDCConfigType, CTX: ctx, AuthConfigs: mgmtCtx.Management.AuthConfigs(""), - Secrets: mgmtCtx.Core.Secrets(""), + Secrets: mgmtCtx.Wrangler.Core.Secret(), UserMGR: userMGR, TokenMGR: tokenMGR, }, diff --git a/pkg/auth/providers/github/github_provider.go b/pkg/auth/providers/github/github_provider.go index 77ef67f1baa..3969b1bd033 100644 --- a/pkg/auth/providers/github/github_provider.go +++ b/pkg/auth/providers/github/github_provider.go @@ -18,10 +18,10 @@ import ( util2 "github.com/rancher/rancher/pkg/auth/util" client "github.com/rancher/rancher/pkg/client/generated/management/v3" publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,7 +42,7 @@ type tokensManager interface { type ghProvider struct { ctx context.Context authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController getConfig func() (*v32.GithubConfig, error) githubClient *GClient userMGR user.Manager @@ -57,7 +57,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. provider := &ghProvider{ ctx: ctx, authConfigs: mgmtCtx.Management.AuthConfigs(""), - secrets: mgmtCtx.Core.Secrets(""), + secrets: mgmtCtx.Wrangler.Core.Secret(), githubClient: githubClient, userMGR: userMGR, tokenMGR: tokenMGR, diff --git a/pkg/auth/providers/googleoauth/goauth_provider.go b/pkg/auth/providers/googleoauth/goauth_provider.go index 903aba1184b..f006167fc4e 100644 --- a/pkg/auth/providers/googleoauth/goauth_provider.go +++ b/pkg/auth/providers/googleoauth/goauth_provider.go @@ -16,10 +16,10 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -42,7 +42,7 @@ var scopes = []string{"openid", "profile", "email", admin.AdminDirectoryUserRead type googleOauthProvider struct { authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController goauthClient *GClient userMGR user.Manager tokenMGR *tokens.Manager @@ -58,7 +58,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. return &googleOauthProvider{ ctx: ctx, authConfigs: mgmtCtx.Management.AuthConfigs(""), - secrets: mgmtCtx.Core.Secrets(""), + secrets: mgmtCtx.Wrangler.Core.Secret(), goauthClient: &gClient, userMGR: userMGR, tokenMGR: tokenMGR, diff --git a/pkg/auth/providers/keycloakoidc/keycloak_provider.go b/pkg/auth/providers/keycloakoidc/keycloak_provider.go index b9061127927..cb84730b891 100644 --- a/pkg/auth/providers/keycloakoidc/keycloak_provider.go +++ b/pkg/auth/providers/keycloakoidc/keycloak_provider.go @@ -39,7 +39,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. Type: client.KeyCloakOIDCConfigType, CTX: ctx, AuthConfigs: mgmtCtx.Management.AuthConfigs(""), - Secrets: mgmtCtx.Core.Secrets(""), + Secrets: mgmtCtx.Wrangler.Core.Secret(), UserMGR: userMGR, TokenMGR: tokenMGR, }, diff --git a/pkg/auth/providers/ldap/ldap_client_test.go b/pkg/auth/providers/ldap/ldap_client_test.go index d749c4432ac..265326dc634 100644 --- a/pkg/auth/providers/ldap/ldap_client_test.go +++ b/pkg/auth/providers/ldap/ldap_client_test.go @@ -10,13 +10,12 @@ import ( ldapv3 "github.com/go-ldap/ldap/v3" "github.com/pkg/errors" - "github.com/rancher/norman/types" v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/tokens" - corev1 "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/user" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" apitypes "k8s.io/apimachinery/pkg/types" ) @@ -31,7 +30,7 @@ func Test_ldapProvider_loginUser(t *testing.T) { type fields struct { ctx context.Context authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController userMGR mockUserManager tokenMGR *tokens.Manager certs string diff --git a/pkg/auth/providers/ldap/ldap_provider.go b/pkg/auth/providers/ldap/ldap_provider.go index 96cbb37a3d1..f32bd417518 100644 --- a/pkg/auth/providers/ldap/ldap_provider.go +++ b/pkg/auth/providers/ldap/ldap_provider.go @@ -15,10 +15,10 @@ import ( "github.com/rancher/rancher/pkg/auth/providers/common/ldap" "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" - corev1 "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" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -59,7 +59,7 @@ var ( type ldapProvider struct { ctx context.Context authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController userMGR user.Manager tokenMGR *tokens.Manager certs string @@ -74,7 +74,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. return &ldapProvider{ ctx: ctx, authConfigs: mgmtCtx.Management.AuthConfigs(""), - secrets: mgmtCtx.Core.Secrets(""), + secrets: mgmtCtx.Wrangler.Core.Secret(), userMGR: userMGR, tokenMGR: tokenMGR, providerName: providerName, diff --git a/pkg/auth/providers/ldap/ldap_provider_test.go b/pkg/auth/providers/ldap/ldap_provider_test.go index 86f77f510c4..80b80963301 100644 --- a/pkg/auth/providers/ldap/ldap_provider_test.go +++ b/pkg/auth/providers/ldap/ldap_provider_test.go @@ -9,9 +9,9 @@ import ( "github.com/rancher/norman/objectclient" v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/tokens" - corev1 "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/user" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -82,7 +82,7 @@ func Test_ldapProvider_getLDAPConfig(t *testing.T) { type fields struct { ctx context.Context authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController userMGR user.Manager tokenMGR *tokens.Manager certs string diff --git a/pkg/auth/providers/oidc/oidc_provider.go b/pkg/auth/providers/oidc/oidc_provider.go index a4b3d1ce6e5..0eeb528c757 100644 --- a/pkg/auth/providers/oidc/oidc_provider.go +++ b/pkg/auth/providers/oidc/oidc_provider.go @@ -19,10 +19,10 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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" "golang.org/x/oauth2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,7 +40,7 @@ type OpenIDCProvider struct { Type string CTX context.Context AuthConfigs v3.AuthConfigInterface - Secrets corev1.SecretInterface + Secrets wcorev1.SecretController UserMGR user.Manager TokenMGR *tokens.Manager } @@ -64,7 +64,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. Type: client.OIDCConfigType, CTX: ctx, AuthConfigs: mgmtCtx.Management.AuthConfigs(""), - Secrets: mgmtCtx.Core.Secrets(""), + Secrets: mgmtCtx.Wrangler.Core.Secret(), UserMGR: userMGR, TokenMGR: tokenMGR, } diff --git a/pkg/auth/providers/saml/saml_provider.go b/pkg/auth/providers/saml/saml_provider.go index d1a1d332d75..0f40d8a787c 100644 --- a/pkg/auth/providers/saml/saml_provider.go +++ b/pkg/auth/providers/saml/saml_provider.go @@ -18,10 +18,10 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" client "github.com/rancher/rancher/pkg/client/generated/management/v3" publicclient "github.com/rancher/rancher/pkg/client/generated/management/v3public" - corev1 "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" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -40,7 +40,7 @@ const ( type Provider struct { ctx context.Context authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController samlTokens v3.SamlTokenInterface userMGR user.Manager tokenMGR *tokens.Manager @@ -60,7 +60,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user. samlp := &Provider{ ctx: ctx, authConfigs: mgmtCtx.Management.AuthConfigs(""), - secrets: mgmtCtx.Core.Secrets(""), + secrets: mgmtCtx.Wrangler.Core.Secret(), samlTokens: mgmtCtx.Management.SamlTokens(""), userMGR: userMGR, tokenMGR: tokenMGR, diff --git a/pkg/auth/providers/saml/saml_provider_test.go b/pkg/auth/providers/saml/saml_provider_test.go index 68534055271..3920bcf199e 100644 --- a/pkg/auth/providers/saml/saml_provider_test.go +++ b/pkg/auth/providers/saml/saml_provider_test.go @@ -10,6 +10,7 @@ import ( "github.com/rancher/rancher/pkg/auth/tokens" v3 "github.com/rancher/rancher/pkg/generated/norman/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" + "github.com/rancher/rancher/pkg/wrangler" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,6 +23,12 @@ func TestConfiguredOktaProviderContainsLdapProvider(t *testing.T) { ctx := context.Background() mgmtCtx, err := config.NewScaledContext(rest.Config{}, nil) require.NoError(t, err, "Failed to create NewScaledContext") + + // Create the dummy wrangler context + wranglerContext, err := wrangler.NewContext(ctx, nil, &rest.Config{}) + require.NoError(t, err, "Failed to create wranglerContext") + mgmtCtx.Wrangler = wranglerContext + tokenMGR := tokens.NewManager(ctx, mgmtCtx) provider, ok := Configure(ctx, mgmtCtx, mgmtCtx.UserManager, tokenMGR, "okta").(*Provider) require.True(t, ok, "Failed to Configure a valid Provider") diff --git a/pkg/auth/providers/setup.go b/pkg/auth/providers/setup.go index d8785a00cef..5522a6227f5 100644 --- a/pkg/auth/providers/setup.go +++ b/pkg/auth/providers/setup.go @@ -7,7 +7,6 @@ import ( "github.com/rancher/norman/types" "github.com/rancher/rancher/pkg/auth/api/secrets" client "github.com/rancher/rancher/pkg/client/generated/management/v3" - "github.com/rancher/rancher/pkg/namespace" managementschema "github.com/rancher/rancher/pkg/schemas/management.cattle.io/v3" "github.com/rancher/rancher/pkg/types/config" ) @@ -34,7 +33,7 @@ func SetupAuthConfig(ctx context.Context, management *config.ScaledContext, sche Configure(ctx, management) authConfigBaseSchema := schemas.Schema(&managementschema.Version, client.AuthConfigType) - authConfigBaseSchema.Store = secrets.Wrap(authConfigBaseSchema.Store, management.Core.Secrets(namespace.GlobalNamespace)) + authConfigBaseSchema.Store = secrets.Wrap(authConfigBaseSchema.Store, management.Wrangler.Core.Secret()) for _, authConfigSubtype := range authConfigTypes { subSchema := schemas.Schema(&managementschema.Version, authConfigSubtype) GetProviderByType(authConfigSubtype).CustomizeSchema(subSchema) diff --git a/pkg/auth/server.go b/pkg/auth/server.go index 5faf139057c..79f790bb5d3 100644 --- a/pkg/auth/server.go +++ b/pkg/auth/server.go @@ -56,6 +56,8 @@ func NewServer(ctx context.Context, cfg *rest.Config, wContext *wrangler.Context return nil, err } + sc.Wrangler = wContext + sc.UserManager, err = common.NewUserManagerNoBindings(sc) if err != nil { return nil, err @@ -66,8 +68,6 @@ func NewServer(ctx context.Context, cfg *rest.Config, wContext *wrangler.Context return nil, err } - sc.Wrangler = wContext - authenticator := requests.NewAuthenticator(ctx, clusterrouter.GetClusterID, sc) authManagement, err := newAPIManagement(ctx, sc) if err != nil { diff --git a/pkg/controllers/management/auth/auth_config.go b/pkg/controllers/management/auth/auth_config.go index f6f4ffdacd4..568c8c22c7c 100644 --- a/pkg/controllers/management/auth/auth_config.go +++ b/pkg/controllers/management/auth/auth_config.go @@ -52,7 +52,7 @@ func newAuthConfigController(context context.Context, mgmt *config.ManagementCon controller := &authConfigController{ users: mgmt.Management.Users("").Controller().Lister(), authRefresher: providerrefresh.NewUserAuthRefresher(context, scaledContext), - cleanup: cleanup.NewCleanupService(mgmt.Core.Secrets(""), mgmt.Wrangler.Mgmt), + cleanup: cleanup.NewCleanupService(mgmt.Wrangler.Core.Secret(), mgmt.Wrangler.Mgmt), authConfigsUnstructured: scaledContext.Management.AuthConfigs("").ObjectClient().UnstructuredClient(), } return controller diff --git a/pkg/controllers/managementapi/samlconfig/samlconfig.go b/pkg/controllers/managementapi/samlconfig/samlconfig.go index ddb7107b691..2e694c6da3b 100644 --- a/pkg/controllers/managementapi/samlconfig/samlconfig.go +++ b/pkg/controllers/managementapi/samlconfig/samlconfig.go @@ -7,16 +7,16 @@ import ( v32 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3" "github.com/rancher/rancher/pkg/auth/providers/common" "github.com/rancher/rancher/pkg/auth/providers/saml" - corev1 "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" + wcorev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) type authProvider struct { authConfigs v3.AuthConfigInterface - secrets corev1.SecretInterface + secrets wcorev1.SecretController } func Register(ctx context.Context, apiContext *config.ScaledContext) { @@ -27,7 +27,7 @@ func Register(ctx context.Context, apiContext *config.ScaledContext) { func newAuthProvider(apiContext *config.ScaledContext) *authProvider { a := &authProvider{ authConfigs: apiContext.Management.AuthConfigs(""), - secrets: apiContext.Core.Secrets(""), + secrets: apiContext.Wrangler.Core.Secret(), } return a }