Merge branch 'master' into 17222-doc-add-keep-components-overview
[arvados.git] / tools / sync-groups / sync-groups.go
index 2ffd61fec6ff2116fe54f3bfe84c6acccd094ff7..24e838c8f1ec64434a13652b36b18689ddb5a216 100644 (file)
@@ -226,8 +226,9 @@ func SetParentGroup(cfg *ConfigParams) error {
                                log.Println("Default parent group not found, creating...")
                        }
                        groupData := map[string]string{
-                               "name":       cfg.ParentGroupName,
-                               "owner_uuid": cfg.SysUserUUID,
+                               "name":        cfg.ParentGroupName,
+                               "owner_uuid":  cfg.SysUserUUID,
+                               "group_class": "role",
                        }
                        if err := CreateGroup(cfg, &parentGroup, groupData); err != nil {
                                return fmt.Errorf("error creating system user owned group named %q: %s", groupData["name"], err)
@@ -274,7 +275,13 @@ func GetConfig() (config ConfigParams, err error) {
        if !u.IsActive || !u.IsAdmin {
                return config, fmt.Errorf("current user (%s) is not an active admin user", u.UUID)
        }
-       config.SysUserUUID = u.UUID[:12] + "000000000000000"
+
+       var ac struct{ ClusterID string }
+       err = config.Client.RequestAndDecode(&ac, "GET", "arvados/v1/config", nil, nil)
+       if err != nil {
+               return config, fmt.Errorf("error getting the exported config: %s", err)
+       }
+       config.SysUserUUID = ac.ClusterID + "-tpzed-000000000000000"
 
        // Set up remote groups' parent
        if err = SetParentGroup(&config); err != nil {
@@ -431,7 +438,7 @@ func ProcessFile(
                                "group_class": "role",
                        }
                        if e := CreateGroup(cfg, &newGroup, groupData); e != nil {
-                               err = fmt.Errorf("error creating group named %q: %s", groupName, err)
+                               err = fmt.Errorf("error creating group named %q: %s", groupName, e)
                                return
                        }
                        // Update cached group data
@@ -450,8 +457,13 @@ func ProcessFile(
                        if cfg.Verbose {
                                log.Printf("Adding %q to group %q", groupMember, groupName)
                        }
-                       // User wasn't a member, but should be.
-                       if e := AddMemberToGroup(cfg, allUsers[userIDToUUID[groupMember]], gi.Group, groupPermission); e != nil {
+                       // User permissionwasn't there, but should be. Avoid duplicating the
+                       // group->user link when necessary.
+                       createG2ULink := true
+                       if _, ok := gi.PreviousMembers[groupMember]; ok {
+                               createG2ULink = false // User is already member of the group
+                       }
+                       if e := AddMemberToGroup(cfg, allUsers[userIDToUUID[groupMember]], gi.Group, groupPermission, createG2ULink); e != nil {
                                err = e
                                return
                        }
@@ -498,7 +510,7 @@ func subtract(setA map[string]GroupPermissions, setB map[string]GroupPermissions
                } else {
                        for perm := range setA[element] {
                                if _, ok := setB[element][perm]; !ok {
-                                       result[element][perm] = true
+                                       result[element] = GroupPermissions{perm: true}
                                }
                        }
                }
@@ -523,17 +535,21 @@ func GetRemoteGroups(cfg *ConfigParams, allUsers map[string]arvados.User) (remot
 
        params := arvados.ResourceListParams{
                Filters: []arvados.Filter{{
-                       Attr:     "owner_uuid",
+                       Attr:     "tail_uuid",
                        Operator: "=",
                        Operand:  cfg.ParentGroupUUID,
                }},
        }
-       results, err := GetAll(cfg.Client, "groups", params, &GroupList{})
+       results, err := GetAll(cfg.Client, "links", params, &LinkList{})
        if err != nil {
                return remoteGroups, groupNameToUUID, fmt.Errorf("error getting remote groups: %s", err)
        }
        for _, item := range results {
-               group := item.(arvados.Group)
+               var group arvados.Group
+               err = GetGroup(cfg, &group, item.(arvados.Link).HeadUUID)
+               if err != nil {
+                       return remoteGroups, groupNameToUUID, fmt.Errorf("error getting remote group: %s", err)
+               }
                // Group -> User filter
                g2uFilter := arvados.ResourceListParams{
                        Filters: []arvados.Filter{{
@@ -716,18 +732,21 @@ func RemoveMemberLinksFromGroup(cfg *ConfigParams, user arvados.User, linkNames
 }
 
 // AddMemberToGroup create membership links
-func AddMemberToGroup(cfg *ConfigParams, user arvados.User, group arvados.Group, perm string) error {
+func AddMemberToGroup(cfg *ConfigParams, user arvados.User, group arvados.Group, perm string, createG2ULink bool) error {
        var newLink arvados.Link
-       linkData := map[string]string{
-               "owner_uuid": cfg.SysUserUUID,
-               "link_class": "permission",
-               "name":       "can_read",
-               "tail_uuid":  group.UUID,
-               "head_uuid":  user.UUID,
-       }
-       if err := CreateLink(cfg, &newLink, linkData); err != nil {
-               userID, _ := GetUserID(user, cfg.UserID)
-               return fmt.Errorf("error adding group %q -> user %q read permission: %s", group.Name, userID, err)
+       var linkData map[string]string
+       if createG2ULink {
+               linkData = map[string]string{
+                       "owner_uuid": cfg.SysUserUUID,
+                       "link_class": "permission",
+                       "name":       "can_read",
+                       "tail_uuid":  group.UUID,
+                       "head_uuid":  user.UUID,
+               }
+               if err := CreateLink(cfg, &newLink, linkData); err != nil {
+                       userID, _ := GetUserID(user, cfg.UserID)
+                       return fmt.Errorf("error adding group %q -> user %q read permission: %s", group.Name, userID, err)
+               }
        }
        linkData = map[string]string{
                "owner_uuid": cfg.SysUserUUID,