Skip to content

Commit

Permalink
Blocking login while migration is running
Browse files Browse the repository at this point in the history
  • Loading branch information
crobby committed Aug 3, 2023
1 parent 840c5a7 commit 673e765
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
36 changes: 22 additions & 14 deletions pkg/agent/clean/active_directory.go
Expand Up @@ -41,11 +41,12 @@ const (
listAdUsersOperation = "list-ad-users"
migrateAdUserOperation = "migrate-ad-user"
activeDirectoryPrefix = "activedirectory_user://"
statusConfigMapName = "ad-guid-migration"
statusConfigMapNamespace = "cattle-system"
statusMigrationField = "ad-guid-migration-status"
statusMigrationFinished = "Finished"
statusMigrationRunning = "Running"
StatusConfigMapName = "ad-guid-migration"
StatusConfigMapNamespace = "cattle-system"
StatusMigrationField = "ad-guid-migration-status"
StatusMigrationFinished = "Finished"
StatusMigrationRunning = "Running"
StatusLoginDisabled = "login is disabled while migration is running"
adGUIDMigrationLabel = "ad-guid-migration"
adGUIDMigrationAnnotation = "ad-guid-migration-data"
migratedLabelValue = "migrated"
Expand Down Expand Up @@ -83,6 +84,13 @@ func (e LdapConnectionPermanentlyFailed) Error() string {
return "ldap search failed to connect after exhausting maximum retry attempts"
}

type LoginDisabledError struct{}

// Error provides a string representation of an LdapErrorNotFound
func (e LoginDisabledError) Error() string {
return StatusLoginDisabled
}

func scaledContext(restConfig *restclient.Config) (*config.ScaledContext, error) {
sc, err := config.NewScaledContext(*restConfig, nil)
if err != nil {
Expand Down Expand Up @@ -297,7 +305,7 @@ func ListAdUsers(clientConfig *restclient.Config) error {
}
defer lConn.Close()

err = updateMigrationStatus(sc, statusMigrationField, statusMigrationRunning)
err = updateMigrationStatus(sc, StatusMigrationField, StatusMigrationRunning)
if err != nil {
return fmt.Errorf("unable to update migration status configmap: %v", err)
}
Expand Down Expand Up @@ -379,8 +387,8 @@ func ListAdUsers(clientConfig *restclient.Config) error {
// Having updated all permissions bindings and resolved all potential principal ID conflicts, it is
// finally safe to save the modified original user

userToMigrate.originalUser.Annotations[adGUIDMigrationLabel] = userToMigrate.guid
userToMigrate.originalUser.Labels[adGUIDMigrationAnnotation] = migratedLabelValue
userToMigrate.originalUser.Annotations[adGUIDMigrationAnnotation] = userToMigrate.guid
userToMigrate.originalUser.Labels[adGUIDMigrationLabel] = migratedLabelValue
_, err = sc.Management.Users("").Update(userToMigrate.originalUser)
if err != nil {
logrus.Errorf("[%v] failed to save modified user '%v' with: %v", listAdUsersOperation, userToMigrate.originalUser.Name, err)
Expand All @@ -389,7 +397,7 @@ func ListAdUsers(clientConfig *restclient.Config) error {
}
}

err = updateMigrationStatus(sc, statusMigrationField, statusMigrationFinished)
err = updateMigrationStatus(sc, StatusMigrationField, StatusMigrationFinished)
if err != nil {
return fmt.Errorf("unable to update migration status configmap: %v", err)
}
Expand Down Expand Up @@ -695,26 +703,26 @@ func migratePRTB(guid string, newPrincipalID string, sc *config.ScaledContext, d
}

func updateMigrationStatus(sc *config.ScaledContext, status string, value string) error {
cm, err := sc.Core.ConfigMaps(statusConfigMapNamespace).Get(statusConfigMapName, metav1.GetOptions{})
cm, err := sc.Core.ConfigMaps(StatusConfigMapNamespace).Get(StatusConfigMapName, metav1.GetOptions{})
if err != nil {
// Create a new ConfigMap if it doesn't exist
if !apierrors.IsNotFound(err) {
return err
}
cm = &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: statusConfigMapName,
Namespace: statusConfigMapNamespace,
Name: StatusConfigMapName,
Namespace: StatusConfigMapNamespace,
},
}
}

cm.Data = map[string]string{status: value}

if _, err := sc.Core.ConfigMaps(statusConfigMapNamespace).Update(cm); err != nil {
if _, err := sc.Core.ConfigMaps(StatusConfigMapNamespace).Update(cm); err != nil {
// If the ConfigMap does not exist, create it
if apierrors.IsNotFound(err) {
_, err = sc.Core.ConfigMaps(statusConfigMapNamespace).Create(cm)
_, err = sc.Core.ConfigMaps(StatusConfigMapNamespace).Create(cm)
if err != nil {
return fmt.Errorf("unable to create migration status configmap: %v", err)
}
Expand Down
Expand Up @@ -36,6 +36,7 @@ var scopes = []string{UserScope, GroupScope}
type adProvider struct {
ctx context.Context
authConfigs v3.AuthConfigInterface
configMaps corev1.ConfigMapInterface
secrets corev1.SecretInterface
userMGR user.Manager
certs string
Expand All @@ -47,6 +48,7 @@ func Configure(ctx context.Context, mgmtCtx *config.ScaledContext, userMGR user.
return &adProvider{
ctx: ctx,
authConfigs: mgmtCtx.Management.AuthConfigs(""),
configMaps: mgmtCtx.Core.ConfigMaps(""),
secrets: mgmtCtx.Core.Secrets(""),
userMGR: userMGR,
tokenMGR: tokenMGR,
Expand Down Expand Up @@ -78,6 +80,12 @@ func (p *adProvider) AuthenticateUser(ctx context.Context, input interface{}) (v
return v3.Principal{}, nil, "", errors.New("unexpected input type")
}

migrationConfigMap, _ := p.configMaps.GetNamespaced("cattle-system", "ad-guid-migration", metav1.GetOptions{})
migrationStatus := migrationConfigMap.Data["ad-guid-migration-status"]
if migrationStatus == "Running" {
return v3.Principal{}, nil, "Unable to perform login while migration is running", fmt.Errorf("login is disabled while migration is running")
}

config, caPool, err := p.getActiveDirectoryConfig()
if err != nil {
return v3.Principal{}, nil, "", errors.New("can't find authprovider")
Expand Down
4 changes: 4 additions & 0 deletions pkg/auth/providers/publicapi/login.go
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/rancher/rancher/pkg/agent/clean"
"io/ioutil"
"net/http"
"strconv"
Expand Down Expand Up @@ -76,6 +77,9 @@ func (h *loginHandler) login(actionName string, action *types.Action, request *t
if httperror.IsAPIError(err) {
return err
}
if err.Error() == clean.StatusLoginDisabled {
return httperror.WrapAPIError(err, httperror.ClusterUnavailable, clean.StatusLoginDisabled)
}
return httperror.WrapAPIError(err, httperror.ServerError, "Server error while authenticating")
}

Expand Down

0 comments on commit 673e765

Please sign in to comment.