X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/885a103aafafc37a5ebc5052feca6453cd0f096a..bb99d90e25a47dff9405fb6f68be0779dd2d8989:/tools/sync-groups/sync-groups.go diff --git a/tools/sync-groups/sync-groups.go b/tools/sync-groups/sync-groups.go index 24e838c8f1..e1e054a663 100644 --- a/tools/sync-groups/sync-groups.go +++ b/tools/sync-groups/sync-groups.go @@ -16,6 +16,7 @@ import ( "os" "strings" + "git.arvados.org/arvados.git/lib/cmd" "git.arvados.org/arvados.git/sdk/go/arvados" ) @@ -119,6 +120,7 @@ type ConfigParams struct { Path string UserID string Verbose bool + CaseInsensitive bool ParentGroupUUID string ParentGroupName string SysUserUUID string @@ -141,9 +143,9 @@ func ParseFlags(config *ConfigParams) error { * 1st: Group name * 2nd: User identifier * 3rd (Optional): User permission on the group: can_read, can_write or can_manage. (Default: can_write)` - fmt.Fprintf(os.Stderr, "%s\n\n", usageStr) - fmt.Fprintf(os.Stderr, "Usage:\n%s [OPTIONS] \n\n", os.Args[0]) - fmt.Fprintf(os.Stderr, "Options:\n") + fmt.Fprintf(flags.Output(), "%s\n\n", usageStr) + fmt.Fprintf(flags.Output(), "Usage:\n%s [OPTIONS] \n\n", os.Args[0]) + fmt.Fprintf(flags.Output(), "Options:\n") flags.PrintDefaults() } @@ -152,6 +154,10 @@ func ParseFlags(config *ConfigParams) error { "user-id", "email", "Attribute by which every user is identified. Valid values are: email and username.") + caseInsensitive := flags.Bool( + "case-insensitive", + false, + "Performs case insensitive matching on user IDs. Off by default.") verbose := flags.Bool( "verbose", false, @@ -165,11 +171,9 @@ func ParseFlags(config *ConfigParams) error { "", "Use given group UUID as a parent for the remote groups. Should be owned by the system user. If not specified, a group named '"+config.ParentGroupName+"' will be used (and created if nonexistant).") - // Parse args; omit the first arg which is the command name - flags.Parse(os.Args[1:]) - - // Print version information if requested - if *getVersion { + if ok, code := cmd.ParseFlags(flags, os.Args[0], os.Args[1:], "input-file.csv", os.Stderr); !ok { + os.Exit(code) + } else if *getVersion { fmt.Printf("%s %s\n", os.Args[0], version) os.Exit(0) } @@ -196,6 +200,7 @@ func ParseFlags(config *ConfigParams) error { config.ParentGroupUUID = *parentGroupUUID config.UserID = *userID config.Verbose = *verbose + config.CaseInsensitive = *caseInsensitive return nil } @@ -299,7 +304,11 @@ func doMain(cfg *ConfigParams) error { } defer f.Close() - log.Printf("%s %s started. Using %q as users id and parent group UUID %q", os.Args[0], version, cfg.UserID, cfg.ParentGroupUUID) + iCaseLog := "" + if cfg.UserID == "username" && cfg.CaseInsensitive { + iCaseLog = " - username matching requested to be case-insensitive" + } + log.Printf("%s %s started. Using %q as users id and parent group UUID %q%s", os.Args[0], version, cfg.UserID, cfg.ParentGroupUUID, iCaseLog) // Get the complete user list to minimize API Server requests allUsers := make(map[string]arvados.User) @@ -316,6 +325,12 @@ func doMain(cfg *ConfigParams) error { if err != nil { return err } + if cfg.UserID == "username" && uID != "" && cfg.CaseInsensitive { + uID = strings.ToLower(uID) + if uuid, found := userIDToUUID[uID]; found { + return fmt.Errorf("case insensitive collision for username %q between %q and %q", uID, u.UUID, uuid) + } + } userIDToUUID[uID] = u.UUID if cfg.Verbose { log.Printf("Seen user %q (%s)", u.Username, u.UUID) @@ -415,6 +430,9 @@ func ProcessFile( membersSkipped++ continue } + if cfg.UserID == "username" && cfg.CaseInsensitive { + groupMember = strings.ToLower(groupMember) + } if !(groupPermission == "can_read" || groupPermission == "can_write" || groupPermission == "can_manage") { log.Printf("Warning: 3rd field should be 'can_read', 'can_write' or 'can_manage'. Found: %q at line %d, skipping.", groupPermission, lineNo) membersSkipped++ @@ -494,9 +512,7 @@ func GetAll(c *arvados.Client, res string, params arvados.ResourceListParams, pa if page.Len() == 0 { break } - for _, i := range page.GetItems() { - allItems = append(allItems, i) - } + allItems = append(allItems, page.GetItems()...) params.Offset += page.Len() } return allItems, nil @@ -634,6 +650,9 @@ func GetRemoteGroups(cfg *ConfigParams, allUsers map[string]arvados.User) (remot if err != nil { return remoteGroups, groupNameToUUID, err } + if cfg.UserID == "username" && cfg.CaseInsensitive { + memberID = strings.ToLower(memberID) + } membersSet[memberID] = u2gLinkSet[link.HeadUUID] } remoteGroups[group.UUID] = &GroupInfo{ @@ -714,9 +733,7 @@ func RemoveMemberLinksFromGroup(cfg *ConfigParams, user arvados.User, linkNames userID, _ := GetUserID(user, cfg.UserID) return fmt.Errorf("error getting links needed to remove user %q from group %q: %s", userID, group.Name, err) } - for _, link := range l { - links = append(links, link) - } + links = append(links, l...) } for _, item := range links { link := item.(arvados.Link)