mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-04 19:53:34 +00:00
Handle ERROR: 412: conditionNotMet - User creation is not complete.
This commit is contained in:
@ -10,6 +10,15 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
||||
|
||||
See [Downloads-Installs-GAM7](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||
|
||||
### 7.00.10
|
||||
|
||||
Handled the following error that occurs when `gam create user` is immediateley followed by `gam update user`.
|
||||
```
|
||||
ERROR: 412: conditionNotMet - User creation is not complete.
|
||||
```
|
||||
|
||||
Updated support for `Folders with limited access`; this is a work in progress.
|
||||
|
||||
### 7.00.09
|
||||
|
||||
Added initial support for `Folders with limited access`; you must be enrolled in the Beta preview.
|
||||
|
@ -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
|
||||
GAM 7.00.09 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.10 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.6 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
|
||||
GAM7 7.00.09 - https://github.com/taers232c/GAM7 - pythonsource
|
||||
GAM7 7.00.10 - https://github.com/taers232c/GAM7 - pythonsource
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.6 64-bit final
|
||||
Windows-10-10.0.17134 AMD64
|
||||
|
@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAM 7.00.09 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.10 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.5 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
|
||||
GAM 7.00.09 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.10 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.5 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
|
||||
GAM 7.00.09 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM 7.00.10 - https://github.com/GAM-team/GAM - pyinstaller
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.5 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: 7.00.09
|
||||
Latest: 7.00.10
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
7.00.09
|
||||
7.00.10
|
||||
```
|
||||
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 7.00.09 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 7.00.10 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM Team <google-apps-manager@googlegroups.com>
|
||||
Python 3.12.5 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
|
5045
src/drive-v3beta.json
Normal file
5045
src/drive-v3beta.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.00.09'
|
||||
__version__ = '7.00.10'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@ -4669,10 +4669,10 @@ def getAPIService(api, httpObj):
|
||||
discoveryServiceUrl=DISCOVERY_URIS[v2discovery], static_discovery=False)
|
||||
|
||||
def getService(api, httpObj):
|
||||
hasLocalJSON = API.hasLocalJSON(api)
|
||||
### Drive v3beta
|
||||
if api == API.DRIVE3 and GC.Values[GC.DRIVE_V3_BETA]:
|
||||
api = API.DRIVE3B
|
||||
hasLocalJSON = API.hasLocalJSON(api)
|
||||
api, version, v2discovery = API.getVersion(api)
|
||||
if api in GM.Globals[GM.CURRENT_API_SERVICES] and version in GM.Globals[GM.CURRENT_API_SERVICES][api]:
|
||||
service = googleapiclient.discovery.build_from_document(GM.Globals[GM.CURRENT_API_SERVICES][api][version], http=httpObj)
|
||||
@ -12445,7 +12445,7 @@ def doProcessSvcAcctKeys(mode=None, iam=None, projectId=None, clientEmail=None,
|
||||
def waitForCompletion(i):
|
||||
sleep_time = i*5
|
||||
if i > 3:
|
||||
sys.stdout.write(Msg.WAITING_FOR_SERVICE_ACCOUNT_CREATION_TO_COMPLETE_SLEEPING.format(sleep_time))
|
||||
sys.stdout.write(Msg.WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING.format(Ent.Singular(Ent.SVCACCT), sleep_time))
|
||||
time.sleep(sleep_time)
|
||||
|
||||
local_key_size = 2048
|
||||
@ -43152,8 +43152,14 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
|
||||
# [notifyonupdate [<Boolean>]]
|
||||
# [lograndompassword <FileName>] [ignorenullpassword]
|
||||
def updateUsers(entityList):
|
||||
def waitingForCreationToComplete(sleep_time):
|
||||
writeStderr(Ind.Spaces()+Msg.WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING.format(Ent.Singular(Ent.USER), sleep_time))
|
||||
time.sleep(sleep_time)
|
||||
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
ci = None
|
||||
errorRetries = 5
|
||||
updateRetryDelay = 5
|
||||
body, notify, tagReplacements, addGroups, addAliases, PwdOpts, \
|
||||
updatePrimaryEmail, notFoundBody, groupOrgUnitMap, \
|
||||
parameters, resolveConflictAccount = getUserAttributes(cd,
|
||||
@ -43228,51 +43234,63 @@ def updateUsers(entityList):
|
||||
continue
|
||||
if PwdOpts.makeUniqueRandomPassword:
|
||||
PwdOpts.AssignPassword(body, notify, notFoundBody, parameters['createIfNotFound'])
|
||||
try:
|
||||
result = callGAPI(cd.users(), 'update',
|
||||
throwReasons=[GAPI.USER_NOT_FOUND, GAPI.DOMAIN_NOT_FOUND, GAPI.FORBIDDEN, GAPI.BAD_REQUEST,
|
||||
GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.INVALID_PARAMETER,
|
||||
GAPI.INVALID_ORGUNIT, GAPI.INVALID_SCHEMA_VALUE, GAPI.DUPLICATE,
|
||||
GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES, GAPI.CONFLICT],
|
||||
userKey=userKey, body=body, fields=fields)
|
||||
entityActionPerformed([Ent.USER, user], i, count)
|
||||
if PwdOpts.filename and PwdOpts.password:
|
||||
writeFile(PwdOpts.filename, f'{userKey},{PwdOpts.password}\n', mode='a', continueOnError=True)
|
||||
if parameters['notifyOnUpdate'] and notify.get('recipients') and notify['password']:
|
||||
sendCreateUpdateUserNotification(result, notify, tagReplacements, i, count, createMessage=False)
|
||||
except GAPI.userNotFound:
|
||||
if parameters['createIfNotFound']:
|
||||
if notFoundBody and (count == 1) and not vfe and ('password' in notFoundBody) and ('name' in body) and ('givenName' in body['name']) and ('familyName' in body['name']):
|
||||
if 'primaryEmail' not in body:
|
||||
body['primaryEmail'] = user
|
||||
body.update(notFoundBody)
|
||||
if parameters['setChangePasswordOnCreate']:
|
||||
body['changePasswordAtNextLogin'] = True
|
||||
Act.Set(Act.CREATE)
|
||||
try:
|
||||
result = callGAPI(cd.users(), 'insert',
|
||||
throwReasons=[GAPI.DUPLICATE, GAPI.DOMAIN_NOT_FOUND, GAPI.FORBIDDEN,
|
||||
GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.INVALID_PARAMETER,
|
||||
GAPI.INVALID_ORGUNIT, GAPI.INVALID_SCHEMA_VALUE, GAPI.CONDITION_NOT_MET],
|
||||
body=body,
|
||||
fields=fields,
|
||||
resolveConflictAccount=resolveConflictAccount)
|
||||
entityActionPerformed([Ent.USER, body['primaryEmail']], i, count)
|
||||
if PwdOpts.filename and PwdOpts.notFoundPassword:
|
||||
writeFile(PwdOpts.filename, f'{user},{PwdOpts.notFoundPassword}\n', mode='a', continueOnError=True)
|
||||
if addGroups:
|
||||
createUserAddToGroups(cd, result['primaryEmail'], addGroups, i, count)
|
||||
if addAliases:
|
||||
createUserAddAliases(cd, result['primaryEmail'], addAliases, i, count)
|
||||
if notify.get('recipients'):
|
||||
notify['password'] = notify['notFoundPassword']
|
||||
sendCreateUpdateUserNotification(result, notify, tagReplacements, i, count)
|
||||
except GAPI.duplicate:
|
||||
duplicateAliasGroupUserWarning(cd, [Ent.USER, body['primaryEmail']], i, count)
|
||||
retry = 0
|
||||
while True:
|
||||
try:
|
||||
result = callGAPI(cd.users(), 'update',
|
||||
throwReasons=[GAPI.CONDITION_NOT_MET, GAPI.USER_NOT_FOUND, GAPI.DOMAIN_NOT_FOUND,
|
||||
GAPI.FORBIDDEN, GAPI.BAD_REQUEST,
|
||||
GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.INVALID_PARAMETER,
|
||||
GAPI.INVALID_ORGUNIT, GAPI.INVALID_SCHEMA_VALUE, GAPI.DUPLICATE,
|
||||
GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES, GAPI.CONFLICT],
|
||||
userKey=userKey, body=body, fields=fields)
|
||||
entityActionPerformed([Ent.USER, user], i, count)
|
||||
if PwdOpts.filename and PwdOpts.password:
|
||||
writeFile(PwdOpts.filename, f'{userKey},{PwdOpts.password}\n', mode='a', continueOnError=True)
|
||||
if parameters['notifyOnUpdate'] and notify.get('recipients') and notify['password']:
|
||||
sendCreateUpdateUserNotification(result, notify, tagReplacements, i, count, createMessage=False)
|
||||
break
|
||||
except GAPI.conditionNotMet as e:
|
||||
retry += 1
|
||||
if ('User creation is not complete' not in str(e)) or retry > errorRetries:
|
||||
entityActionFailedWarning([Ent.USER, user], str(e), i, count)
|
||||
break
|
||||
waitingForCreationToComplete(updateRetryDelay)
|
||||
continue
|
||||
except GAPI.userNotFound:
|
||||
if parameters['createIfNotFound']:
|
||||
if notFoundBody and (count == 1) and not vfe and ('password' in notFoundBody) and ('name' in body) and ('givenName' in body['name']) and ('familyName' in body['name']):
|
||||
if 'primaryEmail' not in body:
|
||||
body['primaryEmail'] = user
|
||||
body.update(notFoundBody)
|
||||
if parameters['setChangePasswordOnCreate']:
|
||||
body['changePasswordAtNextLogin'] = True
|
||||
Act.Set(Act.CREATE)
|
||||
try:
|
||||
result = callGAPI(cd.users(), 'insert',
|
||||
throwReasons=[GAPI.DUPLICATE, GAPI.DOMAIN_NOT_FOUND, GAPI.FORBIDDEN,
|
||||
GAPI.INVALID, GAPI.INVALID_INPUT, GAPI.INVALID_PARAMETER,
|
||||
GAPI.INVALID_ORGUNIT, GAPI.INVALID_SCHEMA_VALUE, GAPI.CONDITION_NOT_MET],
|
||||
body=body,
|
||||
fields=fields,
|
||||
resolveConflictAccount=resolveConflictAccount)
|
||||
entityActionPerformed([Ent.USER, body['primaryEmail']], i, count)
|
||||
if PwdOpts.filename and PwdOpts.notFoundPassword:
|
||||
writeFile(PwdOpts.filename, f'{user},{PwdOpts.notFoundPassword}\n', mode='a', continueOnError=True)
|
||||
if addGroups:
|
||||
createUserAddToGroups(cd, result['primaryEmail'], addGroups, i, count)
|
||||
if addAliases:
|
||||
createUserAddAliases(cd, result['primaryEmail'], addAliases, i, count)
|
||||
if notify.get('recipients'):
|
||||
notify['password'] = notify['notFoundPassword']
|
||||
sendCreateUpdateUserNotification(result, notify, tagReplacements, i, count)
|
||||
except GAPI.duplicate:
|
||||
duplicateAliasGroupUserWarning(cd, [Ent.USER, body['primaryEmail']], i, count)
|
||||
else:
|
||||
entityActionFailedWarning([Ent.USER, user], Msg.UNABLE_TO_CREATE_NOT_FOUND_USER, i, count)
|
||||
else:
|
||||
entityActionFailedWarning([Ent.USER, user], Msg.UNABLE_TO_CREATE_NOT_FOUND_USER, i, count)
|
||||
else:
|
||||
entityUnknownWarning(Ent.USER, user, i, count)
|
||||
entityUnknownWarning(Ent.USER, user, i, count)
|
||||
break
|
||||
else:
|
||||
entityActionNotPerformedWarning([Ent.USER, user], Msg.NO_CHANGES, i, count)
|
||||
except GAPI.userNotFound:
|
||||
@ -64236,7 +64254,7 @@ def _moveSharedDriveToOU(orgUnit, orgUnitId, driveId, user, i, count, ci, return
|
||||
# [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*) | returnidonly]
|
||||
def createSharedDrive(users, useDomainAdminAccess=False):
|
||||
def waitingForCreationToComplete(sleep_time):
|
||||
writeStderr(Ind.Spaces()+Msg.WAITING_FOR_SHARED_DRIVE_CREATION_TO_COMPLETE_SLEEPING.format(sleep_time))
|
||||
writeStderr(Ind.Spaces()+Msg.WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING.format(Ent.Singular(Ent.SHARED_DRIVE), sleep_time))
|
||||
time.sleep(sleep_time)
|
||||
|
||||
requestId = str(uuid.uuid4())
|
||||
|
5045
src/gam/drive-v3beta.json
Normal file
5045
src/gam/drive-v3beta.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -238,7 +238,7 @@ _INFO = {
|
||||
DOCS: {'name': 'Docs API', 'version': 'v1', 'v2discovery': True},
|
||||
DRIVE2: {'name': 'Drive API v2', 'version': 'v2', 'v2discovery': False, 'mappedAPI': 'drive'},
|
||||
DRIVE3: {'name': 'Drive API v3', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
|
||||
DRIVE3B: {'name': 'Drive API v3beta', 'version': 'v3beta', 'v2discovery': False, 'mappedAPI': 'drive'},
|
||||
DRIVE3B: {'name': 'Drive API v3beta', 'version': 'v3beta', 'v2discovery': False, 'mappedAPI': 'drive', 'localjson': True},
|
||||
DRIVETD: {'name': 'Drive API v3 - todrive', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'},
|
||||
DRIVEACTIVITY: {'name': 'Drive Activity API v2', 'version': 'v2', 'v2discovery': True},
|
||||
DRIVELABELS_ADMIN: {'name': 'Drive Labels API v2beta - Admin', 'version': 'v2beta', 'v2discovery': True, 'mappedAPI': DRIVELABELS},
|
||||
|
@ -510,8 +510,7 @@ USING_N_PROCESSES = '{0},0/{1},Using {2} {3}...\n'
|
||||
VALUES_ARE_NOT_CONSISTENT = 'Values are not consistent'
|
||||
VERSION_UPDATE_AVAILABLE = 'Version update available'
|
||||
WAITING_FOR_DATA_TRANSFER_TO_COMPLETE_SLEEPING = 'Waiting for Data Transfer to complete. Sleeping {0} seconds\n'
|
||||
WAITING_FOR_SERVICE_ACCOUNT_CREATION_TO_COMPLETE_SLEEPING = 'Waiting for Service Account creation to complete. Sleeping {0} seconds\n'
|
||||
WAITING_FOR_SHARED_DRIVE_CREATION_TO_COMPLETE_SLEEPING = 'Waiting for Shared Drive creation to complete. Sleeping {0} seconds\n'
|
||||
WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING = 'Waiting for {0} creation to complete. Sleeping {1} seconds\n'
|
||||
WHAT_IS_YOUR_PROJECT_ID = '\nWhat is your project ID? '
|
||||
WILL_RERUN_WITH_NO_BROWSER_TRUE = 'Will re-run command with no_browser true\n'
|
||||
WITH = 'with'
|
||||
|
Reference in New Issue
Block a user