Skip to content

Commit

Permalink
Revert "Revert "[main] Migrate auth/providers from Norman to Wrangler (
Browse files Browse the repository at this point in the history
…rancher#47612…" (rancher#47996)

This reverts commit 32138c3.
  • Loading branch information
crobby authored Nov 11, 2024
1 parent 4ba1a92 commit 30b0b06
Show file tree
Hide file tree
Showing 31 changed files with 517 additions and 289 deletions.
20 changes: 13 additions & 7 deletions pkg/agent/clean/adunmigration/ldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package adunmigration

import (
"bytes"
"context"
"crypto/x509"
"fmt"
"os"
Expand All @@ -11,19 +12,19 @@ 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"
"k8s.io/apimachinery/pkg/runtime"
"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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions pkg/auth/api/secrets/cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand Down
81 changes: 45 additions & 36 deletions pkg/auth/api/secrets/cleanup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,27 @@ 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"
"k8s.io/apimachinery/pkg/runtime/schema"
)

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"},
Expand All @@ -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{
Expand Down Expand Up @@ -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")
})
Expand All @@ -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{
Expand All @@ -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) {
Expand All @@ -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{
Expand Down Expand Up @@ -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")
})
Expand Down
6 changes: 3 additions & 3 deletions pkg/auth/api/secrets/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/auth/cleanup/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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

Expand All @@ -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,

Expand Down
Loading

0 comments on commit 30b0b06

Please sign in to comment.