From 1db8050bf78657150dc5a4d5199726a7c11a2552 Mon Sep 17 00:00:00 2001 From: Tommi Hovi Date: Mon, 20 Nov 2023 14:29:26 +0200 Subject: [PATCH] Feat: Allow diffing and printing group users for multiple groups at a time by providing a commaseparated string of group names. --- client/client.go | 56 ++++++++++++++++++++++++++++++++++++++++-------- main.go | 13 +++++++++-- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/client/client.go b/client/client.go index 50d4a85..6f56717 100644 --- a/client/client.go +++ b/client/client.go @@ -137,8 +137,8 @@ func (oi *OIClient) GetUsersInGroup(wantGroupName string) ([]string, error) { return foundUsers, nil } -func (oi *OIClient) PrintUsersInGroup(wantGroupName string) error { - foundUsers, err := oi.GetUsersInGroup(wantGroupName) +func (oi *OIClient) PrintUsersInGroups(wantGroupsName []string) error { + foundUsers, err := oi.getUsersInGroupsUnion(wantGroupsName) if err != nil { return err } @@ -150,29 +150,67 @@ func (oi *OIClient) PrintUsersInGroup(wantGroupName string) error { return nil } -// PrintGroupDiff prints the difference of 2 groups -func (oi *OIClient) PrintGroupDiff(groupA, groupB string) error { - groupAUsers, err := oi.GetUsersInGroup(groupA) +// PrintGroupDiff prints the difference of two sets of groups +func (oi *OIClient) PrintGroupDiff(groupsA, groupsB []string, hideDeprovisioned bool) error { + groupsAUsers, err := oi.getUsersInGroupsUnion(groupsA) if err != nil { return err } - groupBUsers, err := oi.GetUsersInGroup(groupB) + + groupBUsers, err := oi.getUsersInGroupsUnion(groupsB) if err != nil { return err } - notInB, notInA := lo.Difference(groupAUsers, groupBUsers) + notInB, notInA := lo.Difference(groupsAUsers, groupBUsers) + + groupA := strings.Join(groupsA, ", ") + groupB := strings.Join(groupsB, ", ") - fmt.Printf("Users in %s, but not in %s:\n", groupA, groupB) + headerStringFmt := "Users in %s, but not in %s:\n" + if hideDeprovisioned { + headerStringFmt = "Users (excluding deprovisioned) in %s, but not in %s:\n" + } + + fmt.Printf(headerStringFmt, groupA, groupB) for _, user := range notInB { + if strings.Contains(user, "(DEPROVISIONED)") && hideDeprovisioned { + continue + } + fmt.Println(user) } fmt.Println() - fmt.Printf("Users in %s, but not in %s:\n", groupB, groupA) + fmt.Printf(headerStringFmt, groupB, groupA) for _, user := range notInA { + if strings.Contains(user, "(DEPROVISIONED)") && hideDeprovisioned { + continue + } + fmt.Println(user) } return nil } + +// getUsersInGroupsUnion returns a deduplicated slice of users who are in at least one of the given groups +func (oi *OIClient) getUsersInGroupsUnion(groups []string) ([]string, error) { + users := make([]string, 0) + + for _, group := range groups { + groupUsers, err := oi.GetUsersInGroup(group) + if err != nil { + return nil, err + } + users = append(users, groupUsers...) + } + + // dedup + users = lo.Uniq(users) + + // sort + sort.Strings(users) + + return users, nil +} diff --git a/main.go b/main.go index 368c53e..74364b3 100644 --- a/main.go +++ b/main.go @@ -36,11 +36,20 @@ func run() error { // Handle the subcommands switch os.Args[1] { case "group": - return oic.PrintUsersInGroup(os.Args[2]) + // CommaSeparated list of groups + groups := strings.Split(os.Args[2], ",") + + return oic.PrintUsersInGroups(groups) case "user": return oic.PrintGroupsForUser(os.Args[2]) case "diff": - return oic.PrintGroupDiff(os.Args[2], os.Args[3]) + // CommaSeparated list of groups + groupsA := strings.Split(os.Args[2], ",") + groupsB := strings.Split(os.Args[3], ",") + + hideDeprovisioned := false + + return oic.PrintGroupDiff(groupsA, groupsB, hideDeprovisioned) default: fmt.Println("Invalid subcommand. Valid commands are: group, diff and user") os.Exit(1)