gam7 7.3.5__tar.gz → 7.3.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. gam7-7.3.7/.github/workflows/pypi.yml +32 -0
  2. {gam7-7.3.5 → gam7-7.3.7}/PKG-INFO +1 -1
  3. {gam7-7.3.5 → gam7-7.3.7}/src/GamCommands.txt +13 -5
  4. {gam7-7.3.5 → gam7-7.3.7}/src/GamUpdate.txt +14 -1
  5. {gam7-7.3.5 → gam7-7.3.7}/src/gam/__init__.py +71 -30
  6. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glclargs.py +1 -0
  7. {gam7-7.3.5 → gam7-7.3.7}/.github/ISSUE_TEMPLATE/aa-question.md +0 -0
  8. {gam7-7.3.5 → gam7-7.3.7}/.github/ISSUE_TEMPLATE/za-bug-report.md +0 -0
  9. {gam7-7.3.5 → gam7-7.3.7}/.github/ISSUE_TEMPLATE/zz-feature-request.md +0 -0
  10. {gam7-7.3.5 → gam7-7.3.7}/.github/ISSUE_TEMPLATE.txt +0 -0
  11. {gam7-7.3.5 → gam7-7.3.7}/.github/actions/creds.tar.xz.gpg +0 -0
  12. {gam7-7.3.5 → gam7-7.3.7}/.github/actions/decrypt.sh +0 -0
  13. {gam7-7.3.5 → gam7-7.3.7}/.github/actions/entitlements.plist +0 -0
  14. {gam7-7.3.5 → gam7-7.3.7}/.github/actions/package_exclusions.txt +0 -0
  15. {gam7-7.3.5 → gam7-7.3.7}/.github/stale.yml +0 -0
  16. {gam7-7.3.5 → gam7-7.3.7}/.github/workflows/build.yml +0 -0
  17. {gam7-7.3.5 → gam7-7.3.7}/.github/workflows/codeql-analysis.yml +0 -0
  18. {gam7-7.3.5 → gam7-7.3.7}/.github/workflows/get-cacerts.yml +0 -0
  19. {gam7-7.3.5 → gam7-7.3.7}/.pre-commit-config.yaml +0 -0
  20. {gam7-7.3.5 → gam7-7.3.7}/LICENSE +0 -0
  21. {gam7-7.3.5 → gam7-7.3.7}/README.md +0 -0
  22. {gam7-7.3.5 → gam7-7.3.7}/pyproject.toml +0 -0
  23. {gam7-7.3.5 → gam7-7.3.7}/src/.gitignore +0 -0
  24. {gam7-7.3.5 → gam7-7.3.7}/src/LICENSE +0 -0
  25. {gam7-7.3.5 → gam7-7.3.7}/src/cacerts.pem +0 -0
  26. {gam7-7.3.5 → gam7-7.3.7}/src/callgam.py +0 -0
  27. {gam7-7.3.5 → gam7-7.3.7}/src/gam/__main__.py +0 -0
  28. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/__init__.py +0 -0
  29. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/auth.py +0 -0
  30. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/client.py +0 -0
  31. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/core.py +0 -0
  32. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/data.py +0 -0
  33. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/http.py +0 -0
  34. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/http_core.py +0 -0
  35. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/http_interface.py +0 -0
  36. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/mock_http.py +0 -0
  37. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/mock_http_core.py +0 -0
  38. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/mock_service.py +0 -0
  39. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/service.py +0 -0
  40. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/token_store.py +0 -0
  41. {gam7-7.3.5 → gam7-7.3.7}/src/gam/atom/url.py +0 -0
  42. {gam7-7.3.5 → gam7-7.3.7}/src/gam/cacerts.pem +0 -0
  43. {gam7-7.3.5 → gam7-7.3.7}/src/gam/cbcm-v1.1beta1.json +0 -0
  44. {gam7-7.3.5 → gam7-7.3.7}/src/gam/contactdelegation-v1.json +0 -0
  45. {gam7-7.3.5 → gam7-7.3.7}/src/gam/datastudio-v1.json +0 -0
  46. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/__init__.py +0 -0
  47. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glaction.py +0 -0
  48. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glapi.py +0 -0
  49. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glcfg.py +0 -0
  50. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glentity.py +0 -0
  51. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glgapi.py +0 -0
  52. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glgdata.py +0 -0
  53. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glglobals.py +0 -0
  54. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glindent.py +0 -0
  55. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glmsgs.py +0 -0
  56. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glskus.py +0 -0
  57. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/gluprop.py +0 -0
  58. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/glverlibs.py +0 -0
  59. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gamlib/yubikey.py +0 -0
  60. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/__init__.py +0 -0
  61. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/alt/__init__.py +0 -0
  62. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/alt/app_engine.py +0 -0
  63. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/alt/appengine.py +0 -0
  64. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/__init__.py +0 -0
  65. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/audit/__init__.py +0 -0
  66. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/audit/service.py +0 -0
  67. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/contacts/__init__.py +0 -0
  68. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/contacts/service.py +0 -0
  69. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/service.py +0 -0
  70. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/sites/__init__.py +0 -0
  71. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/apps/sites/service.py +0 -0
  72. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/service.py +0 -0
  73. {gam7-7.3.5 → gam7-7.3.7}/src/gam/gdata/urlfetch.py +0 -0
  74. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/__init__.py +0 -0
  75. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/_auth.py +0 -0
  76. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/_helpers.py +0 -0
  77. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/channel.py +0 -0
  78. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/discovery.py +0 -0
  79. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/discovery_cache/__init__.py +0 -0
  80. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/discovery_cache/appengine_memcache.py +0 -0
  81. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/discovery_cache/base.py +0 -0
  82. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/discovery_cache/file_cache.py +0 -0
  83. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/errors.py +0 -0
  84. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/http.py +0 -0
  85. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/mimeparse.py +0 -0
  86. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/model.py +0 -0
  87. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/schema.py +0 -0
  88. {gam7-7.3.5 → gam7-7.3.7}/src/gam/googleapiclient/version.py +0 -0
  89. {gam7-7.3.5 → gam7-7.3.7}/src/gam/iso8601/__init__.py +0 -0
  90. {gam7-7.3.5 → gam7-7.3.7}/src/gam/iso8601/iso8601.py +0 -0
  91. {gam7-7.3.5 → gam7-7.3.7}/src/gam/serviceaccountlookup-v1.json +0 -0
  92. {gam7-7.3.5 → gam7-7.3.7}/src/gam/six.py +0 -0
  93. {gam7-7.3.5 → gam7-7.3.7}/src/gam-install.sh +0 -0
  94. {gam7-7.3.5 → gam7-7.3.7}/src/gam-setup.bat +0 -0
  95. {gam7-7.3.5 → gam7-7.3.7}/src/gam.exe.manifest +0 -0
  96. {gam7-7.3.5 → gam7-7.3.7}/src/gam.py +0 -0
  97. {gam7-7.3.5 → gam7-7.3.7}/src/gam.spec +0 -0
  98. {gam7-7.3.5 → gam7-7.3.7}/src/gam.wxs +0 -0
  99. {gam7-7.3.5 → gam7-7.3.7}/src/license.rtf +0 -0
  100. {gam7-7.3.5 → gam7-7.3.7}/src/project-apis.txt +0 -0
  101. {gam7-7.3.5 → gam7-7.3.7}/src/requirements-dev.txt +0 -0
  102. {gam7-7.3.5 → gam7-7.3.7}/src/requirements.txt +0 -0
  103. {gam7-7.3.5 → gam7-7.3.7}/src/setup.cfg +0 -0
  104. {gam7-7.3.5 → gam7-7.3.7}/src/setup.py +0 -0
  105. {gam7-7.3.5 → gam7-7.3.7}/src/tools/a_atleast_b.py +0 -0
  106. {gam7-7.3.5 → gam7-7.3.7}/src/tools/gen-wix-xml-filelist.py +0 -0
  107. {gam7-7.3.5 → gam7-7.3.7}/src/tools/mkGamRef.py +0 -0
  108. {gam7-7.3.5 → gam7-7.3.7}/src/tools/openssl.props +0 -0
  109. {gam7-7.3.5 → gam7-7.3.7}/src/version_info.txt.in +0 -0
@@ -0,0 +1,32 @@
1
+ name: build and publish releases to PyPi
2
+ on:
3
+ push:
4
+ tags:
5
+ - 'v[0-9]+.[0-9]+.[0-9]+'
6
+
7
+ jobs:
8
+ pypi:
9
+ name: Upload release to PyPI
10
+ runs-on: ubuntu-latest
11
+ environment:
12
+ name: pypi
13
+ url: https://pypi.org/p/gam7
14
+ permissions:
15
+ id-token: write
16
+ steps:
17
+
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ persist-credentials: false
21
+ fetch-depth: 0
22
+
23
+ - name: Install required packages to publish
24
+ run: |
25
+ python3 -m pip install --upgrade build
26
+
27
+ - name: Build packages
28
+ run: |
29
+ python -m build
30
+
31
+ - name: Publish package distributions to PyPI
32
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.3.5
3
+ Version: 7.3.7
4
4
  Summary: CLI tool to manage Google Workspace
5
5
  Project-URL: Homepage, https://github.com/GAM-team/GAM
6
6
  Project-URL: Issues, https://github.com/GAM-team/GAM/issues
@@ -2090,19 +2090,25 @@ gam move browsers ou|org|orgunit <OrgUnitPath>
2090
2090
  [batchsize <Integer>]
2091
2091
 
2092
2092
  gam info browser <DeviceID>
2093
- [basic|full|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
2093
+ (basic|full|annotated |
2094
+ (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
2095
+ (rawfields "<BrowserFieldNameList>"))
2094
2096
  [formatjson]
2095
2097
  gam show browsers
2096
2098
  ([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser>)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
2097
2099
  [querytime<String> <Time>]
2098
2100
  [orderby <BrowserOrderByFieldName> [ascending|descending]]
2099
- [basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
2101
+ (basic|full|annotated |
2102
+ (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
2103
+ (rawfields "<BrowserFieldNameList>"))
2100
2104
  [formatjson]
2101
2105
  gam print browsers [todrive <ToDriveAttribute>*]
2102
2106
  ([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser>)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
2103
2107
  [querytime<String> <Time>]
2104
2108
  [orderby <BrowserOrderByFieldName> [ascending|descending]]
2105
- [basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
2109
+ (basic|full|annotated |
2110
+ (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
2111
+ (rawfields "<BrowserFieldNameList>"))
2106
2112
  [sortheaders]
2107
2113
  [formatjson [quotechar <Character>]]
2108
2114
 
@@ -5264,7 +5270,7 @@ gam print vaultcounts [todrive <ToDriveAttributes>*]
5264
5270
  gam print vaultcounts [todrive <ToDriveAttributes>*]
5265
5271
  matter <MatterItem> operation <String> [wait <Integer>]
5266
5272
 
5267
- gam create vaultexport|export matter <MatterItem> [name <String>] corpus calendar|drive|mail|groups|hangouts_chat|voice
5273
+ gam create vaultexport|export matter <MatterItem> [name <String>] corpus calendar|drive|gemini|groups|hangouts_chat|mail|voice
5268
5274
  (accounts <EmailAddressEntity>) | (orgunit|org|ou <OrgUnitPath>) | everyone
5269
5275
  (shareddrives|teamdrives <SharedDriveIDList>) | (rooms <RoomList>) | (sitesurl <URLList>)
5270
5276
  [scope all_data|held_data|unprocessed_data]
@@ -5272,10 +5278,12 @@ gam create vaultexport|export matter <MatterItem> [name <String>] corpus calenda
5272
5278
  [locationquery <StringList>] [peoplequery <StringList>] [minuswords <StringList>]
5273
5279
  [responsestatuses <AttendeeStatus>(,<AttendeeStatus>)*] [calendarversiondate <Date>|<Time>]
5274
5280
  [includeshareddrives <Boolean>] [driveversiondate <Date>|<Time>] [includeaccessinfo <Boolean>]
5281
+ [driveclientsideencryption any|encrypted|unencrypted]
5275
5282
  [includerooms <Boolean>]
5276
- [excludedrafts <Boolean>] [format mbox|pst]
5283
+ [excludedrafts <Boolean>] [mailclientsideencryption any|encrypted|unencrypted]
5277
5284
  [showconfidentialmodecontent <Boolean>] [usenewexport <Boolean>] [exportlinkeddrivefiles <Boolean>]
5278
5285
  [covereddata calllogs|textmessages|voicemails]
5286
+ [format ics|mbox|pst|xml]
5279
5287
  [region any|europe|us] [showdetails|returnidonly]
5280
5288
  gam delete vaultexport|export <ExportItem> matter <MatterItem>
5281
5289
  gam delete vaultexport|export <MatterItem> <ExportItem>
@@ -1,3 +1,16 @@
1
+ 7.03.07
2
+
3
+ Updated `gam create vaultexport` to include `corpus gemini`.
4
+
5
+ * See: https://workspaceupdates.googleblog.com/2025/02/google-vault-now-supports-gemini.html
6
+
7
+ 7.03.06
8
+
9
+ Added option `rawfields "<BrowserFieldNameList>"` to `gam info|print|show browsers` that allows
10
+ specification of complex field lists with selected subfields.
11
+
12
+ * See: https://github.com/GAM-team/GAM/wiki/Chrome-Browser-Cloud-Management#raw-fields
13
+
1
14
  7.03.05
2
15
 
3
16
  Make GAM pip-installable: "pip install gam7"
@@ -7,7 +20,7 @@ Make GAM pip-installable: "pip install gam7"
7
20
  Added option `security` to `gam create cigroup` that allows creation of a security group
8
21
  in a single command.
9
22
 
10
- Updated to Python 3.13.2 where possible.
23
+ Updated to Python 3.13.2.
11
24
 
12
25
  7.03.03
13
26
 
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
25
25
  """
26
26
 
27
27
  __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
28
- __version__ = '7.03.05'
28
+ __version__ = '7.03.07'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -7356,6 +7356,12 @@ def addFieldToFieldsList(fieldName, fieldsChoiceMap, fieldsList):
7356
7356
  def _getFieldsList():
7357
7357
  return getString(Cmd.OB_FIELD_NAME_LIST).lower().replace('_', '').replace(',', ' ').split()
7358
7358
 
7359
+ def _getRawFields(requiredField=None):
7360
+ rawFields = getString(Cmd.OB_FIELDS)
7361
+ if requiredField is None or requiredField in rawFields:
7362
+ return rawFields
7363
+ return f'{requiredField},{rawFields}'
7364
+
7359
7365
  def _addInitialField(fieldsList, initialField):
7360
7366
  if isinstance(initialField, list):
7361
7367
  fieldsList.extend(initialField)
@@ -16568,7 +16574,7 @@ def doInfoAdminRole():
16568
16574
  fieldsList.append('rolePrivileges')
16569
16575
  else:
16570
16576
  unknownArgumentExit()
16571
- fields = ','.join(set(fieldsList))
16577
+ fields = getFieldsFromFieldsList(fieldsList)
16572
16578
  try:
16573
16579
  role = callGAPI(cd.roles(), 'get',
16574
16580
  throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.FAILED_PRECONDITION,
@@ -17705,9 +17711,9 @@ def _getOrgUnits(cd, orgUnitPath, fieldsList, listType, showParent, batchSubOrgs
17705
17711
  if 'parentOrgUnitId' not in fieldsList:
17706
17712
  localFieldsList.append('parentOrgUnitId')
17707
17713
  deleteParentOrgUnitId = True
17708
- fields = ','.join(set(localFieldsList))
17714
+ fields = getFieldsFromFieldsList(localFieldsList)
17709
17715
  else:
17710
- fields = ','.join(set(fieldsList))
17716
+ fields = getFieldsFromFieldsList(fieldsList)
17711
17717
  listfields = f'organizationUnits({fields})'
17712
17718
  if listType == 'all' and orgUnitPath == '/':
17713
17719
  printGettingAllAccountEntities(Ent.ORGANIZATIONAL_UNIT)
@@ -22169,8 +22175,7 @@ def printShowUserPeopleContacts(users):
22169
22175
  if not fieldsList:
22170
22176
  ofields = _getPersonFields(PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP, PEOPLE_CONTACTS_DEFAULT_FIELDS, fieldsList, parameters)
22171
22177
  else:
22172
- fieldsList = [PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP[field.lower()] for field in fieldsList if field.lower() in PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP]
22173
- ofields = ','.join(set(fieldsList))
22178
+ ofields = getFieldsFromFieldsList([PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP[field.lower()] for field in fieldsList if field.lower() in PEOPLE_OTHER_CONTACTS_FIELDS_CHOICE_MAP])
22174
22179
  i, count, users = getEntityArgument(users)
22175
22180
  for user in users:
22176
22181
  i += 1
@@ -24784,7 +24789,7 @@ def doPrintCrOSActivity(entityList=None):
24784
24789
  else:
24785
24790
  sortRows = True
24786
24791
  jcount = len(entityList)
24787
- fields = ','.join(set(fieldsList))
24792
+ fields = getFieldsFromFieldsList(fieldsList)
24788
24793
  svcargs = dict([('customerId', GC.Values[GC.CUSTOMER_ID]), ('deviceId', None), ('projection', projection), ('fields', fields)]+GM.Globals[GM.EXTRA_ARGS_LIST])
24789
24794
  method = getattr(cd.chromeosdevices(), 'get')
24790
24795
  dbatch = cd.new_batch_http_request(callback=_callbackPrintCrOS)
@@ -25074,7 +25079,7 @@ def _showBrowser(browser, FJQC, i=0, count=0):
25074
25079
  return
25075
25080
  printEntity([Ent.CHROME_BROWSER, browser['deviceId']], i, count)
25076
25081
  Ind.Increment()
25077
- showJSON(None, browser, timeObjects=BROWSER_TIME_OBJECTS)
25082
+ showJSON(None, browser, timeObjects=BROWSER_TIME_OBJECTS, dictObjectsKey={'machinePolicies': 'name'})
25078
25083
  Ind.Decrement()
25079
25084
 
25080
25085
  BROWSER_FIELDS_CHOICE_MAP = {
@@ -25114,11 +25119,13 @@ BROWSER_FIELDS_CHOICE_MAP = {
25114
25119
  'user': 'annotatedUser',
25115
25120
  'virtualdeviceid': 'virtualDeviceId',
25116
25121
  }
25117
- BROWSER_ANNOTATED_FIELDS_LIST = ['annotatedAssetId', 'annotatedLocation', 'annotatedNotes', 'annotatedUser']
25122
+ BROWSER_ANNOTATED_FIELDS_LIST = ['annotatedAssetId', 'annotatedLocation', 'annotatedNotes', 'annotatedUser', 'deviceId']
25118
25123
  BROWSER_FULL_ACCESS_FIELDS = {'browsers', 'lastDeviceUsers', 'lastStatusReportTime', 'machinePolicies'}
25119
25124
 
25120
25125
  # gam info browser <DeviceID>
25121
- # [basic|full|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
25126
+ # (basic|full|annotated |
25127
+ # (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
25128
+ # (rawfields <BrowserFieldNameList>))
25122
25129
  # [formatjson]
25123
25130
  def doInfoBrowsers():
25124
25131
  cbcm = buildGAPIObject(API.CBCM)
@@ -25126,6 +25133,7 @@ def doInfoBrowsers():
25126
25133
  deviceId = getString(Cmd.OB_DEVICE_ID)
25127
25134
  projection = 'BASIC'
25128
25135
  fieldsList = []
25136
+ rawFields = None
25129
25137
  FJQC = FormatJSONQuoteChar()
25130
25138
  while Cmd.ArgumentsRemaining():
25131
25139
  myarg = getArgument()
@@ -25137,16 +25145,21 @@ def doInfoBrowsers():
25137
25145
  fieldsList = []
25138
25146
  elif getFieldsList(myarg, BROWSER_FIELDS_CHOICE_MAP, fieldsList, initialField='deviceId'):
25139
25147
  pass
25148
+ elif myarg == 'rawfields':
25149
+ projection = 'FULL'
25150
+ rawFields = _getRawFields('deviceId')
25140
25151
  else:
25141
25152
  FJQC.GetFormatJSON(myarg)
25142
25153
  if projection == 'BASIC' and set(fieldsList).intersection(BROWSER_FULL_ACCESS_FIELDS):
25143
25154
  projection = 'FULL'
25144
- fields = ','.join(set(fieldsList))
25155
+ fields = getFieldsFromFieldsList(fieldsList) if not rawFields else rawFields
25145
25156
  try:
25146
25157
  browser = callGAPI(cbcm.chromebrowsers(), 'get',
25147
- throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
25158
+ throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.FORBIDDEN],
25148
25159
  customer=customerId, deviceId=deviceId, projection=projection, fields=fields)
25149
25160
  _showBrowser(browser, FJQC)
25161
+ except GAPI.invalidArgument as e:
25162
+ entityActionFailedWarning([Ent.CHROME_BROWSER, deviceId], str(e))
25150
25163
  except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
25151
25164
  checkEntityAFDNEorAccessErrorExit(None, Ent.CHROME_BROWSER, deviceId)
25152
25165
 
@@ -25347,7 +25360,7 @@ def doInfoChromeProfile():
25347
25360
  pass
25348
25361
  else:
25349
25362
  FJQC.GetFormatJSON(myarg)
25350
- fields = ','.join(set(fieldsList))
25363
+ fields = getFieldsFromFieldsList(fieldsList)
25351
25364
  try:
25352
25365
  profile = callGAPI(cm.customers().profiles(), 'get',
25353
25366
  throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED],
@@ -25479,13 +25492,19 @@ BROWSER_ORDERBY_CHOICE_MAP = {
25479
25492
  # ([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
25480
25493
  # [querytime<String> <Time>]
25481
25494
  # [orderby <BrowserOrderByFieldName> [ascending|descending]]
25482
- # [basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
25495
+ # (basic|full|annotated |
25496
+ # (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
25497
+ # (rawfields <BrowserFieldNameList>))
25498
+ # (<BrowserFieldName>* [fields <BrowserFieldNameList>]|(rawfields <BrowserFieldNameList>)
25483
25499
  # [formatjson]
25484
25500
  # gam print browsers [todrive <ToDriveAttribute>*]
25485
25501
  # ([ou|org|orgunit|browserou <OrgUnitPath>] [(query <QueryBrowser)|(queries <QueryBrowserList>))|(select <BrowserEntity>))
25486
25502
  # [querytime<String> <Time>]
25487
25503
  # [orderby <BrowserOrderByFieldName> [ascending|descending]]
25488
- # [basic|full|allfields|annotated] <BrowserFieldName>* [fields <BrowserFieldNameList>]
25504
+ # (basic|full|annotated |
25505
+ # (<BrowserFieldName>* [fields <BrowserFieldNameList>]) |
25506
+ # (rawfields <BrowserFieldNameList>))
25507
+ # (<BrowserFieldName>* [fields <BrowserFieldNameList>]|(rawfields <BrowserFieldNameList>)
25489
25508
  # [sortheaders] [formatjson [quotechar <Character>]]
25490
25509
  def doPrintShowBrowsers():
25491
25510
  def _printBrowser(browser):
@@ -25502,6 +25521,7 @@ def doPrintShowBrowsers():
25502
25521
  csvPF = CSVPrintFile(['deviceId']) if Act.csvFormat() else None
25503
25522
  FJQC = FormatJSONQuoteChar(csvPF)
25504
25523
  fieldsList = []
25524
+ rawFields = None
25505
25525
  projection = 'BASIC'
25506
25526
  orderBy = 'id'
25507
25527
  sortOrder = 'ASCENDING'
@@ -25540,22 +25560,25 @@ def doPrintShowBrowsers():
25540
25560
  sortHeaders = True
25541
25561
  elif getFieldsList(myarg, BROWSER_FIELDS_CHOICE_MAP, fieldsList, initialField='deviceId'):
25542
25562
  pass
25563
+ elif myarg == 'rawfields':
25564
+ projection = 'FULL'
25565
+ rawFields = _getRawFields('deviceId')
25543
25566
  else:
25544
25567
  FJQC.GetFormatJSONQuoteChar(myarg, True)
25545
25568
  if projection == 'BASIC' and set(fieldsList).intersection(BROWSER_FULL_ACCESS_FIELDS):
25546
25569
  projection = 'FULL'
25547
- fields = getItemFieldsFromFieldsList('browsers', fieldsList)
25548
25570
  if FJQC.formatJSON:
25549
25571
  sortHeaders = False
25550
25572
  substituteQueryTimes(queries, queryTimes)
25551
25573
  if entityList is None:
25574
+ fields = getItemFieldsFromFieldsList('browsers', fieldsList) if not rawFields else f'nextPageToken,browsers({rawFields})'
25552
25575
  for query in queries:
25553
25576
  printGettingAllAccountEntities(Ent.CHROME_BROWSER, query)
25554
25577
  pageMessage = getPageMessage()
25555
25578
  try:
25556
25579
  feed = yieldGAPIpages(cbcm.chromebrowsers(), 'list', 'browsers',
25557
25580
  pageMessage=pageMessage, messageAttribute='deviceId',
25558
- throwReasons=[GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.INVALID_ORGUNIT, GAPI.FORBIDDEN],
25581
+ throwReasons=[GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.INVALID_ARGUMENT, GAPI.INVALID_ORGUNIT, GAPI.FORBIDDEN],
25559
25582
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
25560
25583
  customer=customerId, orgUnitPath=orgUnitPath, query=query, projection=projection,
25561
25584
  orderBy=orderBy, sortOrder=sortOrder, fields=fields)
@@ -25579,7 +25602,7 @@ def doPrintShowBrowsers():
25579
25602
  else:
25580
25603
  entityActionFailedWarning([Ent.CHROME_BROWSER, None], str(e))
25581
25604
  return
25582
- except (GAPI.invalidOrgunit, GAPI.forbidden) as e:
25605
+ except (GAPI.invalidArgument, GAPI.invalidOrgunit, GAPI.forbidden) as e:
25583
25606
  entityActionFailedWarning([Ent.CHROME_BROWSER, None], str(e))
25584
25607
  return
25585
25608
  except (GAPI.badRequest, GAPI.resourceNotFound):
@@ -25587,15 +25610,17 @@ def doPrintShowBrowsers():
25587
25610
  else:
25588
25611
  sortRows = True
25589
25612
  jcount = len(entityList)
25590
- fields = getFieldsFromFieldsList(fieldsList)
25613
+ fields = getFieldsFromFieldsList(fieldsList) if not rawFields else rawFields
25591
25614
  j = 0
25592
25615
  for deviceId in entityList:
25593
25616
  j += 1
25594
25617
  try:
25595
25618
  browser = callGAPI(cbcm.chromebrowsers(), 'get',
25596
- throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
25619
+ throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.FORBIDDEN],
25597
25620
  customer=customerId, deviceId=deviceId, projection=projection, fields=fields)
25598
25621
  _printBrowser(browser)
25622
+ except GAPI.invalidArgument as e:
25623
+ entityActionFailedWarning([Ent.CHROME_BROWSER, deviceId], str(e))
25599
25624
  except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
25600
25625
  checkEntityAFDNEorAccessErrorExit(None, Ent.CHROME_BROWSER, deviceId)
25601
25626
  if csvPF:
@@ -40430,9 +40455,10 @@ VAULT_SEARCH_METHODS_MAP = {
40430
40455
  VAULT_CORPUS_ARGUMENT_MAP = {
40431
40456
  'calendar': 'CALENDAR',
40432
40457
  'drive': 'DRIVE',
40433
- 'mail': 'MAIL',
40458
+ 'gemini': 'GEMINI',
40434
40459
  'groups': 'GROUPS',
40435
40460
  'hangoutschat': 'HANGOUTS_CHAT',
40461
+ 'mail': 'MAIL',
40436
40462
  'voice': 'VOICE',
40437
40463
  }
40438
40464
  VAULT_COUNTS_CORPUS_ARGUMENT_MAP = {
@@ -40459,15 +40485,22 @@ VAULT_EXPORT_FORMAT_MAP = {
40459
40485
  'ics': 'ICS',
40460
40486
  'mbox': 'MBOX',
40461
40487
  'pst': 'PST',
40488
+ 'xml': 'XML',
40462
40489
  }
40463
40490
  VAULT_CORPUS_EXPORT_FORMATS = {
40464
40491
  'CALENDAR': ['ICS', 'PST'],
40465
40492
  'DRIVE': [],
40493
+ 'GEMINI': ['XML'],
40466
40494
  'GROUPS': ['MBOX', 'PST'],
40467
40495
  'HANGOUTS_CHAT': ['MBOX', 'PST'],
40468
40496
  'MAIL': ['MBOX', 'PST'],
40469
40497
  'VOICE' : ['MBOX', 'PST'],
40470
40498
  }
40499
+ VAULT_CSE_OPTION_MAP = {
40500
+ 'any': 'CLIENT_SIDE_ENCRYPTED_OPTION_ANY',
40501
+ 'encrypted': 'CLIENT_SIDE_ENCRYPTED_OPTION_ENCRYPTED',
40502
+ 'unencrypted': 'CLIENT_SIDE_ENCRYPTED_OPTION_UNENCRYPTED',
40503
+ }
40471
40504
  VAULT_EXPORT_REGION_MAP = {
40472
40505
  'any': 'ANY',
40473
40506
  'europe': 'EUROPE',
@@ -40476,16 +40509,18 @@ VAULT_EXPORT_REGION_MAP = {
40476
40509
  VAULT_CORPUS_OPTIONS_MAP = {
40477
40510
  'CALENDAR': 'calendarOptions',
40478
40511
  'DRIVE': 'driveOptions',
40479
- 'MAIL': 'mailOptions',
40512
+ 'GEMINI': 'geminiOptions',
40480
40513
  'GROUPS': 'groupsOptions',
40481
40514
  'HANGOUTS_CHAT': 'hangoutsChatOptions',
40515
+ 'MAIL': 'mailOptions',
40482
40516
  'VOICE': 'voiceOptions',
40483
40517
  }
40484
40518
  VAULT_CORPUS_QUERY_MAP = {
40485
40519
  'CALENDAR': None,
40486
40520
  'DRIVE': 'driveQuery',
40487
- 'MAIL': 'mailQuery',
40521
+ 'GEMINI': None,
40488
40522
  'GROUPS': 'groupsQuery',
40523
+ 'MAIL': 'mailQuery',
40489
40524
  'HANGOUTS_CHAT': 'hangoutsChatQuery',
40490
40525
  'VOICE': 'voiceQuery',
40491
40526
  }
@@ -40494,11 +40529,11 @@ VAULT_QUERY_ARGS = [
40494
40529
  # calendar
40495
40530
  'locationquery', 'peoplequery', 'minuswords', 'responsestatuses', 'caldendarversiondate',
40496
40531
  # drive
40497
- 'driveversiondate', 'includeshareddrives', 'includeteamdrives',
40532
+ 'driveclientsideencryption', 'driveversiondate', 'includeshareddrives', 'includeteamdrives',
40498
40533
  # hangoutsChat
40499
40534
  'includerooms',
40500
40535
  # mail
40501
- 'excludedrafts',
40536
+ 'mailclientsideencryption', 'excludedrafts',
40502
40537
  # voice
40503
40538
  'covereddata',
40504
40539
  ] + list(VAULT_SEARCH_METHODS_MAP.keys())
@@ -40555,12 +40590,16 @@ def _buildVaultQuery(myarg, query, corpusArgumentMap):
40555
40590
  query.setdefault('driveOptions', {})['versionDate'] = getTimeOrDeltaFromNow()
40556
40591
  elif myarg in {'includeshareddrives', 'includeteamdrives'}:
40557
40592
  query.setdefault('driveOptions', {})['includeSharedDrives'] = getBoolean()
40593
+ elif myarg == 'driveclientsideencryption':
40594
+ query.setdefault('driveOptions', {})['clientSideEncryptedOption'] = getChoice(VAULT_CSE_OPTION_MAP, mapChoice=True)
40558
40595
  # hangoutsChat
40559
40596
  elif myarg == 'includerooms':
40560
40597
  query['hangoutsChatOptions'] = {'includeRooms': getBoolean()}
40561
40598
  # mail
40562
40599
  elif myarg == 'excludedrafts':
40563
40600
  query['mailOptions'] = {'excludeDrafts': getBoolean()}
40601
+ elif myarg == 'mailclientsideencryption':
40602
+ query.setdefault('mailOptions', {})['clientSideEncryptedOption'] = getChoice(VAULT_CSE_OPTION_MAP, mapChoice=True)
40564
40603
  # voice
40565
40604
  elif myarg == 'covereddata':
40566
40605
  query['voiceOptions'] = {'coveredData': getChoice(VAULT_VOICE_COVERED_DATA_MAP, mapChoice=True)}
@@ -40575,7 +40614,7 @@ def _validateVaultQuery(body, corpusArgumentMap):
40575
40614
  if body['query']['corpus'] != corpus:
40576
40615
  body['exportOptions'].pop(options, None)
40577
40616
 
40578
- # gam create vaultexport|export matter <MatterItem> [name <String>] corpus calendar|drive|mail|groups|hangouts_chat|voice
40617
+ # gam create vaultexport|export matter <MatterItem> [name <String>] corpus calendar|drive|gemini|groups|hangouts_chat|mail|voice
40579
40618
  # (accounts <EmailAddressEntity>) | (orgunit|org|ou <OrgUnitPath>) | everyone
40580
40619
  # (shareddrives|teamdrives <TeamDriveIDList>) | (rooms <RoomList>) | (sitesurl <URLList>)
40581
40620
  # [scope <all_data|held_data|unprocessed_data>]
@@ -40583,10 +40622,12 @@ def _validateVaultQuery(body, corpusArgumentMap):
40583
40622
  # [locationquery <StringList>] [peoplequery <StringList>] [minuswords <StringList>]
40584
40623
  # [responsestatuses <AttendeeStatus>(,<AttendeeStatus>)*] [calendarversiondate <Date>|<Time>]
40585
40624
  # [includeshareddrives <Boolean>] [driveversiondate <Date>|<Time>] [includeaccessinfo <Boolean>]
40625
+ # [driveclientsideencryption any|encrypted|unencrypted]
40586
40626
  # [includerooms <Boolean>]
40587
- # [excludedrafts <Boolean>] [format mbox|pst]
40627
+ # [excludedrafts <Boolean>] [mailclientsideencryption any|encrypted|unencrypted]
40588
40628
  # [showconfidentialmodecontent <Boolean>] [usenewexport <Boolean>] [exportlinkeddrivefiles <Boolean>]
40589
40629
  # [covereddata calllogs|textmessages|voicemails]
40630
+ # [format ics|mbox|pst|xml]
40590
40631
  # [region any|europe|us] [showdetails|returnidonly]
40591
40632
  def doCreateVaultExport():
40592
40633
  v = buildGAPIObject(API.VAULT)
@@ -48246,7 +48287,7 @@ def doPrintCourseTopics():
48246
48287
  jcount = len(courseTopicIds)
48247
48288
  if jcount == 0:
48248
48289
  continue
48249
- fields = f'{",".join(set(fieldsList))}'
48290
+ fields = getFieldsFromFieldsList(fieldsList)
48250
48291
  j = 0
48251
48292
  for courseTopicId in courseTopicIds:
48252
48293
  j += 1
@@ -48481,7 +48522,7 @@ def doPrintCourseWM(entityIDType, entityStateType):
48481
48522
  jcount = len(courseWMIds)
48482
48523
  if jcount == 0:
48483
48524
  continue
48484
- fields = f'{",".join(set(fieldsList))}' if fieldsList else None
48525
+ fields = getFieldsFromFieldsList(fieldsList)
48485
48526
  j = 0
48486
48527
  for courseWMId in courseWMIds:
48487
48528
  j += 1
@@ -65501,7 +65542,7 @@ def infoSharedDrive(users, useDomainAdminAccess=False):
65501
65542
  guiRoles = getBoolean()
65502
65543
  else:
65503
65544
  FJQC.GetFormatJSON(myarg)
65504
- fields = ','.join(set(fieldsList)) if fieldsList else '*'
65545
+ fields = getFieldsFromFieldsList(fieldsList) if fieldsList else '*'
65505
65546
  i, count, users = getEntityArgument(users)
65506
65547
  for user in users:
65507
65548
  i += 1
@@ -924,6 +924,7 @@ class GamCLArgs():
924
924
  OB_EXPORT_ITEM = 'ExportItem'
925
925
  OB_FIELD_NAME = 'FieldName'
926
926
  OB_FIELD_NAME_LIST = "FieldNameList"
927
+ OB_FIELDS = 'Fields'
927
928
  OB_FILE_NAME = 'FileName'
928
929
  OB_FILE_NAME_FIELD_NAME = OB_FILE_NAME+'(:'+OB_FIELD_NAME+')+'
929
930
  OB_FILE_NAME_OR_URL = 'FileName|URL'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes