}
type ConfigParams struct {
- Path string
- Verbose bool
- Client *arvados.Client
+ Client *arvados.Client
+ CurrentUser arvados.User
+ DeactivateUnlisted bool
+ Path string
+ Verbose bool
}
func ParseFlags(cfg *ConfigParams) error {
flags.PrintDefaults()
}
+ deactivateUnlisted := flags.Bool(
+ "deactivate-unlisted",
+ false,
+ "Deactivate users that are not in the input file.")
verbose := flags.Bool(
"verbose",
false,
return fmt.Errorf("input file path invalid")
}
+ cfg.DeactivateUnlisted = *deactivateUnlisted
cfg.Path = *srcPath
cfg.Verbose = *verbose
return cfg, fmt.Errorf("error getting the current user: %s", err)
}
if !u.IsAdmin {
- return cfg, fmt.Errorf("current user (%s) is not an admin user", u.UUID)
+ return cfg, fmt.Errorf("current user %q is not an admin user", u.UUID)
+ }
+ if cfg.Verbose {
+ log.Printf("Running as admin user %q", u.UUID)
}
+ cfg.CurrentUser = u
return cfg, nil
}
defer f.Close()
allUsers := make(map[string]arvados.User)
+ processedUsers := make(map[string]bool)
results, err := GetAll(cfg.Client, "users", arvados.ResourceListParams{}, &UserList{})
if err != nil {
return fmt.Errorf("error getting all users: %s", err)
for _, item := range results {
u := item.(arvados.User)
allUsers[strings.ToLower(u.Email)] = u
+ processedUsers[strings.ToLower(u.Email)] = false
}
loadedRecords, err := LoadInputFile(f)
updatesSucceeded, updatesFailed := 0, 0
for _, record := range loadedRecords {
+ if record.Email == cfg.CurrentUser.Email {
+ log.Printf("Skipping current user %q from processing", record.Email)
+ continue
+ }
if updated, err := ProcessRecord(cfg, record, allUsers); err != nil {
log.Printf("error processing record %q: %s", record.Email, err)
updatesFailed++
} else if updated {
+ processedUsers[strings.ToLower(record.Email)] = true
updatesSucceeded++
}
}
- log.Printf("Updated %d account(s), failed to update %d account(s)", updatesSucceeded, updatesFailed)
+
+ if cfg.DeactivateUnlisted {
+ for email, user := range allUsers {
+ if user.UUID == cfg.CurrentUser.UUID {
+ log.Printf("Skipping current user deactivation: %s", user.UUID)
+ continue
+ }
+ if !processedUsers[email] {
+ if cfg.Verbose {
+ log.Printf("Deactivating unlisted user %q", user.UUID)
+ }
+ var updatedUser arvados.User
+ if err := UnsetupUser(cfg.Client, user.UUID, &updatedUser); err != nil {
+ log.Printf("error deactivating unlisted user %q: %s", user.UUID, err)
+ updatesFailed++
+ } else {
+ allUsers[email] = updatedUser
+ updatesSucceeded++
+ }
+ }
+ }
+ }
+
+ log.Printf("Updated %d user(s), failed to update %d user(s)", updatesSucceeded, updatesFailed)
return nil
}
// ProcessRecord creates or updates a user based on the given record
func ProcessRecord(cfg *ConfigParams, record userRecord, allUsers map[string]arvados.User) (bool, error) {
+ if cfg.Verbose {
+ log.Printf("Processing record for user %q", record.Email)
+ }
+
wantedActiveStatus := strconv.FormatBool(record.Active)
wantedAdminStatus := strconv.FormatBool(record.Admin)
+ createRequired := false
updateRequired := false
// Check if user exists, set its active & admin status.
var user arvados.User
user, ok := allUsers[record.Email]
if !ok {
+ if cfg.Verbose {
+ log.Printf("User %q does not exist, creating", record.Email)
+ }
+ createRequired = true
err := CreateUser(cfg.Client, &user, map[string]string{
"email": record.Email,
"first_name": record.FirstName,
if err != nil {
return false, fmt.Errorf("error creating user %q: %s", record.Email, err)
}
- updateRequired = true
- log.Printf("Created user %q", record.Email)
}
if record.Active != user.IsActive {
updateRequired = true
if record.Active {
+ if cfg.Verbose {
+ log.Printf("User %q is inactive, activating", record.Email)
+ }
// Here we assume the 'setup' is done elsewhere if needed.
err := UpdateUser(cfg.Client, user.UUID, &user, map[string]string{
"is_active": wantedActiveStatus,
return false, fmt.Errorf("error updating user %q: %s", record.Email, err)
}
} else {
+ if cfg.Verbose {
+ log.Printf("User %q is active, deactivating", record.Email)
+ }
err := UnsetupUser(cfg.Client, user.UUID, &user)
if err != nil {
return false, fmt.Errorf("error deactivating user %q: %s", record.Email, err)
}
// Inactive users cannot be admins.
if user.IsActive && record.Admin != user.IsAdmin {
+ if cfg.Verbose {
+ log.Printf("User %q is active, changing admin status to %v", record.Email, record.Admin)
+ }
updateRequired = true
err := UpdateUser(cfg.Client, user.UUID, &user, map[string]string{
"is_admin": wantedAdminStatus,
}
}
allUsers[record.Email] = user
+ if createRequired {
+ log.Printf("Created user %q", record.Email)
+ }
if updateRequired {
log.Printf("Updated user %q", record.Email)
}
- return updateRequired, nil
+ return createRequired || updateRequired, nil
}
// LoadInputFile reads the input file and returns a list of user records