Updated gam <UserTypeEntity> print|show groups` to show totals
Some checks failed
Build and test GAM / build (Win64, build, 8, VC-WIN64A, windows-2022) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 2, linux-aarch64, [self-hosted linux arm64]) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 4, linux-aarch64, [self-hosted linux arm64], yes) (push) Has been cancelled
Build and test GAM / build (aarch64, build, 6, darwin64-arm64, macos-14) (push) Has been cancelled
Build and test GAM / build (universal2, build, 7, darwin64-arm64 darwin64-x86_64, macos-14) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-20.04) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 3, linux-x86_64, ubuntu-20.04, yes) (push) Has been cancelled
Build and test GAM / build (x86_64, build, 5, darwin64-x86_64, macos-12) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.9) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.10) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.11) (push) Has been cancelled
Build and test GAM / build (x86_64, test, 9, ubuntu-22.04, 3.8) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Check for Google Root CA Updates / check-apis (push) Has been cancelled
Build and test GAM / merge (push) Has been cancelled
Build and test GAM / publish (push) Has been cancelled

This commit is contained in:
Ross Scroggs
2024-07-31 16:37:28 -07:00
parent 10e54e49a5
commit 8211d5df8c
7 changed files with 86 additions and 23 deletions

View File

@@ -10,6 +10,14 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
See [Downloads-Installs](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation
### 6.79.07
Added option `totalonly` to `gam <UserTypeEntity> print|show groups` that displays
the user email address and the total number of groups to which it belongs. This is in
contrast to `countsonly` that has to make an additional API call per group per user to get the user's role.
When `countsonly` is specified, an additional column `Total` is displayed that is the sum
of the role counts.
### 6.79.06
Fixed bug in `gam calendars <CalendarEntity> update event ... removeattendee <EmailAddress>` that caused a trap

View File

@@ -251,7 +251,7 @@ writes the credentials into the file oauth2.txt.
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
admin@server:/Users/admin$ gam version
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
GAMADV-XTD3 6.79.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.79.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
MacOS Sonoma 14.5 x86_64
@@ -923,7 +923,7 @@ writes the credentials into the file oauth2.txt.
C:\>del C:\GAMConfig\oauth2.txt
C:\>gam version
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
GAMADV-XTD3 6.79.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.79.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
Windows-10-10.0.17134 AMD64

View File

@@ -14,6 +14,8 @@
- [Display group details in CSV format](#display-group-details-in-csv-format)
- [Display group counts as an indented list](#display-group-counts-as-an-indented-list)
- [Display group counts in CSV format](#display-group-counts-in-csv-format)
- [Display total group counts as an indented list](#display-total-group-counts-as-an-indented-list)
- [Display total group counts in CSV format](#display-total-group-counts-in-csv-format)
- [Display group addresses in CSV format](#display-group-addresses-in-csv-format)
- [Display groups and their parents](#display-groups-and-their-parents)
- [Add a target user to the same groups as a source user](#add-a-target-user-to-the-same-groups-as-a-source-user)
@@ -461,6 +463,10 @@ gam <UserTypeEntity> show groups
[(domain <DomainName>)|(customerid <CustomerID>)]
[roles <GroupRoleList>] countsonly
```
By default, all groups to which a member belongs are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>` of which they are a member
* `customerid <CustomerID>` - For resellers, display all groups in a resold workspace of which they are a member
* `roles <GroupRoleList>` - Limit display to those groups for which the user has a specific role
### Display group counts in CSV format
There is one row per user displaying the number of groups, by role, to which a user belongs.
@@ -476,6 +482,33 @@ By default, all groups to which a member belongs are displayed, these options al
* `customerid <CustomerID>` - For resellers, display all groups in a resold workspace of which they are a member
* `roles <GroupRoleList>` - Limit display to those groups for which the user has a specific role
### Display total group counts as an indented list
There is one row per user displaying the number of groups to which a user belongs.
There is one API call per user to get the total group count.
```
gam <UserTypeEntity> show groups
[(domain <DomainName>)|(customerid <CustomerID>)]
totalonly
```
By default, all groups to which a member belongs are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>` of which they are a member
* `customerid <CustomerID>` - For resellers, display all groups in a resold workspace of which they are a member
### Display total group counts in CSV format
There is one row per user displaying the total number of groups to which a user belongs.
There is one API call per user to get the total group count.
```
gam <UserTypeEntity> print groups [todrive <ToDriveAttribute>*]
[(domain <DomainName>)|(customerid <CustomerID>)]
totalonly
```
By default, all groups to which a member belongs are displayed, these options allow selection of subsets of groups:
* `domain <DomainName>` - Limit display to groups in the domain `<DomainName>` of which they are a member
* `customerid <CustomerID>` - For resellers, display all groups in a resold workspace of which they are a member
### Display group addresses in CSV format
There is one row per user showing the number and list of groups to which a user directly belongs.
```

View File

@@ -3,7 +3,7 @@
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.79.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.79.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
MacOS Sonoma 14.5 x86_64
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
Print the current version of Gam with details and time offset information
```
gam version timeoffset
GAMADV-XTD3 6.79.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.79.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
MacOS Sonoma 14.5 x86_64
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
Print the current version of Gam with extended details and SSL information
```
gam version extended
GAMADV-XTD3 6.79.06 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 6.79.07 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
MacOS Sonoma 14.5 x86_64
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
Path: /Users/Admin/bin/gamadv-xtd3
Version Check:
Current: 5.35.08
Latest: 6.79.06
Latest: 6.79.07
echo $?
1
```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.79.06
6.79.07
```
In Linux/MacOS you can do:
```
@@ -82,7 +82,7 @@ echo $VER
Print the current version of Gam and address of this Wiki
```
gam help
GAM 6.79.06 - https://github.com/taers232c/GAMADV-XTD3
GAM 6.79.07 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.4 64-bit final
MacOS Sonoma 14.5 x86_64

View File

@@ -1994,6 +1994,7 @@ gam revoke browsertoken <BrowserTokenPermanentID>
org|
orgunit|
orgunitpath|
ou|
revoketime|
revokerid|
state|
@@ -5356,7 +5357,7 @@ gam download storagefile <StorageBucketObjectName>
(note clear|([text_html|text_plain] <String>|
(file|htmlfile <FileName> [charset <Charset>])|
(gdoc|ghtml <UserGoogleDoc>)))|
(org|ou|orgunitpath <OrgUnitPath>|<OrgUnitID>)
(ou|org|orgunitpath <OrgUnitPath>|<OrgUnitID>)
(password (random [<Integer>])|(uniquerandom [<Integer>])|blocklogin|<Password>)|
(recoveryemail <EmailAddress>)|
(recoveryphone <string>)|
@@ -7603,10 +7604,10 @@ gam <UserTypeEntity> check group|groups
[roles <GroupRoleList>] [includederivedmembership] [csv] <GroupEntity>
gam <UserTypeEntity> print groups [todrive <ToDriveAttribute>*]
[(domain <DomainName>)|(customerid <CustomerID>)]
[roles <GroupRoleList>] [countsonly|nodetails]
[roles <GroupRoleList>] [countsonly|totalonly|nodetails]
gam <UserTypeEntity> show groups
[(domain <DomainName>)|(customerid <CustomerID>)]
[roles <GroupRoleList>] [countsonly|nodetails]
[roles <GroupRoleList>] [countsonly|totalonly|nodetails]
gam <UserTypeEntity> print grouptree [todrive <ToDriveAttribute>*]
[(domain <DomainName>)|(customerid <CustomerID>)]
[roles <GroupRoleList>]

View File

@@ -2,6 +2,14 @@
Merged GAM-Team version
6.79.07
Added option `totalonly` to `gam <UserTypeEntity> print|show groups` that displays
the user email address and the total number of groups to which it belongs. This is in
contrast to `countsonly` that has to make an additional API call per group per user to get the user's role.
When `countsonly` is specified, an additional column `Total` is displayed that is the sum
of the role counts.
6.79.06
Fixed bug in `gam calendars <CalendarEntity> update event ... removeattendee <EmailAddress>` that caused a trap

View File

@@ -63546,7 +63546,7 @@ def createSharedDrive(users, useDomainAdminAccess=False):
waitingForCreationToComplete(updateInitialDelay)
created = False
retry = 0
while True:
while not created:
try:
callGAPI(drive.drives(), 'get',
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.NOT_FOUND],
@@ -65275,16 +65275,16 @@ def checkUserInGroups(users):
# gam <UserTypeEntity> print groups [todrive <ToDriveAttribute>*]
# [(domain <DomainName>)|(customerid <CustomerID>)]
# [roles <GroupRoleList>] [countsonly|nodetails]
# [roles <GroupRoleList>] [countsonly|totalonly|nodetails]
# gam <UserTypeEntity> show groups
# [(domain <DomainName>)|(customerid <CustomerID>)]
# [roles <GroupRoleList>] [countsonly|nodetails]
# [roles <GroupRoleList>] [countsonly|totalonly|nodetails]
def printShowUserGroups(users):
cd = buildGAPIObject(API.DIRECTORY)
kwargs = {'customer': GC.Values[GC.CUSTOMER_ID]}
csvPF = CSVPrintFile(['User', 'Group', 'Role', 'Status', 'Delivery'], 'sortall') if Act.csvFormat() else None
rolesSet = set()
countsOnly = noDetails = False
countsOnly = noDetails = totalOnly = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -65299,6 +65299,8 @@ def printShowUserGroups(users):
invalidChoiceExit(role, GROUP_ROLES_MAP, True)
elif myarg == 'countsonly':
countsOnly = True
elif myarg == 'totalonly':
countsOnly = totalOnly = True
elif myarg == 'nodetails':
noDetails = True
else:
@@ -65312,15 +65314,17 @@ def printShowUserGroups(users):
csvPF.SetTitles(titles)
csvPF.SetSortTitles([])
elif countsOnly:
zeroCounts = {'User': None}
for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
if role in rolesSet:
zeroCounts[role] = 0
if csvPF:
titles = ['User']
zeroCounts = {'User': None, 'Total': 0}
if not totalOnly:
for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
if role in rolesSet:
titles.append(role)
zeroCounts[role] = 0
if csvPF:
titles = ['User', 'Total']
if not totalOnly:
for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
if role in rolesSet:
titles.append(role)
csvPF.SetTitles(titles)
csvPF.SetSortTitles([])
i, count, users = getEntityArgument(users)
@@ -65348,6 +65352,12 @@ def printShowUserGroups(users):
return
accessErrorExit(cd)
jcount = len(entityList)
if totalOnly:
if not csvPF:
printEntityKVList([Ent.USER, user], ['Total', jcount])
else:
csvPF.WriteRow({'User': user, 'Total': jcount})
continue
if not csvPF:
if allRoles:
entityPerformActionNumItems([Ent.USER, user], jcount, Ent.GROUP, i, count)
@@ -65393,8 +65403,11 @@ def printShowUserGroups(users):
except (GAPI.memberNotFound, GAPI.invalidMember, GAPI.conditionNotMet, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.USER, user, Ent.GROUP, groupEmail], str(e), j, jcount)
if countsOnly:
for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
if role in rolesSet:
userCounts['Total'] += userCounts[role]
if not csvPF:
kvList = []
kvList = ['Total', userCounts['Total']]
for role in [Ent.ROLE_MEMBER, Ent.ROLE_MANAGER, Ent.ROLE_OWNER]:
if role in rolesSet:
kvList.extend([role, userCounts[role]])