diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 32383302..983867d8 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,21 @@ 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.01 + +Added `process_wait_limit` variable to `gam.cfg` that controls how long (in seconds) GAM should wait for all batch|csv processes to complete +after all have been started. If the limit is reached, GAM terminates any remaining processes. The default is 0 which specifies no limit. + +Following Jay's lead, added option `alwaysevict` to `gam create|update user` that is used to specify GAM's +behavior when `verifynotinvitable` is not specified and there is a conflict with an unmanaged account. + +By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting on this page: + * https://admin.google.com/ac/accountsettings/conflictaccountmanagement + +Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones` + +With `gam update user`, `alwaysevict` only applies if `createifnotfound` is specified and the user was not found to update and must be created. + ### 6.63.00 Added support for calendar working location events. diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index bc3be4e5..b6d1a5a0 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -174,6 +174,7 @@ Section: DEFAULT oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json people_max_results = 100 + process_wait_limit = 0 quick_cros_move = false quick_info_user = false reseller_id = '' @@ -329,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.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.10.8 64-bit final MacOS High Sierra 10.13.6 x86_64 @@ -595,6 +596,7 @@ Section: DEFAULT oauth2_txt = oauth2.txt ; /Users/admin/GAMConfig/oauth2.txt oauth2service_json = oauth2service.json ; /Users/admin/GAMConfig/oauth2service.json people_max_results = 100 + process_wait_limit = 0 quick_cros_move = false quick_info_user = False reseller_id = '' @@ -792,6 +794,7 @@ Section: DEFAULT oauth2_txt = oauth2.txt ; C:\GAMConfig\oauth2.txt oauth2service_json = oauth2service.json ; C:\GAMConfig\oauth2service.json people_max_results = 100 + process_wait_limit = 0 quick_cros_move = false quick_info_user = False reseller_id = '' @@ -969,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.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.4 64-bit final Windows-10-10.0.17134 AMD64 @@ -1237,6 +1240,7 @@ Section: DEFAULT output_dateformat = '' output_timeformat = '' people_max_results = 100 + process_wait_limit = 0 quick_cros_move = false quick_info_user = False reseller_id = '' diff --git a/docs/Users.md b/docs/Users.md index a2ae4892..3dd6b9e8 100644 --- a/docs/Users.md +++ b/docs/Users.md @@ -475,7 +475,7 @@ clearschema . ## Create a user ``` gam create user [ignorenullpassword] * - [verifynotinvitable] + [verifynotinvitable|alwaysevict] (groups [] [[delivery] ] )* [alias|aliases ] [license [product|productid ]] @@ -489,9 +489,15 @@ gam create user [ignorenullpassword] * [lograndompassword ] [addnumericsuffixonduplicate ] ``` -When `verifynotinvitable` is specified, GAM verifies that the email address being updated is not that of an unmanaged account; +When `verifynotinvitable` is specified, GAM verifies that the email address being created is not that of an unmanaged account; if it is, the command is not performed. +By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting as described on these pages. + * https://support.google.com/a/answer/11112794 + * https://admin.google.com/ac/accountsettings/conflictaccountmanagement + +Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones` + The user will be added to the groups specified by `groups [] [[delivery] ] `. The user aliases in `alias|aliases ` will be created. @@ -575,7 +581,7 @@ If the mailbox is setup, a zero return code is returned; if the retries are exha ## Update a user ``` gam update user [ignorenullpassword] * - [verifynotinvitable] [noactionifalias] + [verifynotinvitable|alwaysevict] [noactionifalias] [updateprimaryemail ] [updateoufromgroup [charset ] [columndelimiter ] [quotechar ] @@ -595,7 +601,7 @@ gam update user [ignorenullpassword] * (replace )* [lograndompassword ] gam update users [ignorenullpassword] * - [verifynotinvitable] [noactionifalias] + [verifynotinvitable|alwaysevict] [noactionifalias] [updateprimaryemail ] [updateoufromgroup [charset ] [columndelimiter ] [quotechar ] @@ -615,7 +621,7 @@ gam update users [ignorenullpassword] * (replace )* [lograndompassword ] gam update users [ignorenullpassword] * - [verifynotinvitable] [noactionifalias] + [verifynotinvitable|alwaysevict] [noactionifalias] [updateprimaryemail ] [updateoufromgroup [charset ] [columndelimiter ] [quotechar ] @@ -639,6 +645,14 @@ gam update users [ignorenullpassword] * When `verifynotinvitable` is specified, GAM verifies that the email address being updated is not that of an unmanaged account; if it is, the command is not performed. +If `createifnotfound` is specified and the user was not found to update and must be created, the following applies. + +By default, when creating a user that has a conflict with an unmanaged account, GAM will honor the setting as described on these pages. + * https://support.google.com/a/answer/11112794 + * https://admin.google.com/ac/accountsettings/conflictaccountmanagement + +Specifying `alwaysevict` forces GAM to select this setting: `Replace conflicting unmanaged accounts with managed ones` + When `noactionifalias` is specified, no action is performed if `` or `` specifies an alias rather than a primary email address. **Note that when `changepassword true` is specified, the user is immediately logged out.** diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 036f915d..9650fdb7 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.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.4 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.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.4 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.00 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.11.4 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.00 + Latest: 6.63.01 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.63.00 +6.63.01 ``` 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.00 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.63.01 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.11.4 64-bit final MacOS Monterey 12.6.6 x86_64 diff --git a/docs/gam.cfg.md b/docs/gam.cfg.md index 46030985..c45c2757 100644 --- a/docs/gam.cfg.md +++ b/docs/gam.cfg.md @@ -401,6 +401,11 @@ people_max_results how many should be retrieved in each API call Default: 100 Range: 1 - 1000 +process_wait_limit + When processing batch/CSV files, how long (in seconds) GAM should wait for all batch|csv processes to complete + after all have been started. If the limit is reached, GAM terminates any remaining processes. + Default: 0: no limit + Range: 0 - Unlimited quick_cros_move Default value for "quickcrosmove []" in commands that update Chromebook OUs. Default: False @@ -628,6 +633,7 @@ Section: DEFAULT output_dateformat = '' output_timeformat = '' people_max_results = 100 + process_wait_limit = 0 quick_cros_move = false quick_info_user = false reseller_id = '' @@ -808,6 +814,7 @@ oauth2service_json = oauth2service.json output_dateformat = '' output_timeformat = '' people_max_results = 100 +process_wait_limit = 0 quick_cros_move = False quick_info_user = False reseller_id = '' diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 4ed6a7bd..edce8785 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -4,6 +4,9 @@ Merged GAM-Team version 6.63.01 +Added `process_wait_limit` variable to `gam.cfg` that controls how long (in seconds) GAM should wait for all batch|csv processes to complete +after all have been started. If the limit is reached, GAM terminates any remaining processes. The default is 0 which specifies no limit. + Following Jay's lead, added option `alwaysevict` to `gam create|update user` that is used to specify GAM's behavior when `verifynotinvitable` is not specified and there is a conflict with an unmanaged account. diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 84eca509..155fcf47 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -9457,7 +9457,8 @@ def MultiprocessGAMCommands(items, showCmds): if item[0] == Cmd.COMMIT_BATCH_CMD: batchWriteStderr(Msg.COMMIT_BATCH_WAIT_N_PROCESSES.format(currentISOformatTimeStamp(), numItems, poolProcessResults[0], - PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1])) + PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1] + '')) while poolProcessResults[0] > 0: time.sleep(1) completedProcesses = [] @@ -9512,10 +9513,16 @@ def MultiprocessGAMCommands(items, showCmds): del poolProcessResults[p] break time.sleep(1) + processWaitStart = time.time() + if GC.Values[GC.PROCESS_WAIT_LIMIT] > 0: + waitRemaining = GC.Values[GC.PROCESS_WAIT_LIMIT] + else: + waitRemaining = 'unlimited' while poolProcessResults[0] > 0: batchWriteStderr(Msg.BATCH_CSV_WAIT_N_PROCESSES.format(currentISOformatTimeStamp(), numItems, poolProcessResults[0], - PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1])) + PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1], + Msg.BATCH_CSV_WAIT_LIMIT.format(waitRemaining))) completedProcesses = [] for p, result in iter(poolProcessResults.items()): if p != 0 and result.ready(): @@ -9525,8 +9532,20 @@ def MultiprocessGAMCommands(items, showCmds): del poolProcessResults[p] if poolProcessResults[0] > 0: time.sleep(5) + if GC.Values[GC.PROCESS_WAIT_LIMIT] > 0: + delta = int(time.time()-processWaitStart) + if delta >= GC.Values[GC.PROCESS_WAIT_LIMIT]: + batchWriteStderr(Msg.BATCH_CSV_TERMINATE_N_PROCESSES.format(currentISOformatTimeStamp(), + numItems, poolProcessResults[0], + PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1])) + pool.terminate() + break + waitRemaining = GC.Values[GC.PROCESS_WAIT_LIMIT] - delta except KeyboardInterrupt: setSysExitRC(KEYBOARD_INTERRUPT_RC) + batchWriteStderr(Msg.BATCH_CSV_TERMINATE_N_PROCESSES.format(currentISOformatTimeStamp(), + numItems, poolProcessResults[0], + PROCESS_PLURAL_SINGULAR[poolProcessResults[0] == 1])) pool.terminate() else: pool.close() diff --git a/src/gam/gamlib/glcfg.py b/src/gam/gamlib/glcfg.py index 6dc09b7e..c28553bb 100644 --- a/src/gam/gamlib/glcfg.py +++ b/src/gam/gamlib/glcfg.py @@ -198,6 +198,8 @@ OUTPUT_DATEFORMAT = 'output_dateformat' OUTPUT_TIMEFORMAT = 'output_timeformat' # When retrieving lists of people from API, how many should be retrieved in each chunk PEOPLE_MAX_RESULTS = 'people_max_results' +# Number of seconds to wait for batch/csv processes to complete +PROCESS_WAIT_LIMIT = 'process_wait_limit' # Use quick method to move Chromebooks to OU QUICK_CROS_MOVE = 'quick_cros_move' # Quick info user: nogroups nolicenses noschemas @@ -361,6 +363,7 @@ Defaults = { OUTPUT_DATEFORMAT: '', OUTPUT_TIMEFORMAT: '', PEOPLE_MAX_RESULTS: '100', + PROCESS_WAIT_LIMIT: '0', QUICK_CROS_MOVE: FALSE, QUICK_INFO_USER: FALSE, RESELLER_ID: '', @@ -508,6 +511,7 @@ VAR_INFO = { OUTPUT_DATEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, OUTPUT_TIMEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, PEOPLE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, 1000)}, + PROCESS_WAIT_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, None)}, QUICK_CROS_MOVE: {VAR_TYPE: TYPE_BOOLEAN}, QUICK_INFO_USER: {VAR_TYPE: TYPE_BOOLEAN}, RESELLER_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, diff --git a/src/gam/gamlib/glmsgs.py b/src/gam/gamlib/glmsgs.py index 6e7a29ef..47c92f98 100644 --- a/src/gam/gamlib/glmsgs.py +++ b/src/gam/gamlib/glmsgs.py @@ -162,8 +162,10 @@ BAD_ENTITIES_IN_SOURCE = '{0} {1} {2} in source marked >>> <<< above' BAD_REQUEST = 'Bad Request' BATCH = 'Batch' BATCH_CSV_LOOP_DASH_DEBUG_INCOMPATIBLE = '"gam {0} - ..." is not compatible with debugging. Disable debugging by setting debug_level = 0 in gam.cfg' -BATCH_CSV_WAIT_N_PROCESSES = '{0},0/{1},Waiting for {2} running {3} to finish before terminating\n' BATCH_CSV_PROCESSING_COMPLETE = '{0},0/{1},Processing complete\n' +BATCH_CSV_TERMINATE_N_PROCESSES = '{0},0/{1},Terminating {2} running {3}\n' +BATCH_CSV_WAIT_LIMIT = ', wait limit {0} seconds' +BATCH_CSV_WAIT_N_PROCESSES = '{0},0/{1},Waiting for {2} running {3} to finish before terminating{4}\n' BATCH_NOT_PROCESSED_ERRORS = '{0}batch file: {1}, not processed, {2} {3}\n' CALLING_GCLOUD_FOR_REAUTH = 'Calling gcloud for reauth credentials..."\n' CAN_NOT_DELETE_USER_WITH_VAULT_HOLD = '{0}: The user may be (or have recently been) on Google Vault Hold and thus not eligible for deletion. You can check holds with "gam user {1} show vaultholds".'