mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-29 18:31:38 +00:00
Compare commits
2 Commits
v7.02.02
...
20241223.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0d5ac74da | ||
|
|
a9e28e966a |
@@ -7821,7 +7821,8 @@ gam <UserTypeEntity> delete noteacl <NotesNameEntity>
|
|||||||
# Users - Licenses
|
# Users - Licenses
|
||||||
|
|
||||||
gam <UserTypeEntity> create|add license <SKUIDList> [product|productid <ProductID>] [preview] [actioncsv]
|
gam <UserTypeEntity> create|add license <SKUIDList> [product|productid <ProductID>] [preview] [actioncsv]
|
||||||
gam <UserTypeEntity> update license <SKUID> [product|productid <ProductID>] [from] <SKUID> [preview] [actioncsv]
|
gam <UserTypeEntity> update license <NewSKUID> [product|productid <ProductID>] [from] <OldSKUID>
|
||||||
|
[preview|archive] [actioncsv]
|
||||||
gam <UserTypeEntity> delete license <SKUIDList> [product|productid <ProductID>] [preview] [actioncsv]
|
gam <UserTypeEntity> delete license <SKUIDList> [product|productid <ProductID>] [preview] [actioncsv]
|
||||||
gam <UserTypeEntity> sync license <SKUIDList> [product|productid <ProductID>] [addonly|removeonly] [allskus|onesku] [preview] [actioncsv]
|
gam <UserTypeEntity> sync license <SKUIDList> [product|productid <ProductID>] [addonly|removeonly] [allskus|onesku] [preview] [actioncsv]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
7.02.03
|
||||||
|
|
||||||
|
Added option `archive` to `gam <UserTypeEntity> update license <NewSKUID> from <OldSKUID>` that causes GAM
|
||||||
|
to archive `<UserTypeEntity>` after updating their license to `<NewSKUID>`. This will be used when you want to
|
||||||
|
archive a user with a non-archivable license. The `<NewSKUID>` license is assigned to the user and it then converts
|
||||||
|
to the equivalent Archived User license when the user is archived.
|
||||||
|
|
||||||
|
`<NewSKUID>` must be one of the following SKUs:
|
||||||
|
```
|
||||||
|
Google-Apps-Unlimited - G Suite Business
|
||||||
|
1010020020 - Google Workspace Enterprise Plus
|
||||||
|
1010020025 - Google Workspace Business Plus
|
||||||
|
1010020026 - Google Workspace Enterprise Standard
|
||||||
|
1010020027 - Google Workspace Business Starter
|
||||||
|
1010020028 - Google Workspace Business Standard
|
||||||
|
```
|
||||||
|
|
||||||
7.02.02
|
7.02.02
|
||||||
|
|
||||||
Updated `gam <UserTypeEntity> archive messages <GroupItem>` to retry the following unexpected error
|
Updated `gam <UserTypeEntity> archive messages <GroupItem>` to retry the following unexpected error
|
||||||
|
|||||||
@@ -323,6 +323,8 @@ echo_yellow "Downloading ${download_url} to $temp_archive_dir ($check_type)..."
|
|||||||
(cd "$temp_archive_dir" && curl -O -L -s "${curl_opts[@]}" "$download_url")
|
(cd "$temp_archive_dir" && curl -O -L -s "${curl_opts[@]}" "$download_url")
|
||||||
|
|
||||||
mkdir -p "$target_dir"
|
mkdir -p "$target_dir"
|
||||||
|
echo_yellow "Deleting contents of $target_dir/gam7/lib"
|
||||||
|
rm -frv "$target_dir/gam7/lib"
|
||||||
|
|
||||||
echo_yellow "Extracting archive to $target_dir"
|
echo_yellow "Extracting archive to $target_dir"
|
||||||
if [[ "$name" =~ tar.xz|tar.gz|tar ]]; then
|
if [[ "$name" =~ tar.xz|tar.gz|tar ]]; then
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.02.02'
|
__version__ = '7.02.03'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
#pylint: disable=wrong-import-position
|
#pylint: disable=wrong-import-position
|
||||||
@@ -67173,7 +67173,7 @@ LICENSE_PREVIEW_TITLES = ['user', 'productId', 'skuId', 'action', 'message']
|
|||||||
|
|
||||||
def getLicenseParameters(operation):
|
def getLicenseParameters(operation):
|
||||||
lic = buildGAPIObject(API.LICENSING)
|
lic = buildGAPIObject(API.LICENSING)
|
||||||
parameters = {LICENSE_PRODUCT_SKUIDS: [], 'csvPF': None, 'preview': False, 'syncOperation': 'addremove', 'syncACLsMode': None}
|
parameters = {LICENSE_PRODUCT_SKUIDS: [], 'csvPF': None, 'preview': False, 'syncOperation': 'addremove', 'syncACLsMode': None, 'archive': False}
|
||||||
skuLocation = Cmd.Location()
|
skuLocation = Cmd.Location()
|
||||||
if operation != 'patch':
|
if operation != 'patch':
|
||||||
parameters[LICENSE_PRODUCT_SKUIDS] = getGoogleSKUList(allowUnknownProduct=True)
|
parameters[LICENSE_PRODUCT_SKUIDS] = getGoogleSKUList(allowUnknownProduct=True)
|
||||||
@@ -67203,6 +67203,10 @@ def getLicenseParameters(operation):
|
|||||||
if operation == 'patch':
|
if operation == 'patch':
|
||||||
titles.insert(2, 'oldskuId')
|
titles.insert(2, 'oldskuId')
|
||||||
parameters['csvPF'] = CSVPrintFile(titles)
|
parameters['csvPF'] = CSVPrintFile(titles)
|
||||||
|
elif operation == 'patch' and myarg == 'archive':
|
||||||
|
if skuId not in SKU.ARCHIVABLE_SKUS:
|
||||||
|
usageErrorExit(Msg.SKU_HAS_NO_MATCHING_ARCHIVED_USER_SKU.format(skuId))
|
||||||
|
parameters['archive'] = True
|
||||||
else:
|
else:
|
||||||
unknownArgumentExit()
|
unknownArgumentExit()
|
||||||
for productSku in parameters[LICENSE_PRODUCT_SKUIDS]:
|
for productSku in parameters[LICENSE_PRODUCT_SKUIDS]:
|
||||||
@@ -67308,13 +67312,17 @@ def createLicense(users):
|
|||||||
if parameters['csvPF']:
|
if parameters['csvPF']:
|
||||||
parameters['csvPF'].writeCSVfile('Create Licenses')
|
parameters['csvPF'].writeCSVfile('Create Licenses')
|
||||||
|
|
||||||
# gam <UserTypeEntity> update license <SKUID> [product|productid <ProductID>] [from] <SKUID> [preview] [actioncsv]
|
# gam <UserTypeEntity> update license <SKUID> [product|productid <ProductID>] [from] <SKUID>
|
||||||
|
# [preview] [actioncsv] [archive]
|
||||||
def updateLicense(users):
|
def updateLicense(users):
|
||||||
lic, parameters = getLicenseParameters('patch')
|
lic, parameters = getLicenseParameters('patch')
|
||||||
j, jcount, users = getEntityArgument(users)
|
j, jcount, users = getEntityArgument(users)
|
||||||
Act.Set([Act.UPDATE, Act.UPDATE_PREVIEW][parameters['preview']])
|
Act.Set([Act.UPDATE, Act.UPDATE_PREVIEW][parameters['preview']])
|
||||||
|
cd = None
|
||||||
if parameters['preview']:
|
if parameters['preview']:
|
||||||
message = Act.PREVIEW
|
message = Act.PREVIEW
|
||||||
|
elif parameters['archive']:
|
||||||
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
productId, skuId, oldSkuId = parameters[LICENSE_PRODUCT_SKUIDS][0]
|
productId, skuId, oldSkuId = parameters[LICENSE_PRODUCT_SKUIDS][0]
|
||||||
body = {'skuId': skuId}
|
body = {'skuId': skuId}
|
||||||
entityPerformActionModifierNumItems([Ent.LICENSE, SKU.skuIdToDisplayName(skuId)], Msg.FOR, jcount, Ent.USER)
|
entityPerformActionModifierNumItems([Ent.LICENSE, SKU.skuIdToDisplayName(skuId)], Msg.FOR, jcount, Ent.USER)
|
||||||
@@ -67340,6 +67348,22 @@ def updateLicense(users):
|
|||||||
except GAPI.userNotFound as e:
|
except GAPI.userNotFound as e:
|
||||||
message = str(e)
|
message = str(e)
|
||||||
entityUnknownWarning(Ent.USER, user, j, jcount)
|
entityUnknownWarning(Ent.USER, user, j, jcount)
|
||||||
|
if parameters['archive'] and message == Act.SUCCESS:
|
||||||
|
Act.Set(Act.ARCHIVE)
|
||||||
|
try:
|
||||||
|
callGAPI(cd.users(), 'update',
|
||||||
|
throwReasons=[GAPI.USER_NOT_FOUND, GAPI.DOMAIN_NOT_FOUND,
|
||||||
|
GAPI.FORBIDDEN, GAPI.BAD_REQUEST,
|
||||||
|
GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES],
|
||||||
|
retryReasons=[GAPI.INSUFFICIENT_ARCHIVED_USER_LICENSES],
|
||||||
|
userKey=user, body={'archived': True})
|
||||||
|
entityActionPerformed([Ent.USER, user], j, jcount)
|
||||||
|
except GAPI.userNotFound:
|
||||||
|
entityUnknownWarning(Ent.USER, user, j, jcount)
|
||||||
|
except (GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden, GAPI.badRequest,
|
||||||
|
GAPI.insufficientArchivedUserLicenses) as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user], str(e), j, jcount)
|
||||||
|
Act.Set(Act.UPDATE)
|
||||||
if parameters['csvPF']:
|
if parameters['csvPF']:
|
||||||
_writeLicenseAction(productId, skuId, oldSkuId, parameters, user, Act.UPDATE, message)
|
_writeLicenseAction(productId, skuId, oldSkuId, parameters, user, Act.UPDATE, message)
|
||||||
Ind.Decrement()
|
Ind.Decrement()
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ SERVICE_NOT_APPLICABLE = 'Service not applicable/Does not exist'
|
|||||||
SERVICE_NOT_APPLICABLE_THIS_ADDRESS = 'Service not applicable for this address: {0}'
|
SERVICE_NOT_APPLICABLE_THIS_ADDRESS = 'Service not applicable for this address: {0}'
|
||||||
SERVICE_NOT_ENABLED = '{0} Service/App not enabled'
|
SERVICE_NOT_ENABLED = '{0} Service/App not enabled'
|
||||||
SHORTCUT_TARGET_CAPABILITY_IS_FALSE = '{0} capability {1} is False'
|
SHORTCUT_TARGET_CAPABILITY_IS_FALSE = '{0} capability {1} is False'
|
||||||
|
SKU_HAS_NO_MATCHING_ARCHIVED_USER_SKU = 'SKU {0} has no matching Archived User SKU'
|
||||||
STARTING_THREAD = 'Starting thread'
|
STARTING_THREAD = 'Starting thread'
|
||||||
STATISTICS_COPY_FILE = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Copy Failed: {5}, Not copyable: {6}, In skipids: {7}, Permissions Failed: {8}, Protected Ranges Failed: {9}'
|
STATISTICS_COPY_FILE = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Copy Failed: {5}, Not copyable: {6}, In skipids: {7}, Permissions Failed: {8}, Protected Ranges Failed: {9}'
|
||||||
STATISTICS_COPY_FOLDER = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Merged: {5}, Copy Failed: {6}, Not writable: {7}, Permissions Failed: {8}'
|
STATISTICS_COPY_FOLDER = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Merged: {5}, Copy Failed: {6}, Not writable: {7}, Permissions Failed: {8}'
|
||||||
|
|||||||
@@ -182,6 +182,8 @@ _SKUS = {
|
|||||||
'product': 'Google-Chrome-Device-Management', 'aliases': ['chrome', 'cdm', 'googlechromedevicemanagement'], 'displayName': 'Google Chrome Device Management'}
|
'product': 'Google-Chrome-Device-Management', 'aliases': ['chrome', 'cdm', 'googlechromedevicemanagement'], 'displayName': 'Google Chrome Device Management'}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ARCHIVABLE_SKUS = {'1010020020', '1010020025', '1010020026', '1010020027', '1010020028', 'Google-Apps-Unlimited'}
|
||||||
|
|
||||||
def getProductAndSKU(sku):
|
def getProductAndSKU(sku):
|
||||||
l_sku = sku.lower().replace('-', '').replace(' ', '').replace('"', '').replace("'", '').strip()
|
l_sku = sku.lower().replace('-', '').replace(' ', '').replace('"', '').replace("'", '').strip()
|
||||||
if l_sku.startswith('nv:'):
|
if l_sku.startswith('nv:'):
|
||||||
|
|||||||
Reference in New Issue
Block a user