From ed62abe46474ba7ed8033096e611141fde6cd0b1 Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Mon, 4 Sep 2023 20:04:41 -0700 Subject: [PATCH] Added option `ou_and_children ` to `gam print|show crostelemetry` --- docs/ChromeOS-Devices.md | 6 +- docs/GamUpdates.md | 5 ++ docs/Groups-Membership.md | 2 +- docs/How-to-Upgrade-from-Standard-GAM.md | 4 +- docs/Version-and-Help.md | 12 ++-- src/GamCommands.txt | 4 +- src/GamUpdate.txt | 5 ++ src/gam/__init__.py | 84 ++++++++++++++---------- 8 files changed, 74 insertions(+), 48 deletions(-) diff --git a/docs/ChromeOS-Devices.md b/docs/ChromeOS-Devices.md index cb1c8381..f4d82d57 100644 --- a/docs/ChromeOS-Devices.md +++ b/docs/ChromeOS-Devices.md @@ -832,7 +832,7 @@ gam info crostelemetry ### Display data about all or selected devices. ``` gam show crostelemetry - [(ou|org|orgunit )|(cros_sn )|(filter )] + [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] * [fields ] [start ] [end ] [listlimit ] [reverselists ] @@ -841,6 +841,7 @@ gam show crostelemetry Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected. - `ou|org|orgunit ` - Select CrOS devices directly in the OU `` +- `ou_and_children ` - Select CrOS devices in the OU `` and its sub OUs - `cros_sn ` - Select the CrOS device with serial number ``. - `filter ` - Select the CrOS device with a filter. - `listlimit ` - Limits the number of repetitions to ``; if not specified or `` equals zero, there is no limit. @@ -857,7 +858,7 @@ By default, Gam displays the information as an indented list of keys and values: ### Print data about all or selected devices. ``` gam print crostelemetry [todrive *] - [(ou|org|orgunit )|(cros_sn )|(filter )] + [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] * [fields ] [reverselists ] [start ] [end ] [listlimit ] @@ -866,6 +867,7 @@ gam print crostelemetry [todrive *] Use these options to select CrOS devices; if none are chosen, all CrOS devices in the account are selected. - `ou|org|orgunit ` - Select CrOS devices directly in the OU `` +- `ou_and_children ` - Select CrOS devices in the OU `` and its sub OUs - `cros_sn ` - Select the CrOS device with serial number ``. - `filter ` - Select the CrOS device with a filter. - `listlimit ` - Limits the number of repetitions to ``; if not specified or `` equals zero, there is no limit. diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 931d8365..517182bb 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,11 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation. +### 6.63.11 + +Added option `ou_and_children ` to `gam print|show crostelemetry` to simplify getting +telemetry data for all ChromeOS devices in an OU and its children. + ### 6.63.10 Added option `addcsvdata ` to these commands. This adds additional columns of data to the CSV file output diff --git a/docs/Groups-Membership.md b/docs/Groups-Membership.md index 0841660e..57a087d3 100644 --- a/docs/Groups-Membership.md +++ b/docs/Groups-Membership.md @@ -108,7 +108,7 @@ users in a particular archived state. This option can be used with the following (query )| (queries ) ``` -Prior to bersion `6.20.05`, the `notarchived|archived` option could only be used with the following ``: +Prior to version `6.20.05`, the `notarchived|archived` option could only be used with the following ``: ``` (group|group_ns|group_susp )| (groups|groups_ns|groups_susp )| diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index d0f1f7f7..106b1b85 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -330,7 +330,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin/bin/gamadv-xtd3$ ./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.63.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.10.8 64-bit final MacOS High Sierra 10.13.6 x86_64 @@ -972,7 +972,7 @@ writes the credentials into the file oauth2.txt. C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt C:\GAMADV-XTD3>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAMADV-XTD3 6.63.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.5 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 68fe0438..cbe4d493 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -3,7 +3,7 @@ Print the current version of Gam with details ``` gam version -GAMADV-XTD3 6.63.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.5 64-bit final MacOS Monterey 12.6.6 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.63.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.5 64-bit final MacOS Monterey 12.6.6 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.63.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.5 64-bit final MacOS Monterey 12.6.6 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.63.10 + Latest: 6.63.11 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.63.10 +6.63.11 ``` 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.63.10 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.63.11 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.11.5 64-bit final MacOS Monterey 12.6.6 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 013bc672..518d0a31 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -2416,13 +2416,13 @@ gam info crostelemetry [reverselists ] [formatjson] gam show crostelemetry - [(ou|org|orgunit )|(cros_sn )|(filter )] + [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] * [fields ] [start ] [end ] [listlimit ] [reverselists ] [formatjson] gam print crostelemetry [todrive *] - [(ou|org|orgunit )|(cros_sn )|(filter )] + [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] * [fields ] [reverselists ] [start ] [end ] [listlimit ] diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 0d0daaba..144400fc 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -2,6 +2,11 @@ Merged GAM-Team version +6.63.11 + +Added option `ou_and_children ` to `gam print|show crostelemetry` to simplify getting +telemetry data for all ChromeOS devices in an OU and its children. + 6.63.10 Added option `addcsvdata ` to these commands. This adds additional columns of data to the CSV file output diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 985dff3b..f02ac5ea 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -23704,13 +23704,13 @@ CROS_TELEMETRY_TIME_OBJECTS = {'reportTime', 'lastUpdateTime', 'lastUpdateCheckT # [reverselists ] # [formatjson [quotechar ]] # gam show crostelemetry -# [(ou|org|orgunit )|(cros_sn )|(filter )] +# [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] # * [fields ] # [start ] [end ] [listlimit ] # [reverselists ] # [formatjson [quotechar ]] # gam print crostelemetry [todrive *] -# [(ou|org|orgunit )|(cros_sn )|(filter )] +# [(ou|org|orgunit|ou_and_children )|(cros_sn )|(filter )] # * [fields ] # [reverselists ] # [start ] [end ] [listlimit ] @@ -23778,10 +23778,11 @@ def doInfoPrintShowCrOSTelemetry(): reverseLists = [] action = Act.Get() if action == Act.INFO: - pfilter = f'serialNumber={getString(Cmd.OB_SERIAL_NUMBER)}' + sn = getString(Cmd.OB_SERIAL_NUMBER) + pfilters = [(f'serialNumber={sn}', f'serialNumber={sn}')] Act.Set(Act.SHOW) else: - pfilter = None + pfilters = [] csvPF = CSVPrintFile(['deviceId'], CROS_TELEMETRY_SCALAR_FIELDS, CROS_TELEMETRY_LIST_FIELDS) if Act.csvFormat() else None FJQC = FormatJSONQuoteChar(csvPF) diskPercentOnly = showOrgUnitPath = False @@ -23791,19 +23792,31 @@ def doInfoPrintShowCrOSTelemetry(): myarg = getArgument() if csvPF and myarg == 'todrive': csvPF.GetTodriveParameters() - elif myarg in ['ou', 'org', 'orgunit', 'limittoou', 'crossn', 'filter']: - if pfilter: + elif myarg in ['ou', 'org', 'orgunit', 'limittoou', 'ouandchildren', 'crossn', 'filter']: + if pfilters: Cmd.Backup() - usageErrorExit(Msg.ONLY_ONE_DEVICE_SELECTION_ALLOWED.format(pfilter)) + usageErrorExit(Msg.ONLY_ONE_DEVICE_SELECTION_ALLOWED.format(pfilters[0][1])) if myarg == 'crossn': - pfilter = f'serialNumber={getString(Cmd.OB_SERIAL_NUMBER)}' + sn = getString(Cmd.OB_SERIAL_NUMBER) + pfilters = [(f'serialNumber={sn}', f'serialNumber={sn}')] elif myarg == 'filter': - pfilter = getString(Cmd.OB_STRING) + pf = getString(Cmd.OB_STRING) + pfilters = [(pf, pf)] else: if cd is None: cd = buildGAPIObject(API.DIRECTORY) - _, orgUnitId = getOrgUnitId(cd) - pfilter = f'orgUnitId={orgUnitId[3:]}' + orgUnitPath, orgUnitId = getOrgUnitId(cd) + pfilters = [(f'orgUnitId={orgUnitId[3:]}', f'orgUnitPath={orgUnitPath}')] + if myarg == 'ouandchildren': + try: + subous = callGAPI(cd.orgunits(), 'list', + throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS, + customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath=orgUnitId, + type='all', fields='organizationUnits(orgUnitPath,orgUnitId)') + except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError, GAPI.badRequest, GAPI.invalidCustomerId, GAPI.loginRequired): + checkEntityDNEorAccessErrorExit(cd, Ent.ORGANIZATIONAL_UNIT, orgUnitId) + return + pfilters.extend([(f'orgUnitId={subou["orgUnitId"][3:]}', f'orgUnitPath={subou["orgUnitPath"]}') for subou in subous.get('organizationUnits', [])]) elif myarg == 'listlimit': listLimit = getInteger() elif myarg in CROS_START_ARGUMENTS: @@ -23841,30 +23854,31 @@ def doInfoPrintShowCrOSTelemetry(): readMask = ','.join(set(fieldsList)) if csvPF and FJQC.formatJSON: csvPF.SetJSONTitles(['deviceId', 'JSON']) - printGettingAllAccountEntities(Ent.CROS_DEVICE, pfilter) - pageMessage = getPageMessage() - try: - devices = callGAPIpages(cm.customers().telemetry().devices(), 'list', 'devices', - pageMessage=pageMessage, - throwReasons=[GAPI.PERMISSION_DENIED, GAPI.INVALID_ARGUMENT, GAPI.INVALID_INPUT], - parent=parent, filter=pfilter, - readMask=readMask, pageSize=GC.Values[GC.DEVICE_MAX_RESULTS]) - except (GAPI.invalidArgument, GAPI.invalidInput) as e: - message = str(e).replace('\n', ',') - entityActionFailedWarning([Ent.CROS_DEVICE, None], message) - return - except GAPI.permissionDenied as e: - accessErrorExitNonDirectory(API.CHROMEMANAGEMENT, str(e)) - if csvPF: - for device in devices: - _printDevice(device) - else: - jcount = len(devices) - performActionNumItems(jcount, Ent.CROS_DEVICE) - j = 0 - for device in devices: - j += 1 - _showDevice(device, j, jcount) + for pfilter in pfilters: + printGettingAllAccountEntities(Ent.CROS_DEVICE, pfilter[1]) + pageMessage = getPageMessage() + try: + devices = callGAPIpages(cm.customers().telemetry().devices(), 'list', 'devices', + pageMessage=pageMessage, + throwReasons=[GAPI.PERMISSION_DENIED, GAPI.INVALID_ARGUMENT, GAPI.INVALID_INPUT], + parent=parent, filter=pfilter[0], + readMask=readMask, pageSize=GC.Values[GC.DEVICE_MAX_RESULTS]) + except (GAPI.invalidArgument, GAPI.invalidInput) as e: + message = str(e).replace('\n', ',') + entityActionFailedWarning([Ent.CROS_DEVICE, None], message) + return + except GAPI.permissionDenied as e: + accessErrorExitNonDirectory(API.CHROMEMANAGEMENT, str(e)) + if csvPF: + for device in devices: + _printDevice(device) + else: + jcount = len(devices) + performActionNumItems(jcount, Ent.CROS_DEVICE) + j = 0 + for device in devices: + j += 1 + _showDevice(device, j, jcount) if csvPF: csvPF.writeCSVfile('CrOS Devices Telemetry')