mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-28 09:51:36 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d7817664b | ||
|
|
9aea95e8db | ||
|
|
8b6781a49b | ||
|
|
ff59855a2c | ||
|
|
37d00ff0d8 | ||
|
|
669dffcd39 | ||
|
|
e3ad108c91 | ||
|
|
d7d98d41cd | ||
|
|
213b0f2ba2 | ||
|
|
d745aa65f5 | ||
|
|
c122a55ad7 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -165,7 +165,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
cache.tar.xz
|
cache.tar.xz
|
||||||
key: gam-${{ matrix.jid }}-20260609
|
key: gam-${{ matrix.jid }}-20260611
|
||||||
|
|
||||||
- name: Untar Cache archive
|
- name: Untar Cache archive
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ dependencies = [
|
|||||||
"chardet==7.4.3",
|
"chardet==7.4.3",
|
||||||
"cryptography==48.0.0",
|
"cryptography==48.0.0",
|
||||||
"distro==1.9.0 ; sys_platform=='linux'",
|
"distro==1.9.0 ; sys_platform=='linux'",
|
||||||
"filelock==3.29.0",
|
"filelock==3.29.1",
|
||||||
"google-api-python-client==2.196.0",
|
"google-api-python-client==2.197.0",
|
||||||
"google-auth-httplib2==0.4.0",
|
"google-auth-httplib2==0.4.0",
|
||||||
"google-auth-oauthlib==1.4.0",
|
"google-auth-oauthlib==1.4.0",
|
||||||
"google-auth==2.53.0",
|
"google-auth==2.53.0",
|
||||||
|
|||||||
@@ -4378,6 +4378,14 @@ gam show policies
|
|||||||
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
|
gam create policy
|
||||||
|
json <JSONData>
|
||||||
|
[(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
|
gam update policy
|
||||||
|
json <JSONData>
|
||||||
|
[(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
|
gam delete policies <CIPolicyNameEntity>
|
||||||
|
|
||||||
# Inbound SSO
|
# Inbound SSO
|
||||||
|
|
||||||
<SSOProfileDisplayName> ::= <String>
|
<SSOProfileDisplayName> ::= <String>
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
7.46.02
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> show calsettings` to display `dataOwner` field;
|
||||||
|
it is labelled `Owner`.
|
||||||
|
|
||||||
|
7.46.01
|
||||||
|
|
||||||
|
Fixed bug in `gam <CrOSTypeEntity> issuecommand command <CrOSCommand> ... csv` where
|
||||||
|
command execution status lines were improperly indented.
|
||||||
|
|
||||||
|
Upgraded to Python 3.14.6.
|
||||||
|
|
||||||
|
7.46.00
|
||||||
|
|
||||||
|
Added commands to create, update and delete Cloud Identity policies for data loss prevention (DLP) rules and detectors.
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Cloud-Identity-Policies
|
||||||
|
* See: https://workspaceupdates.googleblog.com/2026/06/introducing-workspace-policy-api-mutate-endpoints-for-DLP.html
|
||||||
|
|
||||||
7.45.00
|
7.45.00
|
||||||
|
|
||||||
Added options `isdisabled [<Boolean>]`, `disabledafter <DateTime>` and `disabledbefore <DateTime>`
|
Added options `isdisabled [<Boolean>]`, `disabledafter <DateTime>` and `disabledbefore <DateTime>`
|
||||||
|
|||||||
@@ -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.45.00'
|
__version__ = '7.46.02'
|
||||||
__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
|
||||||
@@ -24392,7 +24392,7 @@ def displayCrOSCommandResult(cd, deviceId, commandId, checkResultRetries, i, cou
|
|||||||
if addCSVData:
|
if addCSVData:
|
||||||
result.update(addCSVData)
|
result.update(addCSVData)
|
||||||
csvPF.WriteRowTitles(flattenJSON(result, timeObjects=CROS_COMMAND_TIME_OBJECTS))
|
csvPF.WriteRowTitles(flattenJSON(result, timeObjects=CROS_COMMAND_TIME_OBJECTS))
|
||||||
return
|
break
|
||||||
showJSON(None, result, timeObjects=CROS_COMMAND_TIME_OBJECTS)
|
showJSON(None, result, timeObjects=CROS_COMMAND_TIME_OBJECTS)
|
||||||
state = result.get('state')
|
state = result.get('state')
|
||||||
if state in CROS_COMMAND_FINAL_STATES:
|
if state in CROS_COMMAND_FINAL_STATES:
|
||||||
@@ -38526,37 +38526,25 @@ def _checkPoliciesWithDASA():
|
|||||||
systemErrorExit(USAGE_ERROR_RC,
|
systemErrorExit(USAGE_ERROR_RC,
|
||||||
Msg.COMMAND_NOT_COMPATIBLE_WITH_ENABLE_DASA.format(Act.ToPerform().lower(), Cmd.ARG_CIPOLICIES))
|
Msg.COMMAND_NOT_COMPATIBLE_WITH_ENABLE_DASA.format(Act.ToPerform().lower(), Cmd.ARG_CIPOLICIES))
|
||||||
|
|
||||||
def _getCIPolicyOrgUnitTarget(cd, myarg, groupEmail):
|
|
||||||
if groupEmail:
|
|
||||||
Cmd.Backup()
|
|
||||||
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'group'))
|
|
||||||
targetName, targetResource = _getOrgunitsOrgUnitIdPath(cd, getString(Cmd.OB_ORGUNIT_PATH))
|
|
||||||
return (targetName, targetResource)
|
|
||||||
|
|
||||||
def _getCIPolicyGroupTarget(cd, myarg, orgUnit):
|
|
||||||
if orgUnit:
|
|
||||||
Cmd.Backup()
|
|
||||||
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'ou|org|orgunit'))
|
|
||||||
targetName = getEmailAddress(returnUIDprefix='uid:')
|
|
||||||
targetResource = f"groups/{convertEmailAddressToUID(targetName, cd, emailType='group')}"
|
|
||||||
return (targetName, targetResource)
|
|
||||||
|
|
||||||
# gam create policy
|
# gam create policy
|
||||||
# json <JSONData>
|
# json <JSONData>
|
||||||
# [(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)]
|
# [(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
# gam update policy
|
# gam update policy
|
||||||
# json <JSONData>
|
# json <JSONData>
|
||||||
# [(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)]
|
# [(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
def doCreateUpdateCIPolicy():
|
def doCreateUpdateCIPolicy():
|
||||||
_checkPoliciesWithDASA()
|
_checkPoliciesWithDASA()
|
||||||
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY_BETA)
|
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
cd = buildGAPIObject(API.DIRECTORY)
|
||||||
updateCmd = Act.Get() == Act.UPDATE
|
updateCmd = Act.Get() == Act.UPDATE
|
||||||
groupEmail = orgUnit = None
|
groupEmail = orgUnit = query = None
|
||||||
checkArgumentPresent('json', True)
|
checkArgumentPresent('json', True)
|
||||||
policy = getJSON(['customer', 'type'])
|
policy = getJSON(['customer', 'type'])
|
||||||
if updateCmd:
|
if updateCmd:
|
||||||
pname = policy.pop('name', None)
|
pname = policy.pop('name', None)
|
||||||
|
if not pname:
|
||||||
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.POLICY_NAME_NOT_FOUND)
|
||||||
else:
|
else:
|
||||||
policy.pop('name', None)
|
policy.pop('name', None)
|
||||||
pname = 'New Policy'
|
pname = 'New Policy'
|
||||||
@@ -38564,6 +38552,8 @@ def doCreateUpdateCIPolicy():
|
|||||||
policy['policyQuery'].pop('orgUnitPath', None)
|
policy['policyQuery'].pop('orgUnitPath', None)
|
||||||
policy['policyQuery'].pop('groupEmail', None)
|
policy['policyQuery'].pop('groupEmail', None)
|
||||||
policy['policyQuery'].pop('sortOrder', None)
|
policy['policyQuery'].pop('sortOrder', None)
|
||||||
|
if 'orgUnit' in policy['policyQuery'] or 'group' in policy['policyQuery']:
|
||||||
|
policy['policyQuery'].pop('query', None)
|
||||||
if 'setting' in policy:
|
if 'setting' in policy:
|
||||||
if 'value' in policy['setting']:
|
if 'value' in policy['setting']:
|
||||||
policy['setting']['value'].pop('createTime', None)
|
policy['setting']['value'].pop('createTime', None)
|
||||||
@@ -38576,19 +38566,37 @@ def doCreateUpdateCIPolicy():
|
|||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if myarg in {'ou', 'org', 'orgunit'}:
|
if myarg in {'ou', 'org', 'orgunit'}:
|
||||||
orgUnit, targetResource = _getCIPolicyOrgUnitTarget(cd, myarg, groupEmail)
|
if groupEmail:
|
||||||
policy.setdefault('policyQuery', {})
|
Cmd.Backup()
|
||||||
policy['policyQuery'].pop('group', None)
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'group'))
|
||||||
policy['policyQuery']['orgUnit'] = f"orgUnits/{targetResource}"
|
if query:
|
||||||
policy['policyQuery']['query'] = f"entity.org_units.exists(org_unit, org_unit.org_unit_id == orgUnitId('{targetResource}'))"
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'query'))
|
||||||
|
orgUnit, targetResource = _getOrgunitsOrgUnitIdPath(cd, getString(Cmd.OB_ORGUNIT_PATH))
|
||||||
|
policy['policyQuery'] = {'orgUnit': f"orgUnits/{targetResource}"}
|
||||||
elif myarg == 'group':
|
elif myarg == 'group':
|
||||||
groupEmail, targetResource = _getCIPolicyGroupTarget(cd, myarg, orgUnit)
|
if orgUnit:
|
||||||
policy.setdefault('policyQuery', {})
|
Cmd.Backup()
|
||||||
policy['policyQuery'].pop('orgUnit', None)
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'ou|org|orgunit'))
|
||||||
policy['policyQuery']['group'] = f"groups/{targetResource}"
|
if query:
|
||||||
policy['policyQuery']['query'] = f"entity.groups.exists(group, group.group_id == groupId('{targetResource}'))"
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'query'))
|
||||||
|
groupEmail = getEmailAddress(returnUIDprefix='uid:')
|
||||||
|
targetResource = f"groups/{convertEmailAddressToUID(groupEmail, cd, emailType='group')}"
|
||||||
|
policy['policyQuery'] = {'group': f"groups/{targetResource}"}
|
||||||
|
elif myarg == 'query':
|
||||||
|
if groupEmail:
|
||||||
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'group'))
|
||||||
|
if orgUnit:
|
||||||
|
Cmd.Backup()
|
||||||
|
usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format(myarg, 'ou|org|orgunit'))
|
||||||
|
query = getString(Cmd.OB_QUERY)
|
||||||
|
policy['policyQuery'] = {'query': query}
|
||||||
else:
|
else:
|
||||||
unknownArgumentExit()
|
unknownArgumentExit()
|
||||||
|
if 'policyQuery' not in policy:
|
||||||
|
missingArgumentExit('ou|org|orgunit|group|query')
|
||||||
policy['customer'] = _getCustomersCustomerIdWithC()
|
policy['customer'] = _getCustomersCustomerIdWithC()
|
||||||
try:
|
try:
|
||||||
if updateCmd:
|
if updateCmd:
|
||||||
@@ -38616,11 +38624,10 @@ def doCreateUpdateCIPolicy():
|
|||||||
GAPI.notFound, GAPI.permissionDenied, GAPI.internalError) as e:
|
GAPI.notFound, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||||
entityActionFailedWarning([Ent.POLICY, pname], str(e))
|
entityActionFailedWarning([Ent.POLICY, pname], str(e))
|
||||||
|
|
||||||
|
|
||||||
# gam delete policies <CIPolicyNameEntity>
|
# gam delete policies <CIPolicyNameEntity>
|
||||||
def doDeleteCIPolicies():
|
def doDeleteCIPolicies():
|
||||||
_checkPoliciesWithDASA()
|
_checkPoliciesWithDASA()
|
||||||
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY_BETA)
|
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
|
||||||
entityList = getEntityList(Cmd.OB_CIPOLICY_NAME_ENTITY)
|
entityList = getEntityList(Cmd.OB_CIPOLICY_NAME_ENTITY)
|
||||||
checkForExtraneousArguments()
|
checkForExtraneousArguments()
|
||||||
i = 0
|
i = 0
|
||||||
@@ -42949,14 +42956,16 @@ def doCalendarsModifySettings(calIds):
|
|||||||
def _showCalendarSettings(calendar, j, jcount):
|
def _showCalendarSettings(calendar, j, jcount):
|
||||||
printEntity([Ent.CALENDAR, calendar['id']], j, jcount)
|
printEntity([Ent.CALENDAR, calendar['id']], j, jcount)
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
|
if 'dataOwner' in calendar:
|
||||||
|
printKeyValueList(['Owner', calendar['dataOwner']])
|
||||||
if 'summaryOverride' in calendar or 'summary' in calendar:
|
if 'summaryOverride' in calendar or 'summary' in calendar:
|
||||||
printKeyValueList(['Summary', calendar.get('summaryOverride', calendar.get('summary', ''))])
|
printKeyValueList(['Summary', calendar.get('summaryOverride', calendar.get('summary', ''))])
|
||||||
if 'description' in calendar:
|
if 'description' in calendar:
|
||||||
printKeyValueWithCRsNLs('Description', calendar.get('description', ''))
|
printKeyValueWithCRsNLs('Description', calendar['description'])
|
||||||
if 'location' in calendar:
|
if 'location' in calendar:
|
||||||
printKeyValueList(['Location', calendar.get('location', '')])
|
printKeyValueList(['Location', calendar['location']])
|
||||||
if 'timeZone' in calendar:
|
if 'timeZone' in calendar:
|
||||||
printKeyValueList(['Timezone', calendar.get('timeZone', '')])
|
printKeyValueList(['Timezone', calendar['timeZone']])
|
||||||
if 'conferenceProperties' in calendar:
|
if 'conferenceProperties' in calendar:
|
||||||
printKeyValueList(['ConferenceProperties', None])
|
printKeyValueList(['ConferenceProperties', None])
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ CLOUDIDENTITY_INBOUND_SSO = 'cloudidentityinboundsso'
|
|||||||
CLOUDIDENTITY_ORGUNITS = 'cloudidentityorgunits'
|
CLOUDIDENTITY_ORGUNITS = 'cloudidentityorgunits'
|
||||||
CLOUDIDENTITY_ORGUNITS_BETA = 'cloudidentityorgunitsbeta'
|
CLOUDIDENTITY_ORGUNITS_BETA = 'cloudidentityorgunitsbeta'
|
||||||
CLOUDIDENTITY_POLICY = 'cloudidentitypolicy'
|
CLOUDIDENTITY_POLICY = 'cloudidentitypolicy'
|
||||||
CLOUDIDENTITY_POLICY_BETA = 'cloudidentitypolicybeta'
|
|
||||||
CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations'
|
CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations'
|
||||||
CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
|
CLOUDRESOURCEMANAGER = 'cloudresourcemanager'
|
||||||
CLOUDRESOURCEMANAGERV1 = 'cloudresourcemanagerv1'
|
CLOUDRESOURCEMANAGERV1 = 'cloudresourcemanagerv1'
|
||||||
@@ -261,7 +260,6 @@ _INFO = {
|
|||||||
CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDIDENTITY_POLICY_BETA: {'name': 'Cloud Identity API - Policy Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
|
||||||
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'},
|
||||||
CLOUDRESOURCEMANAGER: {'name': 'Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
|
CLOUDRESOURCEMANAGER: {'name': 'Resource Manager API v3', 'version': 'v3', 'v2discovery': True},
|
||||||
CLOUDRESOURCEMANAGERV1: {'name': 'Resource Manager API v1', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudresourcemanager'},
|
CLOUDRESOURCEMANAGERV1: {'name': 'Resource Manager API v1', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudresourcemanager'},
|
||||||
@@ -405,10 +403,6 @@ _CLIENT_SCOPES = [
|
|||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
'roByDefault': True,
|
'roByDefault': True,
|
||||||
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
{'name': 'Cloud Identity API - Policy Beta',
|
|
||||||
'api': CLOUDIDENTITY_POLICY_BETA,
|
|
||||||
'offByDefault': True,
|
|
||||||
'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
|
||||||
{'name': 'Cloud Identity API - User Invitations',
|
{'name': 'Cloud Identity API - User Invitations',
|
||||||
'api': CLOUDIDENTITY_USERINVITATIONS,
|
'api': CLOUDIDENTITY_USERINVITATIONS,
|
||||||
'subscopes': READONLY,
|
'subscopes': READONLY,
|
||||||
@@ -641,10 +635,6 @@ _SVCACCT_SCOPES = [
|
|||||||
# 'subscopes': READONLY,
|
# 'subscopes': READONLY,
|
||||||
# 'roByDefault': True,
|
# 'roByDefault': True,
|
||||||
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
||||||
# {'name': 'Cloud Identity API - Policy Beta',
|
|
||||||
# 'api': CLOUDIDENTITY_POLICY_BETA,
|
|
||||||
# 'offByDefault': True,
|
|
||||||
# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'},
|
|
||||||
# {'name': 'Cloud Identity User Invitations API',
|
# {'name': 'Cloud Identity User Invitations API',
|
||||||
# 'api': CLOUDIDENTITY_USERINVITATIONS,
|
# 'api': CLOUDIDENTITY_USERINVITATIONS,
|
||||||
# 'subscopes': READONLY,
|
# 'subscopes': READONLY,
|
||||||
|
|||||||
@@ -462,6 +462,7 @@ PLEASE_CORRECT_YOUR_SYSTEM_TIME = 'Please correct your system time.'
|
|||||||
PLEASE_ENTER_A_OR_M = 'Please enter a or m ...\n'
|
PLEASE_ENTER_A_OR_M = 'Please enter a or m ...\n'
|
||||||
PLEASE_SELECT_ENTITY_TO_PROCESS = '{0} {1} found, please select the correct one to {2} and specify with {3}'
|
PLEASE_SELECT_ENTITY_TO_PROCESS = '{0} {1} found, please select the correct one to {2} and specify with {3}'
|
||||||
PLEASE_SPECIFY_BUILDING_EXACT_CASE_NAME_OR_ID = 'Please specify building by exact case name or ID.'
|
PLEASE_SPECIFY_BUILDING_EXACT_CASE_NAME_OR_ID = 'Please specify building by exact case name or ID.'
|
||||||
|
POLICY_NAME_NOT_FOUND = 'JSON key "name" not found in JSON data'
|
||||||
PREVIEW_ONLY = 'Preview Only'
|
PREVIEW_ONLY = 'Preview Only'
|
||||||
PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN = 'primaryEmail address did not match pattern: {0}'
|
PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN = 'primaryEmail address did not match pattern: {0}'
|
||||||
PROCESS = 'process'
|
PROCESS = 'process'
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
- [Definitions](#definitions)
|
- [Definitions](#definitions)
|
||||||
- [Policies](#policies)
|
- [Policies](#policies)
|
||||||
- [Display Cloud Identity Policies](#display-cloud-identity-policies)
|
- [Display Cloud Identity Policies](#display-cloud-identity-policies)
|
||||||
|
- [Create and Update Cloud Identity Policies](#create-and-update-cloud-identity-policies)
|
||||||
|
- [Delete Cloud Identity Policies](#delete-cloud-identity-policies)
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
* [Policy API](https://cloud.google.com/identity/docs/reference/rest/v1/policies)
|
* [Policy API](https://cloud.google.com/identity/docs/reference/rest/v1/policies)
|
||||||
@@ -35,6 +37,9 @@ You must enable access to policies in the GCP cloud console.
|
|||||||
* Click Organization Policy Administrator
|
* Click Organization Policy Administrator
|
||||||
* Click Save
|
* Click Save
|
||||||
|
|
||||||
|
The commands to create, update and delete Cloud Identity policies for data loss prevention (DLP) rules and detectors
|
||||||
|
were added in version `7.46.00`.
|
||||||
|
|
||||||
## Definitions
|
## Definitions
|
||||||
```
|
```
|
||||||
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||||
@@ -87,7 +92,7 @@ gam show policies
|
|||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
By default, all policies are displayed.
|
By default, all policies are displayed.
|
||||||
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1/policies/list
|
||||||
* `group <REMatchPattern>` - Only display policies whose group email address matches the `<REMatchPattern>`
|
* `group <REMatchPattern>` - Only display policies whose group email address matches the `<REMatchPattern>`
|
||||||
* `ou|org|orgunit <REMatchPattern>` - Only display policies whose OU path matches the `<REMatchPattern>`
|
* `ou|org|orgunit <REMatchPattern>` - Only display policies whose OU path matches the `<REMatchPattern>`
|
||||||
|
|
||||||
@@ -110,7 +115,7 @@ gam print policies [todrive <ToDriveAttribute>*]
|
|||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
By default, all policies are displayed:
|
By default, all policies are displayed:
|
||||||
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1/policies/list
|
||||||
* `group <REMatchPattern>` - Only display policies whose group email address matches the `<REMatchPattern>`
|
* `group <REMatchPattern>` - Only display policies whose group email address matches the `<REMatchPattern>`
|
||||||
* `ou|org|orgunit <REMatchPattern>` - Only display policies whose OU path matches the `<REMatchPattern>`
|
* `ou|org|orgunit <REMatchPattern>` - Only display policies whose OU path matches the `<REMatchPattern>`
|
||||||
|
|
||||||
@@ -152,3 +157,32 @@ Print all polices that apply to the OU "/Staff" and its sub-OUs.
|
|||||||
```
|
```
|
||||||
gam redirect csv ./StaffPolicies.csv print policies ou "^/Staff"
|
gam redirect csv ./StaffPolicies.csv print policies ou "^/Staff"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Create and Update Cloud Identity Policies
|
||||||
|
Policies can be complex objects, it is probably easiest to create template policies in the Admin console (under Rules),
|
||||||
|
output the JSON format data for those policies to be used in subsequent create and update commands.
|
||||||
|
|
||||||
|
```
|
||||||
|
gam create policy
|
||||||
|
json <JSONData>
|
||||||
|
[(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
|
gam update policy
|
||||||
|
json <JSONData>
|
||||||
|
[(ou|orgunit <OrgUnitItem>)|(group <GroupItem>)|(query <String>)]
|
||||||
|
```
|
||||||
|
```
|
||||||
|
gam redirect stdout ./policy.json info policies policies/akajj264aoclblvncu
|
||||||
|
Make changes to policy.json and update the policy.
|
||||||
|
gam update policy json file policy.json
|
||||||
|
|
||||||
|
Update the policy to reference a different group.
|
||||||
|
gam update policy json file policy.json group <EmailAddress>
|
||||||
|
|
||||||
|
Make changes to policy.json and create a new policy in a different OU.
|
||||||
|
gam create policy json file policy.json ou <OrgUnitPath>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Delete Cloud Identity Policies
|
||||||
|
```
|
||||||
|
gam delete policies <CIPolicyNameEntity>
|
||||||
|
```
|
||||||
|
|||||||
@@ -10,6 +10,33 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
|||||||
|
|
||||||
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 7.46.01
|
||||||
|
|
||||||
|
Fixed bug in `gam <CrOSTypeEntity> issuecommand command <CrOSCommand> ... csv` where
|
||||||
|
command execution status lines were improperly indented.
|
||||||
|
|
||||||
|
Upgraded to Python 3.14.6.
|
||||||
|
|
||||||
|
### 7.46.00
|
||||||
|
|
||||||
|
Added commands to create, update and delete Cloud Identity policies for data loss prevention (DLP) rules and detectors.
|
||||||
|
|
||||||
|
* See: https://github.com/GAM-team/GAM/wiki/Cloud-Identity-Policies
|
||||||
|
* See: https://workspaceupdates.googleblog.com/2026/06/introducing-workspace-policy-api-mutate-endpoints-for-DLP.html
|
||||||
|
|
||||||
|
### 7.45.00
|
||||||
|
|
||||||
|
Added options `isdisabled [<Boolean>]`, `disabledafter <DateTime>` and `disabledbefore <DateTime>`
|
||||||
|
to `gam print users`. These options along with `issuspended [<Boolean>]` and `isarchived [<Boolean>]`
|
||||||
|
are useful when identifying users to deprovision.
|
||||||
|
|
||||||
|
Added option `movefilepermissions [<Boolean>]]` to `gam <UserTypeEntity> move drivefile` that, when False,
|
||||||
|
causes GAM to remove ACLs from a file before moving it; this will be most useful when moving files to
|
||||||
|
Shared Drives so that only the Shared Drive ACls apply. When not specified or set True, file permissions
|
||||||
|
are not removed; this is the current GAM behavior.
|
||||||
|
|
||||||
|
Upgraded to OpenSSL 4.0.1.
|
||||||
|
|
||||||
### 7.44.03
|
### 7.44.03
|
||||||
|
|
||||||
Added `writerwithoutprivateaccess` to `<CalendarACLRole>`; this will become effective 2026-06-29.
|
Added `writerwithoutprivateaccess` to `<CalendarACLRole>`; this will become effective 2026-06-29.
|
||||||
|
|||||||
@@ -251,10 +251,10 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
gamteam@server:/Users/gamteam$ rm -f /Users/gamteam/GAMConfig/oauth2.txt
|
||||||
gamteam@server:/Users/gamteam$ gam version
|
gamteam@server:/Users/gamteam$ gam version
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.46.01 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|
||||||
@@ -1034,9 +1034,9 @@ writes the credentials into the file oauth2.txt.
|
|||||||
```
|
```
|
||||||
C:\>del C:\GAMConfig\oauth2.txt
|
C:\>del C:\GAMConfig\oauth2.txt
|
||||||
C:\>gam version
|
C:\>gam version
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM - pythonsource
|
GAM 7.46.01 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
Windows 11 10.0.26200 AMD64
|
Windows 11 10.0.26200 AMD64
|
||||||
Path: C:\GAM7
|
Path: C:\GAM7
|
||||||
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ gam <UserTypeEntity> print driveactivity [todrive <ToDriveAttributes>*]
|
|||||||
By default, drive activity for all files in the top level of My Drive will be displayed.
|
By default, drive activity for all files in the top level of My Drive will be displayed.
|
||||||
* `fileid <DriveFileID>` - Display drive activity for file `<DriveFileID>`
|
* `fileid <DriveFileID>` - Display drive activity for file `<DriveFileID>`
|
||||||
* `folderid <DriveFolderID>` - Display drive activity for all files in folder `<DriveFolderID>`
|
* `folderid <DriveFolderID>` - Display drive activity for all files in folder `<DriveFolderID>`
|
||||||
* `drivefilename <DriveFileName>` - Display drive activity for the file with name `<DriveFolderID>`
|
* `drivefilename <DriveFileName>` - Display drive activity for the file with name `<DriveFileName>`
|
||||||
* `drivefoldername <DriveFolderName>` - Display drive activity for all files in the folder with name `<DriveFolderName>`
|
* `drivefoldername <DriveFolderName>` - Display drive activity for all files in the folder with name `<DriveFolderName>`
|
||||||
* `query` - Display drive activity for all files/folders selected by the query
|
* `query` - Display drive activity for all files/folders selected by the query
|
||||||
|
|
||||||
Activities can be filtered by time.
|
Activities can be filtered by time.
|
||||||
|
|||||||
@@ -583,6 +583,7 @@ gam <UserTypeEntity> move drivefile <DriveFileEntity> [newfilename <DriveFileNam
|
|||||||
[copysubfolderpermissions [<Boolean>]]
|
[copysubfolderpermissions [<Boolean>]]
|
||||||
[copysubfolderinheritedpermissions [<Boolean>]]
|
[copysubfolderinheritedpermissions [<Boolean>]]
|
||||||
[copysubfoldernoninheritedpermissions never|always|syncallfolders|syncupdatedfolders]
|
[copysubfoldernoninheritedpermissions never|always|syncallfolders|syncupdatedfolders]
|
||||||
|
[movefilepermissions [<Boolean>]]
|
||||||
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
|
[excludepermissionsfromdomains|includepermissionsfromdomains <DomainNameList>]
|
||||||
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
|
(mappermissionsemail <EmailAddress> <EmailAddress)* [mappermissionsemailfile <CSVFileInput> endcsv]
|
||||||
(mappermissionsdomain <DomainName> <DomainName>)*
|
(mappermissionsdomain <DomainName> <DomainName>)*
|
||||||
@@ -729,6 +730,8 @@ and any remaining copy errors.
|
|||||||
### Moved File Permissions
|
### Moved File Permissions
|
||||||
By default, the permissions of a moved file are not modified.
|
By default, the permissions of a moved file are not modified.
|
||||||
|
|
||||||
|
When `movefilerpermissions false` is specified, all ACLs are removed.
|
||||||
|
|
||||||
When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that references a domain in `<DomainNameList>` will be removed.
|
When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that references a domain in `<DomainNameList>` will be removed.
|
||||||
|
|
||||||
When `includepermissionsfromdomains <DomainNameList>` is specified, any ACLs that references a domain not in `<DomainNameList>` will be removed.
|
When `includepermissionsfromdomains <DomainNameList>` is specified, any ACLs that references a domain not in `<DomainNameList>` will be removed.
|
||||||
|
|||||||
@@ -1122,6 +1122,10 @@ The `isarchived`, `issuspended` and `isdisabled` options can be used to select u
|
|||||||
| isdisabled [true] | Archived or Suspended Users |
|
| isdisabled [true] | Archived or Suspended Users |
|
||||||
| isdisabled false | Non-Archived and Non-Suspended Users |
|
| isdisabled false | Non-Archived and Non-Suspended Users |
|
||||||
|
|
||||||
|
When none of `isarchived`, `issuspended`, `isdisabled` are specified,
|
||||||
|
but one or both of `disabledafter` or `disabledbefore` is specified,
|
||||||
|
then `isdisabled true` is selected.
|
||||||
|
|
||||||
When any of `isarchived [true]`, `issuspended [true]`, `isdisabled [true]` are specified,
|
When any of `isarchived [true]`, `issuspended [true]`, `isdisabled [true]` are specified,
|
||||||
the following options can be used to further limit the users displayed.
|
the following options can be used to further limit the users displayed.
|
||||||
* `disabledafter <DateTime>` - Display users disabled on/after `<DateTime>`
|
* `disabledafter <DateTime>` - Display users disabled on/after `<DateTime>`
|
||||||
@@ -1230,6 +1234,10 @@ The `isarchived`, `issuspended` and `isdisabled` options can be used to select u
|
|||||||
| isdisabled [true] | Archived or Suspended Users |
|
| isdisabled [true] | Archived or Suspended Users |
|
||||||
| isdisabled false | Non-Archived and Non-Suspended Users |
|
| isdisabled false | Non-Archived and Non-Suspended Users |
|
||||||
|
|
||||||
|
When none of `isarchived`, `issuspended`, `isdisabled` are specified,
|
||||||
|
but one or both of `disabledafter` or `disabledbefore` is specified,
|
||||||
|
then `isdisabled true` is selected.
|
||||||
|
|
||||||
When any of `isarchived [true]`, `issuspended [true]`, `isdisabled [true]` are specified,
|
When any of `isarchived [true]`, `issuspended [true]`, `isdisabled [true]` are specified,
|
||||||
the following options can be used to further limit the users displayed.
|
the following options can be used to further limit the users displayed.
|
||||||
* `disabledafter <DateTime>` - Display users disabled on/after `<DateTime>`
|
* `disabledafter <DateTime>` - Display users disabled on/after `<DateTime>`
|
||||||
|
|||||||
@@ -376,7 +376,7 @@ For `corpus calendar`, you can specify advanced search options:
|
|||||||
* `minuswords <StringList>`
|
* `minuswords <StringList>`
|
||||||
* Matches only those events that do not contain any of the words in the given set in title, description, location, or attendees.
|
* Matches only those events that do not contain any of the words in the given set in title, description, location, or attendees.
|
||||||
* Entries in the set are considered in "or".
|
* Entries in the set are considered in "or".
|
||||||
* `responsestatuses <AttendeeStatus>(,<AttendeeStatus>)*
|
* `responsestatuses <AttendeeStatus>(,<AttendeeStatus>)*`
|
||||||
* Matches only events for which the custodian gave one of these responses. If the set is empty, there will be no filtering on responses.
|
* Matches only events for which the custodian gave one of these responses. If the set is empty, there will be no filtering on responses.
|
||||||
* `calendarversiondate <Date>|<Time>`
|
* `calendarversiondate <Date>|<Time>`
|
||||||
* Search the current version of the Calendar event, but export the contents of the last version saved before 12:00 AM UTC on the specified date.
|
* Search the current version of the Calendar event, but export the contents of the last version saved before 12:00 AM UTC on the specified date.
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.46.01 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
@@ -15,10 +15,10 @@ Time: 2026-02-15T07:51:00-08:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.46.01 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Your system time differs from www.googleapis.com by less than 1 second
|
Your system time differs from www.googleapis.com by less than 1 second
|
||||||
@@ -27,29 +27,29 @@ 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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.46.01 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
Your system time differs from admin.googleapis.com by less than 1 second
|
Your system time differs from admin.googleapis.com by less than 1 second
|
||||||
OpenSSL 4.0.0 14 Apr 2026
|
OpenSSL 4.0.1 9 Jun 2026
|
||||||
arrow 1.4.0
|
arrow 1.4.0
|
||||||
chardet 5.2.0
|
chardet 7.4.3
|
||||||
cryptography 46.0.5
|
cryptography 48.0.0
|
||||||
filelock 3.21.2
|
filelock 3.29.0
|
||||||
google-api-python-client 2.190.0
|
google-api-python-client 2.196.0
|
||||||
google-auth-httplib2 0.3.0
|
google-auth-httplib2 0.4.0
|
||||||
google-auth-oauthlib 1.2.4
|
google-auth-oauthlib 1.4.0
|
||||||
google-auth 2.48.0
|
google-auth 2.53.0
|
||||||
lxml 6.0.2
|
lxml 6.1.1
|
||||||
httplib2 0.31.2
|
httplib2 0.31.2
|
||||||
passlib 1.7.4
|
passlib 1.7.4
|
||||||
pathvalidate 3.3.1
|
pathvalidate 3.3.1
|
||||||
pyscard 2.3.1
|
pyscard 2.3.1
|
||||||
yubikey-manager 5.9.0
|
yubikey-manager 5.9.1
|
||||||
admin.googleapis.com connects using TLSv1.3 TLS_AES_256_GCM_SHA384
|
admin.googleapis.com connects using TLSv1.3 TLS_AES_256_GCM_SHA384
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 7.44.03
|
Latest: 7.46.01
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -76,7 +76,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
7.44.03
|
7.46.01
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -86,10 +86,10 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 7.44.03 - https://github.com/GAM-team/GAM
|
GAM 7.46.01 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.14.5 64-bit final
|
Python 3.14.6 64-bit final
|
||||||
macOS Tahoe 26.5 arm64
|
macOS Tahoe 26.5.1 arm64
|
||||||
Path: /Users/gamteam/bin/gam7
|
Path: /Users/gamteam/bin/gam7
|
||||||
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/gamteam/GamConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2026-02-15T07:51:00-08:00
|
Time: 2026-02-15T07:51:00-08:00
|
||||||
|
|||||||
Reference in New Issue
Block a user