// Input file as a required positional argument
if flags.NArg() == 0 {
return fmt.Errorf("please provide a path to an input file")
+ } else if flags.NArg() > 1 {
+ return fmt.Errorf("please provide just one input file argument")
}
- srcPath := &os.Args[flags.NFlag()+1]
+ srcPath := &os.Args[len(os.Args)-1]
// Validations
if *srcPath == "" {
allUsers := make(map[string]arvados.User)
userIDToUUID := make(map[string]string) // Index by email or username
dupedEmails := make(map[string][]arvados.User)
+ emptyUserIDs := []string{}
processedUsers := make(map[string]bool)
results, err := GetAll(cfg.Client, "users", arvados.ResourceListParams{}, &UserList{})
if err != nil {
return err
}
if uID == "" {
- return fmt.Errorf("%s is empty for user with uuid %q", cfg.UserID, u.UUID)
+ if u.UUID != cfg.AnonUserUUID && u.UUID != cfg.SysUserUUID {
+ emptyUserIDs = append(emptyUserIDs, u.UUID)
+ log.Printf("Empty %s found in user %s - ignoring", cfg.UserID, u.UUID)
+ }
+ continue
}
if cfg.CaseInsensitive {
uID = strings.ToLower(uID)
log.Printf("User update successes: %d, skips: %d, failures: %d", len(updatesSucceeded), len(updatesSkipped), len(updatesFailed))
- // Report duplicated emails detection
+ var errors []string
if len(dupedEmails) > 0 {
emails := make([]string, len(dupedEmails))
i := 0
emails[i] = e
i++
}
- return fmt.Errorf("skipped %d duplicated email address(es) in the cluster's local user list: %v", len(dupedEmails), emails)
+ errors = append(errors, fmt.Sprintf("skipped %d duplicated email address(es) in the cluster's local user list: %v", len(dupedEmails), emails))
+ }
+ if len(emptyUserIDs) > 0 {
+ errors = append(errors, fmt.Sprintf("skipped %d user account(s) with empty %s: %v", len(emptyUserIDs), cfg.UserID, emptyUserIDs))
+ }
+ if len(errors) > 0 {
+ return fmt.Errorf("%s", strings.Join(errors, "\n"))
}
return nil
Admin bool
}
+func needsUpdating(user arvados.User, record userRecord) bool {
+ userData := userRecord{"", user.FirstName, user.LastName, user.IsActive, user.IsAdmin}
+ recordData := userRecord{"", record.FirstName, record.LastName, record.Active, record.Active && record.Admin}
+ return userData != recordData
+}
+
// ProcessRecord creates or updates a user based on the given record
func ProcessRecord(cfg *ConfigParams, record userRecord, userIDToUUID map[string]string, allUsers map[string]arvados.User) (bool, error) {
if cfg.Verbose {
// Check if user exists, set its active & admin status.
var user arvados.User
recordUUID := userIDToUUID[record.UserID]
- user, ok := allUsers[recordUUID]
- if !ok {
+ user, found := allUsers[recordUUID]
+ if !found {
if cfg.Verbose {
log.Printf("User %q does not exist, creating", record.UserID)
}
if err != nil {
return false, fmt.Errorf("error creating user %q: %s", record.UserID, err)
}
- }
- if record.Active != user.IsActive {
+ } else if needsUpdating(user, record) {
updateRequired = true
if record.Active {
- if cfg.Verbose {
- log.Printf("User %q is inactive, activating", record.UserID)
+ if !user.IsActive && cfg.Verbose {
+ log.Printf("User %q (%s) is inactive, activating", record.UserID, user.UUID)
}
// Here we assume the 'setup' is done elsewhere if needed.
err := UpdateUser(cfg.Client, user.UUID, &user, map[string]string{
- "is_active": wantedActiveStatus,
- "is_admin": wantedAdminStatus, // Just in case it needs to be changed.
+ "first_name": record.FirstName,
+ "last_name": record.LastName,
+ "is_active": wantedActiveStatus,
+ "is_admin": wantedAdminStatus,
})
if err != nil {
return false, fmt.Errorf("error updating user %q: %s", record.UserID, err)
}
} else {
- if cfg.Verbose {
- log.Printf("User %q is active, deactivating", record.UserID)
+ fnChanged := user.FirstName != record.FirstName
+ lnChanged := user.LastName != record.LastName
+ if fnChanged || lnChanged {
+ err := UpdateUser(cfg.Client, user.UUID, &user, map[string]string{
+ "first_name": record.FirstName,
+ "last_name": record.LastName,
+ })
+ if err != nil {
+ return false, fmt.Errorf("error updating user %q: %s", record.UserID, err)
+ }
}
- err := UnsetupUser(cfg.Client, user.UUID, &user)
- if err != nil {
- return false, fmt.Errorf("error deactivating user %q: %s", record.UserID, err)
+ if user.IsActive {
+ if cfg.Verbose {
+ log.Printf("User %q is active, deactivating", record.UserID)
+ }
+ err := UnsetupUser(cfg.Client, user.UUID, &user)
+ if err != nil {
+ return false, fmt.Errorf("error deactivating user %q: %s", record.UserID, 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.UserID, record.Admin)
- }
- updateRequired = true
- err := UpdateUser(cfg.Client, user.UUID, &user, map[string]string{
- "is_admin": wantedAdminStatus,
- })
- if err != nil {
- return false, fmt.Errorf("error updating user %q: %s", record.UserID, err)
- }
- }
- allUsers[record.UserID] = user
if createRequired {
log.Printf("Created user %q", record.UserID)
}