Added preview to updateprimaryemail <RegularExpression> <EmailReplacement> [preview]

This commit is contained in:
Ross Scroggs
2026-04-03 11:34:29 -07:00
parent 28adb4b1ce
commit 9c44a11a6a
3 changed files with 40 additions and 21 deletions

View File

@@ -1,3 +1,14 @@
7.39.05
Added optional argument `preview` to `updateprimaryemail <RegularExpression> <EmailReplacement> [preview]`
for the following commands that causes GAM to preview, but not perform, primary email address changes.
This allows verification of the primary email address changes before commiting the changes.
```
gam update group <GroupEntity>
gam update cigroup <GroupEntity>
gam <UserTypeEntity> update user
```
7.39.04
Added `updateprimaryemail <RegularExpression> <EmailReplacement>` option to

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.39.04'
__version__ = '7.39.05'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position
@@ -34102,7 +34102,7 @@ UPDATE_GROUP_SUBCMDS = ['add', 'create', 'delete', 'remove', 'clear', 'sync', 'u
GROUP_PREVIEW_TITLES = ['group', 'email', 'role', 'action', 'message']
# gam update groups <GroupEntity> [email <EmailAddress>]
# [updateprimaryemail <RESEarchPattern> <RESubstitution>]
# [updateprimaryemail <RESEarchPattern> <RESubstitution> [preview]]
# [copyfrom <GroupItem>] <GroupAttribute>*
# [security|makesecuritygroup]
# [admincreated <Boolean>]
@@ -34532,13 +34532,14 @@ def doUpdateGroups():
gs_body = {}
ci_body = {}
verifyNotInvitable = False
updatePrimaryEmail = {}
updatePrimaryEmail = []
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'email':
body['email'] = getEmailAddress(noUid=True)
elif myarg == 'updateprimaryemail':
updatePrimaryEmail = getREPatternSubstitution(re.IGNORECASE)
updatePrimaryEmail = list(getREPatternSubstitution(re.IGNORECASE))
updatePrimaryEmail.append(checkArgumentPresent(['preview']))
elif myarg == 'admincreated':
body['adminCreated'] = getBoolean()
elif myarg == 'getbeforeupdate':
@@ -34579,9 +34580,10 @@ def doUpdateGroups():
if updatePrimaryEmail:
if updatePrimaryEmail[0].search(group) is not None:
body['email'] = re.sub(updatePrimaryEmail[0], updatePrimaryEmail[1], group)
if updatePrimaryEmail[2]:
entityActionNotPerformedWarning([Ent.GROUP, group], Msg.UPDATE_PRIMARY_EMAIL_PREVIEW.format(body['email']), i, count)
continue
else:
body.pop('email', None)
if not body:
entityActionNotPerformedWarning([Ent.GROUP, group], Msg.PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN.format(updatePrimaryEmail[0].pattern), i, count)
continue
if 'email' in body and verifyNotInvitable:
@@ -37050,7 +37052,7 @@ def doCreateCIGroup():
doCreateGroup(ciGroupsAPI=True)
# gam update cigroups <GroupEntity> [email <EmailAddress>]
# [updateprimaryemail <RESEarchPattern> <RESubstitution>]
# [updateprimaryemail <RESEarchPattern> <RESubstitution> [preview]]
# [copyfrom <GroupItem>] <GroupAttribute>*
# [security|makesecuritygroup|dynamicsecurity|makedynamicsecuritygroup]
# [dynamic <QueryDynamicGroup>]
@@ -37239,13 +37241,14 @@ def doUpdateCIGroups():
gs_body = {}
ci_body = {}
se_body = {}
updatePrimaryEmail = {}
updatePrimaryEmail = []
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'email':
ci_body['groupKey'] = {'id': getEmailAddress(noUid=True)}
elif myarg == 'updateprimaryemail':
updatePrimaryEmail = getREPatternSubstitution(re.IGNORECASE)
updatePrimaryEmail = list(getREPatternSubstitution(re.IGNORECASE))
updatePrimaryEmail.append(checkArgumentPresent(['preview']))
elif myarg == 'getbeforeupdate':
getBeforeUpdate = True
elif myarg == 'dynamic':
@@ -37301,9 +37304,10 @@ def doUpdateCIGroups():
if updatePrimaryEmail:
if updatePrimaryEmail[0].search(group) is not None:
ci_body['groupKey'] = {'id': re.sub(updatePrimaryEmail[0], updatePrimaryEmail[1], group)}
if updatePrimaryEmail[2]:
entityActionNotPerformedWarning([Ent.GROUP, group], Msg.UPDATE_PRIMARY_EMAIL_PREVIEW.format(ci_body['groupKey']['id']), i, count)
continue
else:
ci_body.pop('groupKey', None)
if not ci_body:
entityActionNotPerformedWarning([Ent.GROUP, group], Msg.PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN.format(updatePrimaryEmail[0].pattern), i, count)
continue
if gs_body and not GroupIsAbuseOrPostmaster(group):
@@ -45794,7 +45798,7 @@ def getUserAttributes(cd, updateCmd, noUid=False):
notFoundBody = {}
notify = {'recipients': [], 'subject': '', 'message': '', 'html': False, 'charset': UTF8, 'password': ''}
primary = {}
updatePrimaryEmail = {}
updatePrimaryEmail = []
groupOrgUnitMap = None
tagReplacements = _initTagReplacements()
addGroups = {}
@@ -45846,7 +45850,8 @@ def getUserAttributes(cd, updateCmd, noUid=False):
elif updateCmd and myarg == 'updateoufromgroup':
groupOrgUnitMap = _getGroupOrgUnitMap()
elif updateCmd and myarg == 'updateprimaryemail':
updatePrimaryEmail = getREPatternSubstitution(re.IGNORECASE)
updatePrimaryEmail = list(getREPatternSubstitution(re.IGNORECASE))
updatePrimaryEmail.append(checkArgumentPresent(['preview']))
elif myarg == 'json':
body.update(getJSON(USER_JSON_SKIP_FIELDS))
if 'name' in body and 'fullName' in body['name']:
@@ -46324,7 +46329,7 @@ def doCreateGuestUser():
# gam <UserTypeEntity> update user <UserAttribute>*
# [verifynotinvitable|alwaysevict] [noactionifalias]
# [updateprimaryemail <RESEarchPattern> <RESubstitution>]
# [updateprimaryemail <RESEarchPattern> <RESubstitution> [preview]]
# [updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]]
# [immutableous <OrgUnitEntity>]|
# [clearschema <SchemaName>|<SchemaNameField>]
@@ -46383,10 +46388,12 @@ def updateUsers(entityList):
elif updatePrimaryEmail:
if updatePrimaryEmail[0].search(user) is not None:
body['primaryEmail'] = re.sub(updatePrimaryEmail[0], updatePrimaryEmail[1], user)
if updatePrimaryEmail[2]:
entityActionNotPerformedWarning([Ent.USER, user], Msg.UPDATE_PRIMARY_EMAIL_PREVIEW.format(body['primaryEmail']), i, count)
continue
else:
body.pop('primaryEmail', None)
if not body:
entityActionNotPerformedWarning([Ent.USER, user], Msg.PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN.format(updatePrimaryEmail[0].pattern), i, count)
continue
if groupOrgUnitMap:
try:
groups = callGAPIpages(cd.groups(), 'list', 'groups',

View File

@@ -534,6 +534,7 @@ UNKNOWN_API_OR_VERSION = 'Unknown Google API or version: ({0}), contact {1}'
UNRECOVERABLE_ERROR = 'Unrecoverable error'
UPDATE_ATTENDEE_CHANGES = 'Update attendee changes'
UPDATE_GAM_TO_64BIT = "You're running a 32-bit version of GAM on a 64-bit version of Windows, upgrade to a windows-x86_64 version of GAM"
UPDATE_PRIMARY_EMAIL_PREVIEW = 'updateprimaryemail preview: {0}'
UPDATE_USER_PASSWORD_CHANGE_NOTIFY_MESSAGE = 'The account password for #givenname# #familyname#, #user# has been changed to: #password#\n'
UPDATE_USER_PASSWORD_CHANGE_NOTIFY_SUBJECT = 'Account #user# password has been changed'
UPLOAD_CSV_FILE_INTERNAL_ERROR = 'Google reported "{0}" but the file was probably uploaded, check that it has {1} rows'