gam7 7.21.3__py3-none-any.whl → 7.22.2__py3-none-any.whl

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.

Potentially problematic release.


This version of gam7 might be problematic. Click here for more details.

gam/__init__.py CHANGED
@@ -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.21.03'
28
+ __version__ = '7.22.02'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -969,14 +969,14 @@ SUSPENDED_CHOICE_MAP = {'notsuspended': False, 'suspended': True}
969
969
  def _getIsSuspended(myarg):
970
970
  if myarg in SUSPENDED_CHOICE_MAP:
971
971
  return SUSPENDED_CHOICE_MAP[myarg]
972
- return getBoolean()
972
+ return getBoolean() #issuspended
973
973
 
974
974
  ARCHIVED_ARGUMENTS = {'notarchived', 'archived', 'isarchived'}
975
975
  ARCHIVED_CHOICE_MAP = {'notarchived': False, 'archived': True}
976
976
  def _getIsArchived(myarg):
977
977
  if myarg in ARCHIVED_CHOICE_MAP:
978
978
  return ARCHIVED_CHOICE_MAP[myarg]
979
- return getBoolean()
979
+ return getBoolean() #isarchived
980
980
 
981
981
  def _getOptionalIsSuspendedIsArchived():
982
982
  isSuspended = isArchived = None
@@ -1549,10 +1549,12 @@ def getOrderBySortOrder(choiceMap, defaultSortOrderChoice='ASCENDING', mapSortOr
1549
1549
  return (getChoice(choiceMap, mapChoice=True),
1550
1550
  getChoice(SORTORDER_CHOICE_MAP, defaultChoice=defaultSortOrderChoice, mapChoice=mapSortOrderChoice))
1551
1551
 
1552
- def orgUnitPathQuery(path, isSuspended):
1552
+ def orgUnitPathQuery(path, isSuspended, isArchived):
1553
1553
  query = "orgUnitPath='{0}'".format(path.replace("'", "\\'")) if path != '/' else ''
1554
1554
  if isSuspended is not None:
1555
1555
  query += f' isSuspended={isSuspended}'
1556
+ if isArchived is not None:
1557
+ query += f' isArchived={isArchived}'
1556
1558
  return query
1557
1559
 
1558
1560
  def makeOrgUnitPathAbsolute(path):
@@ -6247,63 +6249,77 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6247
6249
  _showInvalidEntity(Ent.USER, user)
6248
6250
  if GC.Values[GC.USER_SERVICE_ACCOUNT_ACCESS_ONLY]:
6249
6251
  return entityList
6250
- elif entityType in {Cmd.ENTITY_ALL_USERS, Cmd.ENTITY_ALL_USERS_NS, Cmd.ENTITY_ALL_USERS_NS_SUSP, Cmd.ENTITY_ALL_USERS_SUSP}:
6252
+ elif entityType in Cmd.ALL_USER_ENTITY_TYPES:
6251
6253
  cd = buildGAPIObject(API.DIRECTORY)
6252
- if entityType == Cmd.ENTITY_ALL_USERS and isSuspended is not None:
6253
- query = f'isSuspended={isSuspended}'
6254
+ if entityType == Cmd.ENTITY_ALL_USERS and ((isSuspended is not None) or (isArchived is not None)):
6255
+ if isSuspended is not None:
6256
+ query = f'isSuspended={isSuspended}'
6257
+ if isArchived is not None:
6258
+ query += f' isArchived={isArchived}'
6259
+ else:
6260
+ query = f'isArchived={isArchived}'
6254
6261
  else:
6255
6262
  query = Cmd.ALL_USERS_QUERY_MAP[entityType]
6256
- printGettingAllAccountEntities(Ent.USER)
6263
+ printGettingAllAccountEntities(Ent.USER, query=query)
6257
6264
  try:
6258
6265
  result = callGAPIpages(cd.users(), 'list', 'users',
6259
6266
  pageMessage=getPageMessage(),
6260
6267
  throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
6261
6268
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
6262
- customer=GC.Values[GC.CUSTOMER_ID],
6263
- query=query, orderBy='email', fields='nextPageToken,users(primaryEmail,archived)',
6269
+ customer=GC.Values[GC.CUSTOMER_ID], query=query, orderBy='email',
6270
+ fields='nextPageToken,users(primaryEmail)',
6264
6271
  maxResults=GC.Values[GC.USER_MAX_RESULTS])
6265
6272
  except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
6266
6273
  accessErrorExit(cd)
6267
- entityList = [user['primaryEmail'] for user in result if isArchived is None or isArchived == user['archived']]
6268
- printGotAccountEntities(len(entityList))
6269
- elif entityType in {Cmd.ENTITY_DOMAINS, Cmd.ENTITY_DOMAINS_NS, Cmd.ENTITY_DOMAINS_SUSP}:
6270
- if entityType == Cmd.ENTITY_DOMAINS_NS:
6271
- query = 'isSuspended=False'
6272
- elif entityType == Cmd.ENTITY_DOMAINS_SUSP:
6273
- query = 'isSuspended=True'
6274
- elif isSuspended is not None:
6275
- query = f'isSuspended={isSuspended}'
6274
+ entityList = [user['primaryEmail'] for user in result]
6275
+ elif entityType == Cmd.ENTITY_ALL_USERS_ARCH_OR_SUSP:
6276
+ cd = buildGAPIObject(API.DIRECTORY)
6277
+ for query in ['isSuspended=True', 'isArchived=True']:
6278
+ printGettingAllAccountEntities(Ent.USER, query)
6279
+ try:
6280
+ result = callGAPIpages(cd.users(), 'list', 'users',
6281
+ pageMessage=getPageMessage(),
6282
+ throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
6283
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
6284
+ customer=GC.Values[GC.CUSTOMER_ID], query=query, orderBy='email',
6285
+ fields='nextPageToken,users(primaryEmail)',
6286
+ maxResults=GC.Values[GC.USER_MAX_RESULTS])
6287
+ except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.forbidden):
6288
+ accessErrorExit(cd)
6289
+ entitySet |= {user['primaryEmail'] for user in result}
6290
+ entityList = sorted(list(entitySet))
6291
+ elif entityType in Cmd.DOMAIN_ENTITY_TYPES:
6292
+ if entityType == Cmd.ENTITY_DOMAINS and ((isSuspended is not None) or (isArchived is not None)):
6293
+ if isSuspended is not None:
6294
+ query = f'isSuspended={isSuspended}'
6295
+ if isArchived is not None:
6296
+ query += f' isArchived={isArchived}'
6297
+ else:
6298
+ query = f'isArchived={isArchived}'
6276
6299
  else:
6277
- query = None
6300
+ query = Cmd.DOMAINS_QUERY_MAP[entityType]
6278
6301
  cd = buildGAPIObject(API.DIRECTORY)
6279
6302
  domains = convertEntityToList(entity)
6280
6303
  for domain in domains:
6281
- printGettingAllEntityItemsForWhom(Ent.USER, domain, entityType=Ent.DOMAIN)
6304
+ printGettingAllEntityItemsForWhom(Ent.USER, domain, query=query, entityType=Ent.DOMAIN)
6282
6305
  try:
6283
6306
  result = callGAPIpages(cd.users(), 'list', 'users',
6284
6307
  pageMessage=getPageMessageForWhom(),
6285
6308
  throwReasons=[GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.DOMAIN_NOT_FOUND, GAPI.FORBIDDEN],
6286
6309
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
6287
- domain=domain,
6288
- query=query, orderBy='email', fields='nextPageToken,users(primaryEmail,archived)',
6310
+ domain=domain, query=query, orderBy='email',
6311
+ fields='nextPageToken,users(primaryEmail)',
6289
6312
  maxResults=GC.Values[GC.USER_MAX_RESULTS])
6290
6313
  except (GAPI.badRequest, GAPI.resourceNotFound, GAPI.domainNotFound, GAPI.forbidden):
6291
6314
  checkEntityDNEorAccessErrorExit(cd, Ent.DOMAIN, domain)
6292
6315
  _incrEntityDoesNotExist(Ent.DOMAIN)
6293
6316
  continue
6294
- entityList = [user['primaryEmail'] for user in result if isArchived is None or isArchived == user['archived']]
6295
- printGotAccountEntities(len(entityList))
6296
- elif entityType in {Cmd.ENTITY_GROUP, Cmd.ENTITY_GROUPS,
6297
- Cmd.ENTITY_GROUP_NS, Cmd.ENTITY_GROUPS_NS,
6298
- Cmd.ENTITY_GROUP_SUSP, Cmd.ENTITY_GROUPS_SUSP,
6299
- Cmd.ENTITY_GROUP_INDE, Cmd.ENTITY_GROUPS_INDE}:
6300
- if entityType in {Cmd.ENTITY_GROUP_NS, Cmd.ENTITY_GROUPS_NS}:
6301
- isSuspended = False
6302
- elif entityType in {Cmd.ENTITY_GROUP_SUSP, Cmd.ENTITY_GROUPS_SUSP}:
6303
- isSuspended = True
6317
+ entityList.extend([user['primaryEmail'] for user in result])
6318
+ elif entityType in Cmd.GROUP_ENTITY_TYPES or entityType in Cmd.GROUPS_ENTITY_TYPES:
6319
+ isArchived, isSuspended = Cmd.GROUPS_QUERY_MAP.get(entityType, (isArchived, isSuspended))
6304
6320
  includeDerivedMembership = entityType in {Cmd.ENTITY_GROUP_INDE, Cmd.ENTITY_GROUPS_INDE}
6305
6321
  cd = buildGAPIObject(API.DIRECTORY)
6306
- groups = convertEntityToList(entity, nonListEntityType=entityType in {Cmd.ENTITY_GROUP, Cmd.ENTITY_GROUP_NS, Cmd.ENTITY_GROUP_SUSP, Cmd.ENTITY_GROUP_INDE})
6322
+ groups = convertEntityToList(entity, nonListEntityType=entityType in Cmd.GROUP_ENTITY_TYPES)
6307
6323
  for group in groups:
6308
6324
  if validateEmailAddressOrUID(group, checkPeople=False):
6309
6325
  group = normalizeEmailAddressOrUID(group)
@@ -6329,11 +6345,8 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6329
6345
  entityList.append(email)
6330
6346
  else:
6331
6347
  _showInvalidEntity(Ent.GROUP, group)
6332
- elif entityType in {Cmd.ENTITY_GROUP_USERS, Cmd.ENTITY_GROUP_USERS_NS, Cmd.ENTITY_GROUP_USERS_SUSP, Cmd.ENTITY_GROUP_USERS_SELECT}:
6333
- if entityType == Cmd.ENTITY_GROUP_USERS_NS:
6334
- isSuspended = False
6335
- elif entityType == Cmd.ENTITY_GROUP_USERS_SUSP:
6336
- isSuspended = True
6348
+ elif entityType in Cmd.GROUP_USERS_ENTITY_TYPES:
6349
+ isArchived, isSuspended = Cmd.GROUP_USERS_QUERY_MAP.get(entityType, (isArchived, isSuspended))
6337
6350
  cd = buildGAPIObject(API.DIRECTORY)
6338
6351
  groups = convertEntityToList(entity)
6339
6352
  includeDerivedMembership = False
@@ -6424,21 +6437,13 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6424
6437
  _addCIGroupUsersToUsers(name, groupEmail, recursive)
6425
6438
  else:
6426
6439
  _showInvalidEntity(Ent.GROUP, group)
6427
- elif entityType in {Cmd.ENTITY_OU, Cmd.ENTITY_OUS, Cmd.ENTITY_OU_AND_CHILDREN, Cmd.ENTITY_OUS_AND_CHILDREN,
6428
- Cmd.ENTITY_OU_NS, Cmd.ENTITY_OUS_NS, Cmd.ENTITY_OU_AND_CHILDREN_NS, Cmd.ENTITY_OUS_AND_CHILDREN_NS,
6429
- Cmd.ENTITY_OU_SUSP, Cmd.ENTITY_OUS_SUSP, Cmd.ENTITY_OU_AND_CHILDREN_SUSP, Cmd.ENTITY_OUS_AND_CHILDREN_SUSP}:
6430
- if entityType in {Cmd.ENTITY_OU_NS, Cmd.ENTITY_OUS_NS, Cmd.ENTITY_OU_AND_CHILDREN_NS, Cmd.ENTITY_OUS_AND_CHILDREN_NS}:
6431
- isSuspended = False
6432
- elif entityType in {Cmd.ENTITY_OU_SUSP, Cmd.ENTITY_OUS_SUSP, Cmd.ENTITY_OU_AND_CHILDREN_SUSP, Cmd.ENTITY_OUS_AND_CHILDREN_SUSP}:
6433
- isSuspended = True
6440
+ elif entityType in Cmd.OU_ENTITY_TYPES or entityType in Cmd.OUS_ENTITY_TYPES:
6441
+ isArchived, isSuspended = Cmd.OU_QUERY_MAP.get(entityType, (isArchived, isSuspended))
6434
6442
  cd = buildGAPIObject(API.DIRECTORY)
6435
- ous = convertEntityToList(entity, shlexSplit=True, nonListEntityType=entityType in {Cmd.ENTITY_OU, Cmd.ENTITY_OU_AND_CHILDREN,
6436
- Cmd.ENTITY_OU_NS, Cmd.ENTITY_OU_AND_CHILDREN_NS,
6437
- Cmd.ENTITY_OU_SUSP, Cmd.ENTITY_OU_AND_CHILDREN_SUSP})
6438
- directlyInOU = entityType in {Cmd.ENTITY_OU, Cmd.ENTITY_OUS, Cmd.ENTITY_OU_NS, Cmd.ENTITY_OUS_NS, Cmd.ENTITY_OU_SUSP, Cmd.ENTITY_OUS_SUSP}
6443
+ ous = convertEntityToList(entity, shlexSplit=True, nonListEntityType=entityType in Cmd.OU_ENTITY_TYPES)
6444
+ directlyInOU = entityType in Cmd.OU_DIRECT_ENTITY_TYPES
6439
6445
  qualifier = Msg.DIRECTLY_IN_THE.format(Ent.Singular(Ent.ORGANIZATIONAL_UNIT)) if directlyInOU else Msg.IN_THE.format(Ent.Singular(Ent.ORGANIZATIONAL_UNIT))
6440
- fields = 'nextPageToken,users(primaryEmail,orgUnitPath,archived)' if directlyInOU else 'nextPageToken,users(primaryEmail,archived)'
6441
- prevLen = 0
6446
+ fields = 'nextPageToken,users(primaryEmail,orgUnitPath)' if directlyInOU else 'nextPageToken,users(primaryEmail)'
6442
6447
  for ou in ous:
6443
6448
  ou = makeOrgUnitPathAbsolute(ou)
6444
6449
  if ou.startswith('id:'):
@@ -6463,22 +6468,17 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6463
6468
  throwReasons=[GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND,
6464
6469
  GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
6465
6470
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
6466
- customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(ou, isSuspended), orderBy='email',
6471
+ customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(ou, isSuspended, isArchived), orderBy='email',
6467
6472
  fields=fields, maxResults=GC.Values[GC.USER_MAX_RESULTS])
6468
6473
  for users in feed:
6469
6474
  if directlyInOU:
6470
6475
  for user in users:
6471
- if ouLower == user.get('orgUnitPath', '').lower() and (isArchived is None or isArchived == user['archived']):
6476
+ if ouLower == user.get('orgUnitPath', '').lower():
6472
6477
  usersInOU += 1
6473
6478
  entityList.append(user['primaryEmail'])
6474
- elif isArchived is None:
6479
+ else:
6475
6480
  entityList.extend([user['primaryEmail'] for user in users])
6476
6481
  usersInOU += len(users)
6477
- else:
6478
- for user in users:
6479
- if isArchived == user['archived']:
6480
- usersInOU += 1
6481
- entityList.append(user['primaryEmail'])
6482
6482
  setGettingAllEntityItemsForWhom(Ent.USER, ou, qualifier=qualifier)
6483
6483
  printGotEntityItemsForWhom(usersInOU)
6484
6484
  except (GAPI.invalidInput, GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError, GAPI.badRequest,
@@ -6488,7 +6488,6 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6488
6488
  elif entityType in {Cmd.ENTITY_QUERY, Cmd.ENTITY_QUERIES}:
6489
6489
  cd = buildGAPIObject(API.DIRECTORY)
6490
6490
  queries = convertEntityToList(entity, shlexSplit=True, nonListEntityType=entityType == Cmd.ENTITY_QUERY)
6491
- prevLen = 0
6492
6491
  for query in queries:
6493
6492
  printGettingAllAccountEntities(Ent.USER, query)
6494
6493
  try:
@@ -6512,9 +6511,6 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6512
6511
  email not in entitySet):
6513
6512
  entitySet.add(email)
6514
6513
  entityList.append(email)
6515
- totalLen = len(entityList)
6516
- printGotAccountEntities(totalLen-prevLen)
6517
- prevLen = totalLen
6518
6514
  elif entityType == Cmd.ENTITY_LICENSES:
6519
6515
  skusList = []
6520
6516
  for item in entity.split(','):
@@ -6573,8 +6569,7 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6573
6569
  ClientAPIAccessDeniedExit(str(e))
6574
6570
  elif entityType == Cmd.ENTITY_CROS:
6575
6571
  buildGAPIObject(API.DIRECTORY)
6576
- result = convertEntityToList(entity)
6577
- for deviceId in result:
6572
+ for deviceId in convertEntityToList(entity):
6578
6573
  if deviceId not in entitySet:
6579
6574
  entitySet.add(deviceId)
6580
6575
  entityList.append(deviceId)
@@ -6598,7 +6593,6 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6598
6593
  nonListEntityType=entityType == Cmd.ENTITY_CROS_QUERY)
6599
6594
  if entityType == Cmd.ENTITY_CROS_SN:
6600
6595
  queries = [f'id:{query}' for query in queries]
6601
- prevLen = 0
6602
6596
  for query in queries:
6603
6597
  printGettingAllAccountEntities(Ent.CROS_DEVICE, query)
6604
6598
  try:
@@ -6619,25 +6613,15 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6619
6613
  if deviceId not in entitySet:
6620
6614
  entitySet.add(deviceId)
6621
6615
  entityList.append(deviceId)
6622
- totalLen = len(entityList)
6623
- printGotAccountEntities(totalLen-prevLen)
6624
- prevLen = totalLen
6625
- elif entityType in {Cmd.ENTITY_CROS_OU, Cmd.ENTITY_CROS_OU_AND_CHILDREN, Cmd.ENTITY_CROS_OUS, Cmd.ENTITY_CROS_OUS_AND_CHILDREN,
6626
- Cmd.ENTITY_CROS_OU_QUERY, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERY, Cmd.ENTITY_CROS_OUS_QUERY, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERY,
6627
- Cmd.ENTITY_CROS_OU_QUERIES, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERIES, Cmd.ENTITY_CROS_OUS_QUERIES, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERIES}:
6616
+ elif entityType in Cmd.CROS_OU_ENTITY_TYPES or entityType in Cmd.CROS_OUS_ENTITY_TYPES:
6628
6617
  cd = buildGAPIObject(API.DIRECTORY)
6629
- ous = convertEntityToList(entity, shlexSplit=True,
6630
- nonListEntityType=entityType in {Cmd.ENTITY_CROS_OU, Cmd.ENTITY_CROS_OU_AND_CHILDREN,
6631
- Cmd.ENTITY_CROS_OU_QUERY, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERY,
6632
- Cmd.ENTITY_CROS_OU_QUERIES, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERIES})
6618
+ ous = convertEntityToList(entity, shlexSplit=True, nonListEntityType=entityType in Cmd.CROS_OU_ENTITY_TYPES)
6633
6619
  numOus = len(ous)
6634
- includeChildOrgunits = entityType in {Cmd.ENTITY_CROS_OU_AND_CHILDREN, Cmd.ENTITY_CROS_OUS_AND_CHILDREN,
6635
- Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERY, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERY,
6636
- Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERIES, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERIES}
6620
+ includeChildOrgunits = entityType in Cmd.CROS_OU_CHILDREN_ENTITY_TYPES
6637
6621
  allQualifier = Msg.DIRECTLY_IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus)) if not includeChildOrgunits else Msg.IN_THE.format(Ent.Choose(Ent.ORGANIZATIONAL_UNIT, numOus))
6638
- if entityType in {Cmd.ENTITY_CROS_OU_QUERY, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERY, Cmd.ENTITY_CROS_OUS_QUERY, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERY}:
6622
+ if entityType in Cmd.CROS_OU_QUERY_ENTITY_TYPES:
6639
6623
  queries = getQueries('query')
6640
- elif entityType in {Cmd.ENTITY_CROS_OU_QUERIES, Cmd.ENTITY_CROS_OU_AND_CHILDREN_QUERIES, Cmd.ENTITY_CROS_OUS_QUERIES, Cmd.ENTITY_CROS_OUS_AND_CHILDREN_QUERIES}:
6624
+ elif entityType in Cmd.CROS_OU_QUERIES_ENTITY_TYPES:
6641
6625
  queries = getQueries('queries')
6642
6626
  else:
6643
6627
  queries = [None]
@@ -6710,7 +6694,6 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6710
6694
  customerId = _getCustomerIdNoC()
6711
6695
  queries = convertEntityToList(entity, shlexSplit=entityType == Cmd.ENTITY_BROWSER_QUERIES,
6712
6696
  nonListEntityType=entityType == Cmd.ENTITY_BROWSER_QUERY)
6713
- prevLen = 0
6714
6697
  for query in queries:
6715
6698
  printGettingAllAccountEntities(Ent.CHROME_BROWSER, query)
6716
6699
  try:
@@ -6730,9 +6713,6 @@ def getItemsToModify(entityType, entity, memberRoles=None, isSuspended=None, isA
6730
6713
  if deviceId not in entitySet:
6731
6714
  entitySet.add(deviceId)
6732
6715
  entityList.append(deviceId)
6733
- totalLen = len(entityList)
6734
- printGotAccountEntities(totalLen-prevLen)
6735
- prevLen = totalLen
6736
6716
  else:
6737
6717
  systemErrorExit(UNKNOWN_ERROR_RC, 'getItemsToModify coding error')
6738
6718
  for errorType in [ENTITY_ERROR_DNE, ENTITY_ERROR_INVALID]:
@@ -7045,10 +7025,7 @@ def getEntityToModify(defaultEntityType=None, browserAllowed=False, crosAllowed=
7045
7025
  choices += Cmd.CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES
7046
7026
  entityType = mapEntityType(getChoice(choices), typeMap)
7047
7027
  return (Cmd.ENTITY_USERS if entityType not in Cmd.CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES else Cmd.ENTITY_CROS,
7048
- getItemsToModify(entityType, getEntitiesFromFile(shlexSplit=entityType in [Cmd.ENTITY_OUS, Cmd.ENTITY_OUS_AND_CHILDREN,
7049
- Cmd.ENTITY_OUS_NS, Cmd.ENTITY_OUS_AND_CHILDREN_NS,
7050
- Cmd.ENTITY_OUS_SUSP, Cmd.ENTITY_OUS_AND_CHILDREN_SUSP,
7051
- Cmd.ENTITY_CROS_OUS, Cmd.ENTITY_CROS_OUS_AND_CHILDREN])))
7028
+ getItemsToModify(entityType, getEntitiesFromFile(shlexSplit=entityType in Cmd.OUS_ENTITY_TYPES | {Cmd.ENTITY_CROS_OUS, Cmd.ENTITY_CROS_OUS_AND_CHILDREN})))
7052
7029
  if entitySelector == Cmd.ENTITY_SELECTOR_CSVDATAFILE:
7053
7030
  if userAllowed:
7054
7031
  choices += Cmd.USER_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES if not GC.Values[GC.USER_SERVICE_ACCOUNT_ACCESS_ONLY] else [Cmd.ENTITY_USERS]
@@ -7056,10 +7033,7 @@ def getEntityToModify(defaultEntityType=None, browserAllowed=False, crosAllowed=
7056
7033
  choices += Cmd.CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES
7057
7034
  entityType = mapEntityType(getChoice(choices), typeMap)
7058
7035
  return (Cmd.ENTITY_USERS if entityType not in Cmd.CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES else Cmd.ENTITY_CROS,
7059
- getItemsToModify(entityType, getEntitiesFromCSVFile(shlexSplit=entityType in [Cmd.ENTITY_OUS, Cmd.ENTITY_OUS_AND_CHILDREN,
7060
- Cmd.ENTITY_OUS_NS, Cmd.ENTITY_OUS_AND_CHILDREN_NS,
7061
- Cmd.ENTITY_OUS_SUSP, Cmd.ENTITY_OUS_AND_CHILDREN_SUSP,
7062
- Cmd.ENTITY_CROS_OUS, Cmd.ENTITY_CROS_OUS_AND_CHILDREN])))
7036
+ getItemsToModify(entityType, getEntitiesFromCSVFile(shlexSplit=entityType in Cmd.OUS_ENTITY_TYPES | {Cmd.ENTITY_CROS_OUS, Cmd.ENTITY_CROS_OUS_AND_CHILDREN})))
7063
7037
  if entitySelector == Cmd.ENTITY_SELECTOR_CSVKMD:
7064
7038
  if userAllowed:
7065
7039
  choices += Cmd.USER_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES if not GC.Values[GC.USER_SERVICE_ACCOUNT_ACCESS_ONLY] else [Cmd.ENTITY_USERS]
@@ -7102,10 +7076,7 @@ def getEntityToModify(defaultEntityType=None, browserAllowed=False, crosAllowed=
7102
7076
  if not GC.Values[GC.USER_SERVICE_ACCOUNT_ACCESS_ONLY]:
7103
7077
  buildGAPIObject(API.DIRECTORY)
7104
7078
  if entityClass == Cmd.ENTITY_USERS:
7105
- if entityType in [Cmd.ENTITY_GROUP_USERS,
7106
- Cmd.ENTITY_GROUP_USERS_NS, Cmd.ENTITY_GROUP_USERS_SUSP,
7107
- Cmd.ENTITY_GROUP_USERS_SELECT,
7108
- Cmd.ENTITY_CIGROUP_USERS]:
7079
+ if entityType in Cmd.GROUP_USERS_ENTITY_TYPES | {Cmd.ENTITY_CIGROUP_USERS}:
7109
7080
  # Skip over sub-arguments
7110
7081
  while Cmd.ArgumentsRemaining():
7111
7082
  myarg = getArgument()
@@ -10149,8 +10120,8 @@ def threadBatchWorker(showCmds=False, numItems=0):
10149
10120
  batchWriteStderr(f'{currentISOformatTimeStamp()},{pid}/{numItems},Error,{str(e)},{logCmd}\n')
10150
10121
  GM.Globals[GM.TBATCH_QUEUE].task_done()
10151
10122
 
10152
- BATCH_COMMANDS = [Cmd.GAM_CMD, Cmd.COMMIT_BATCH_CMD, Cmd.PRINT_CMD, Cmd.SLEEP_CMD]
10153
- TBATCH_COMMANDS = [Cmd.GAM_CMD, Cmd.COMMIT_BATCH_CMD, Cmd.EXECUTE_CMD, Cmd.PRINT_CMD, Cmd.SLEEP_CMD]
10123
+ BATCH_COMMANDS = [Cmd.GAM_CMD, Cmd.COMMIT_BATCH_CMD, Cmd.PRINT_CMD, Cmd.SLEEP_CMD, Cmd.DATETIME_CMD, Cmd.SET_CMD, Cmd.CLEAR_CMD]
10124
+ TBATCH_COMMANDS = [Cmd.GAM_CMD, Cmd.COMMIT_BATCH_CMD, Cmd.EXECUTE_CMD, Cmd.PRINT_CMD, Cmd.SLEEP_CMD, Cmd.DATETIME_CMD, Cmd.SET_CMD, Cmd.CLEAR_CMD]
10154
10125
 
10155
10126
  def ThreadBatchGAMCommands(items, showCmds):
10156
10127
  if not items:
@@ -10262,6 +10233,14 @@ def doBatch(threadBatch=False):
10262
10233
  continue
10263
10234
  if argv:
10264
10235
  cmd = argv[0].strip().lower()
10236
+ if cmd == Cmd.DATETIME_CMD:
10237
+ if len(argv) == 2:
10238
+ kwValues['datetime'] = todaysTime().strftime(argv[1])
10239
+ else:
10240
+ writeStderr(f'Command: >>>{Cmd.QuotedArgumentList([argv[0]])}<<< {Cmd.QuotedArgumentList(argv[1:])}\n')
10241
+ writeStderr(f'{ERROR_PREFIX}{Cmd.ARGUMENT_ERROR_NAMES[Cmd.ARGUMENT_INVALID][1]}: {Msg.EXPECTED} <{Cmd.DATETIME_CMD} DateTimeFormat>)>\n')
10242
+ errors += 1
10243
+ continue
10265
10244
  if cmd == Cmd.SET_CMD:
10266
10245
  if len(argv) == 3:
10267
10246
  kwValues[argv[1]] = argv[2]
@@ -13353,7 +13332,7 @@ def getUserOrgUnits(cd, orgUnit, orgUnitId):
13353
13332
  throwReasons=[GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND,
13354
13333
  GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
13355
13334
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
13356
- customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnit, None), orderBy='email',
13335
+ customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnit, None, None), orderBy='email',
13357
13336
  fields='nextPageToken,users(primaryEmail,orgUnitPath)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
13358
13337
  userOrgUnits = {}
13359
13338
  for user in result:
@@ -17848,10 +17827,29 @@ ORG_FIELD_INFO_ORDER = ['orgUnitId', 'name', 'description', 'parentOrgUnitPath',
17848
17827
  ORG_FIELDS_WITH_CRS_NLS = {'description'}
17849
17828
 
17850
17829
  def _doInfoOrgs(entityList):
17830
+ def _printUsers(entityType, orgUnitPath, isSuspended, isArchived):
17831
+ users = callGAPIpages(cd.users(), 'list', 'users',
17832
+ throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
17833
+ retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
17834
+ customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, isSuspended, isArchived), orderBy='email',
17835
+ fields='nextPageToken,users(primaryEmail,orgUnitPath)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
17836
+ printEntitiesCount(entityType, None)
17837
+ usersInOU = 0
17838
+ Ind.Increment()
17839
+ orgUnitPath = orgUnitPath.lower()
17840
+ for user in users:
17841
+ if orgUnitPath == user['orgUnitPath'].lower():
17842
+ printKeyValueList([user['primaryEmail']])
17843
+ usersInOU += 1
17844
+ elif showChildren:
17845
+ printKeyValueList([f'{user["primaryEmail"]} (child)'])
17846
+ usersInOU += 1
17847
+ Ind.Decrement()
17848
+ printKeyValueList([Msg.TOTAL_ITEMS_IN_ENTITY.format(Ent.Plural(entityType), Ent.Singular(Ent.ORGANIZATIONAL_UNIT)), usersInOU])
17849
+
17851
17850
  cd = buildGAPIObject(API.DIRECTORY)
17852
17851
  getUsers = True
17853
- isSuspended = None
17854
- entityType = Ent.USER
17852
+ isSuspended = isArchived = None
17855
17853
  showChildren = False
17856
17854
  while Cmd.ArgumentsRemaining():
17857
17855
  myarg = getArgument()
@@ -17859,7 +17857,8 @@ def _doInfoOrgs(entityList):
17859
17857
  getUsers = False
17860
17858
  elif myarg in SUSPENDED_ARGUMENTS:
17861
17859
  isSuspended = _getIsSuspended(myarg)
17862
- entityType = Ent.USER_SUSPENDED if isSuspended else Ent.USER_NOT_SUSPENDED
17860
+ elif myarg in ARCHIVED_ARGUMENTS:
17861
+ isArchived = _getIsArchived(myarg)
17863
17862
  elif myarg in {'children', 'child'}:
17864
17863
  showChildren = True
17865
17864
  else:
@@ -17890,38 +17889,29 @@ def _doInfoOrgs(entityList):
17890
17889
  printKeyValueWithCRsNLs(field, value)
17891
17890
  if getUsers:
17892
17891
  orgUnitPath = result['orgUnitPath']
17893
- users = callGAPIpages(cd.users(), 'list', 'users',
17894
- throwReasons=[GAPI.BAD_REQUEST, GAPI.INVALID_INPUT, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
17895
- retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
17896
- customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, isSuspended), orderBy='email',
17897
- fields='nextPageToken,users(primaryEmail,orgUnitPath)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
17898
- printEntitiesCount(entityType, None)
17899
- usersInOU = 0
17900
- Ind.Increment()
17901
- orgUnitPath = orgUnitPath.lower()
17902
- for user in users:
17903
- if orgUnitPath == user['orgUnitPath'].lower():
17904
- printKeyValueList([user['primaryEmail']])
17905
- usersInOU += 1
17906
- elif showChildren:
17907
- printKeyValueList([f'{user["primaryEmail"]} (child)'])
17908
- usersInOU += 1
17909
- Ind.Decrement()
17910
- printKeyValueList([Msg.TOTAL_ITEMS_IN_ENTITY.format(Ent.Plural(entityType), Ent.Singular(Ent.ORGANIZATIONAL_UNIT)), usersInOU])
17892
+ if isArchived is None and isSuspended is None:
17893
+ _printUsers(Ent.USER, orgUnitPath, None, None)
17894
+ else:
17895
+ if isArchived is not None:
17896
+ _printUsers(Ent.USER_ARCHIVED if isArchived else Ent.USER_NOT_ARCHIVED, orgUnitPath, None, isArchived)
17897
+ if isSuspended is not None:
17898
+ _printUsers(Ent.USER_SUSPENDED if isSuspended else Ent.USER_NOT_SUSPENDED, orgUnitPath, isSuspended, None)
17911
17899
  Ind.Decrement()
17912
17900
  except (GAPI.invalidInput, GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError):
17913
17901
  entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], Msg.DOES_NOT_EXIST, i, count)
17914
17902
  except (GAPI.badRequest, GAPI.invalidCustomerId, GAPI.loginRequired, GAPI.resourceNotFound, GAPI.forbidden):
17915
17903
  checkEntityAFDNEorAccessErrorExit(cd, Ent.ORGANIZATIONAL_UNIT, orgUnitPath)
17916
17904
 
17917
- # gam info orgs|ous <OrgUnitEntity> [nousers|notsuspended|suspended] [children|child]
17918
- def doInfoOrgs():
17919
- _doInfoOrgs(getEntityList(Cmd.OB_ORGUNIT_ENTITY, shlexSplit=True))
17920
-
17921
- # gam info org|ou <OrgUnitItem> [nousers|notsuspended|suspended] [children|child]
17905
+ # gam info org|ou <OrgUnitItem>
17906
+ # [nousers | ([notarchived|archived] [notsuspended|suspended])] [children|child]
17922
17907
  def doInfoOrg():
17923
17908
  _doInfoOrgs([getOrgUnitItem()])
17924
17909
 
17910
+ # gam info orgs|ous <OrgUnitEntity>
17911
+ # [nousers | ([notarchived|archived] [notsuspended|suspended])] [children|child]
17912
+ def doInfoOrgs():
17913
+ _doInfoOrgs(getEntityList(Cmd.OB_ORGUNIT_ENTITY, shlexSplit=True))
17914
+
17925
17915
  ORG_ARGUMENT_TO_FIELD_MAP = {
17926
17916
  'blockinheritance': 'blockInheritance',
17927
17917
  'inheritanceblocked': 'blockInheritance',
@@ -18151,7 +18141,7 @@ def doPrintOrgs():
18151
18141
  return
18152
18142
  if showUserCounts:
18153
18143
  for orgUnit in orgUnits:
18154
- userCounts[orgUnit['orgUnitPath']] = [0, 0]
18144
+ userCounts[orgUnit['orgUnitPath']] = {'suspended': [0, 0], 'archived': [0, 0], 'total': 0}
18155
18145
  qualifier = Msg.IN_THE.format(Ent.Singular(Ent.ORGANIZATIONAL_UNIT))
18156
18146
  printGettingAllEntityItemsForWhom(Ent.USER, orgUnitPath, qualifier=qualifier, entityType=Ent.ORGANIZATIONAL_UNIT)
18157
18147
  pageMessage = getPageMessageForWhom()
@@ -18161,12 +18151,14 @@ def doPrintOrgs():
18161
18151
  throwReasons=[GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND,
18162
18152
  GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
18163
18153
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
18164
- customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, None), orderBy='email',
18165
- fields='nextPageToken,users(orgUnitPath,suspended)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
18154
+ customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, None, None), orderBy='email',
18155
+ fields='nextPageToken,users(orgUnitPath,suspended,archived)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
18166
18156
  for users in feed:
18167
18157
  for user in users:
18168
18158
  if user['orgUnitPath'] in userCounts:
18169
- userCounts[user['orgUnitPath']][user['suspended']] += 1
18159
+ userCounts[user['orgUnitPath']]['suspended'][user['suspended']] += 1
18160
+ userCounts[user['orgUnitPath']]['archived'][user['archived']] += 1
18161
+ userCounts[user['orgUnitPath']]['total'] += 1
18170
18162
  except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.invalidInput, GAPI.badRequest, GAPI.backendError,
18171
18163
  GAPI.invalidCustomerId, GAPI.loginRequired, GAPI.resourceNotFound, GAPI.forbidden):
18172
18164
  checkEntityDNEorAccessErrorExit(cd, Ent.ORGANIZATIONAL_UNIT, orgUnitPath)
@@ -18233,15 +18225,34 @@ def doPrintOrgs():
18233
18225
  (maxCrOSCounts != -1 and total > maxCrOSCounts)):
18234
18226
  continue
18235
18227
  if showUserCounts:
18236
- row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}NotSuspended'] = userCounts[orgUnitPath][0]
18237
- row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}Suspended'] = userCounts[orgUnitPath][1]
18238
- row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}Total'] = total = userCounts[orgUnitPath][0]+userCounts[orgUnitPath][1]
18228
+ row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}NotArchived'] = userCounts[orgUnitPath]['archived'][0]
18229
+ row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}Archived'] = userCounts[orgUnitPath]['archived'][1]
18230
+ row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}NotSuspended'] = userCounts[orgUnitPath]['suspended'][0]
18231
+ row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}Suspended'] = userCounts[orgUnitPath]['suspended'][1]
18232
+ row[f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}Total'] = total = userCounts[orgUnitPath]['total']
18239
18233
  if ((minUserCounts != -1 and total < minUserCounts) or
18240
18234
  (maxUserCounts != -1 and total > maxUserCounts)):
18241
18235
  continue
18242
18236
  csvPF.WriteRowTitles(row)
18243
18237
  else:
18244
18238
  csvPF.WriteRow(row)
18239
+ if showCrOSCounts or showUserCounts:
18240
+ crosTitles = []
18241
+ userTitles = []
18242
+ allTitles = csvPF.titlesList[:]
18243
+ for title in allTitles:
18244
+ if showCrOSCounts and title.startswith(f'CrOS{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}'):
18245
+ crosTitles.append(title)
18246
+ csvPF.RemoveTitles(title)
18247
+ if showUserCounts and title.startswith(f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}'):
18248
+ userTitles.append(title)
18249
+ csvPF.RemoveTitles(title)
18250
+ if showCrOSCounts:
18251
+ csvPF.AddTitles(sorted(crosTitles))
18252
+ if showUserCounts:
18253
+ for title in ['NotArchived', 'Archived', 'NotSuspended', 'Suspended', 'Total']:
18254
+ csvPF.AddTitles(f'Users{GC.Values[GC.CSV_OUTPUT_SUBFIELD_DELIMITER]}{title}')
18255
+ csvPF.SetSortTitles([])
18245
18256
  csvPF.writeCSVfile('Orgs')
18246
18257
 
18247
18258
  # gam show orgtree [fromparent <OrgUnitItem>] [batchsuborgs [Boolean>]]
@@ -18451,7 +18462,7 @@ def doCheckOrgUnit():
18451
18462
  throwReasons=[GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND,
18452
18463
  GAPI.INVALID_INPUT, GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN],
18453
18464
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
18454
- customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, None),
18465
+ customer=GC.Values[GC.CUSTOMER_ID], query=orgUnitPathQuery(orgUnitPath, None, None),
18455
18466
  fields='nextPageToken,users(orgUnitPath)', maxResults=GC.Values[GC.USER_MAX_RESULTS])
18456
18467
  for users in feed:
18457
18468
  for user in users:
@@ -18872,7 +18883,7 @@ def makeUserGroupDomainQueryFilters(kwargsDict):
18872
18883
  kwargsQueries.append((kwargs, query))
18873
18884
  return kwargsQueries
18874
18885
 
18875
- def userFilters(kwargs, query, orgUnitPath, isSuspended):
18886
+ def userFilters(kwargs, query, orgUnitPath, isSuspended, isArchived):
18876
18887
  queryTitle = ''
18877
18888
  if kwargs.get('domain'):
18878
18889
  queryTitle += f'domain={kwargs["domain"]}, '
@@ -18891,6 +18902,12 @@ def userFilters(kwargs, query, orgUnitPath, isSuspended):
18891
18902
  else:
18892
18903
  query += ' '
18893
18904
  query += f'isSuspended={isSuspended}'
18905
+ if isArchived is not None:
18906
+ if query is None:
18907
+ query = ''
18908
+ else:
18909
+ query += ' '
18910
+ query += f'isArchived={isArchived}'
18894
18911
  if query is not None:
18895
18912
  queryTitle += f'query="{query}", '
18896
18913
  if queryTitle:
@@ -18902,7 +18919,7 @@ def userFilters(kwargs, query, orgUnitPath, isSuspended):
18902
18919
  # [limittoou <OrgUnitItem>])
18903
18920
  # [user|users <EmailAddressList>] [group|groups <EmailAddressList>]
18904
18921
  # [select <UserTypeEntity>]
18905
- # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
18922
+ # [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
18906
18923
  # [shownoneditable] [nogroups] [nousers]
18907
18924
  # [onerowpertarget] [delimiter <Character>]
18908
18925
  # [suppressnoaliasrows]
@@ -18948,7 +18965,7 @@ def doPrintAliases():
18948
18965
  groups = []
18949
18966
  users = []
18950
18967
  aliasMatchPattern = re.compile(r'^.*$')
18951
- isSuspended = orgUnitPath = None
18968
+ isArchived = isSuspended = orgUnitPath = None
18952
18969
  addCSVData = {}
18953
18970
  delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
18954
18971
  while Cmd.ArgumentsRemaining():
@@ -18972,8 +18989,10 @@ def doPrintAliases():
18972
18989
  pass
18973
18990
  elif myarg == 'select':
18974
18991
  _, users = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
18975
- elif myarg == 'issuspended':
18976
- isSuspended = getBoolean()
18992
+ elif myarg in SUSPENDED_ARGUMENTS:
18993
+ isSuspended = _getIsSuspended(myarg)
18994
+ elif myarg in ARCHIVED_ARGUMENTS:
18995
+ isArchived = _getIsArchived(myarg)
18977
18996
  elif myarg in {'user','users'}:
18978
18997
  users.extend(convertEntityToList(getString(Cmd.OB_EMAIL_ADDRESS_LIST, minLen=0)))
18979
18998
  elif myarg in {'group', 'groups'}:
@@ -19008,7 +19027,7 @@ def doPrintAliases():
19008
19027
  for kwargsQuery in makeUserGroupDomainQueryFilters(kwargsDict):
19009
19028
  kwargs = kwargsQuery[0]
19010
19029
  query = kwargsQuery[1]
19011
- query, pquery = userFilters(kwargs, query, orgUnitPath, isSuspended)
19030
+ query, pquery = userFilters(kwargs, query, orgUnitPath, isSuspended, isArchived)
19012
19031
  printGettingAllAccountEntities(Ent.USER, pquery)
19013
19032
  try:
19014
19033
  entityList = callGAPIpages(cd.users(), 'list', 'users',
@@ -45690,7 +45709,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
45690
45709
  # [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
45691
45710
  # [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
45692
45711
  # [convertcrnl]
45693
- # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
45712
+ # [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
45694
45713
  # [showitemcountonly]
45695
45714
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
45696
45715
  #
@@ -45703,7 +45722,7 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
45703
45722
  # [userview] [basic|full|allfields | <UserFieldName>* | fields <UserFieldNameList>]
45704
45723
  # [delimiter <Character>] [sortheaders] [formatjson [quotechar <Character>]] [quoteplusphonenumbers]
45705
45724
  # [convertcrnl]
45706
- # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
45725
+ # [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
45707
45726
  # [showitemcountonly]
45708
45727
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
45709
45728
  #
@@ -45711,13 +45730,13 @@ USERS_INDEXED_TITLES = ['addresses', 'aliases', 'nonEditableAliases', 'emails',
45711
45730
  # ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)]
45712
45731
  # [limittoou <OrgUnitItem>] [deleted_only|only_deleted])|[select <UserTypeEntity>]
45713
45732
  # [formatjson [quotechar <Character>]] [countonly]
45714
- # [issuspended <Boolean>] [aliasmatchpattern <REMatchPattern>]
45733
+ # [issuspended <Boolean>] [isarchived <Boolean>] [aliasmatchpattern <REMatchPattern>]
45715
45734
  # [showitemcountonly]
45716
45735
  # [showvalidcolumn] (addcsvdata <FieldName> <String>)*
45717
45736
  #
45718
45737
  # gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
45719
45738
  # [formatjson [quotechar <Character>]] [countonly]
45720
- # [issuspended <Boolean>]
45739
+ # [issuspended <Boolean>] [isarchived <Boolean>]
45721
45740
  # [showitemcountonly]
45722
45741
  def doPrintUsers(entityList=None):
45723
45742
  def _writeUserEntity(userEntity):
@@ -45873,7 +45892,7 @@ def doPrintUsers(entityList=None):
45873
45892
  schemaParms = _initSchemaParms('basic')
45874
45893
  projectionSet = False
45875
45894
  oneLicensePerRow = quotePlusPhoneNumbers = showDeleted = False
45876
- aliasMatchPattern = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
45895
+ aliasMatchPattern = isArchived = isSuspended = orgUnitPath = orgUnitPathLower = orderBy = sortOrder = None
45877
45896
  viewType = 'admin_view'
45878
45897
  delimiter = GC.Values[GC.CSV_OUTPUT_FIELD_DELIMITER]
45879
45898
  showValidColumn = ''
@@ -45892,8 +45911,10 @@ def doPrintUsers(entityList=None):
45892
45911
  showDeleted = True
45893
45912
  elif entityList is None and myarg == 'select':
45894
45913
  _, entityList = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
45895
- elif myarg == 'issuspended':
45896
- isSuspended = getBoolean()
45914
+ elif myarg in SUSPENDED_ARGUMENTS:
45915
+ isSuspended = _getIsSuspended(myarg)
45916
+ elif myarg in ARCHIVED_ARGUMENTS:
45917
+ isArchived = _getIsArchived(myarg)
45897
45918
  elif myarg == 'orderby':
45898
45919
  orderBy, sortOrder = getOrderBySortOrder(USERS_ORDERBY_CHOICE_MAP)
45899
45920
  elif myarg == 'userview':
@@ -46006,7 +46027,7 @@ def doPrintUsers(entityList=None):
46006
46027
  for kwargsQuery in makeUserGroupDomainQueryFilters(kwargsDict):
46007
46028
  kwargs = kwargsQuery[0]
46008
46029
  query = kwargsQuery[1]
46009
- query, pquery = userFilters(kwargs, query, orgUnitPath, isSuspended)
46030
+ query, pquery = userFilters(kwargs, query, orgUnitPath, isSuspended, isArchived)
46010
46031
  printGettingAllAccountEntities(Ent.USER, pquery)
46011
46032
  pageMessage = getPageMessage(showFirstLastItems=True)
46012
46033
  try:
@@ -46016,9 +46037,9 @@ def doPrintUsers(entityList=None):
46016
46037
  GAPI.BAD_REQUEST, GAPI.RESOURCE_NOT_FOUND, GAPI.FORBIDDEN,
46017
46038
  GAPI.UNKNOWN_ERROR, GAPI.FAILED_PRECONDITION],
46018
46039
  retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS+[GAPI.UNKNOWN_ERROR, GAPI.FAILED_PRECONDITION],
46019
- query=query, fields=fields,
46020
46040
  showDeleted=showDeleted, orderBy=orderBy, sortOrder=sortOrder, viewType=viewType,
46021
46041
  projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'],
46042
+ query=query, fields=fields,
46022
46043
  maxResults=maxResults, **kwargs)
46023
46044
  for users in feed:
46024
46045
  if orgUnitPath is None:
@@ -54970,7 +54991,7 @@ def getDriveFileAttribute(myarg, body, parameters, updateCmd):
54970
54991
  elif myarg == 'timestamp':
54971
54992
  parameters[DFA_TIMESTAMP] = getBoolean()
54972
54993
  elif myarg == 'timeformat':
54973
- parameters[DFA_TIMEFORMAT] = getString(Cmd.OB_STRING, minLen=0)
54994
+ parameters[DFA_TIMEFORMAT] = getString(Cmd.OB_DATETIME_FORMAT, minLen=0)
54974
54995
  elif getDriveFileCopyAttribute(myarg, body, parameters):
54975
54996
  pass
54976
54997
  else:
@@ -59557,7 +59578,7 @@ createReturnItemMap = {
59557
59578
  # [(localfile <FileName>|-)|(url <URL>)]
59558
59579
  # [(drivefilename|newfilename <DriveFileName>) | (replacefilename <REMatchPattern> <RESubstitution>)*]
59559
59580
  # [stripnameprefix <String>]
59560
- # [timestamp <Boolean>]] [timeformat <String>]
59581
+ # [timestamp <Boolean>]] [timeformat <DateTimeFormat>]
59561
59582
  # <DriveFileCreateAttribute>* [noduplicate]
59562
59583
  # [(csv [todrive <ToDriveAttribute>*] (addcsvdata <FieldName> <String>)*)) |
59563
59584
  # (returnidonly|returnlinkonly|returneditlinkonly|showdetails)]
@@ -60084,7 +60105,7 @@ def checkDriveFileShortcut(users):
60084
60105
  # [(localfile <FileName>|-)|(url <URL>)]
60085
60106
  # [retainname | (newfilename <DriveFileName>) | (replacefilename <REMatchPattern> <RESubstitution>)*]
60086
60107
  # [stripnameprefix <String>]
60087
- # [timestamp <Boolean>]] [timeformat <String>]
60108
+ # [timestamp <Boolean>]] [timeformat <DateTimeFormat>]
60088
60109
  # <DriveFileUpdateAttribute>*
60089
60110
  # [(gsheet|csvsheet <SheetEntity> [clearfilter])|(addsheet <String>)]
60090
60111
  # [charset <String>] [columndelimiter <Character>]
gam/gamlib/glclargs.py CHANGED
@@ -49,43 +49,71 @@ class GamCLArgs():
49
49
  ENTITY_CROS_OUS_AND_CHILDREN_QUERIES = 'cros_ous_and_children_queries'
50
50
  ENTITY_CROS_SN = 'cros_sn'
51
51
  ENTITY_DOMAINS = 'domains'
52
+ ENTITY_DOMAINS_NA = 'domains_na'
53
+ ENTITY_DOMAINS_ARCH = 'domains_arch'
52
54
  ENTITY_DOMAINS_NS = 'domains_ns'
53
55
  ENTITY_DOMAINS_SUSP = 'domains_susp'
56
+ ENTITY_DOMAINS_NA_NS = 'domains_na_ns'
54
57
  ENTITY_GROUP = 'group'
55
58
  ENTITY_GROUP_INDE = 'group_inde'
59
+ ENTITY_GROUP_NA = 'group_na'
60
+ ENTITY_GROUP_ARCH = 'group_arch'
56
61
  ENTITY_GROUP_NS = 'group_ns'
57
62
  ENTITY_GROUP_SUSP = 'group_susp'
63
+ ENTITY_GROUP_NA_NS = 'group_na_ns'
58
64
  ENTITY_GROUPS = 'groups'
59
65
  ENTITY_GROUPS_INDE = 'groups_inde'
66
+ ENTITY_GROUPS_NA = 'groups_na'
67
+ ENTITY_GROUPS_ARCH = 'groups_arch'
60
68
  ENTITY_GROUPS_NS = 'groups_ns'
61
69
  ENTITY_GROUPS_SUSP = 'groups_susp'
70
+ ENTITY_GROUPS_NA_NS = 'groups_na_ns'
62
71
  ENTITY_GROUP_USERS = 'group_users'
72
+ ENTITY_GROUP_USERS_NA = 'group_users_na'
73
+ ENTITY_GROUP_USERS_ARCH = 'group_users_arch'
63
74
  ENTITY_GROUP_USERS_NS = 'group_users_ns'
64
75
  ENTITY_GROUP_USERS_SUSP = 'group_users_susp'
76
+ ENTITY_GROUP_USERS_NA_NS = 'group_users_na_ns'
65
77
  ENTITY_GROUP_USERS_SELECT = 'group_users_select'
66
78
  ENTITY_LICENSES = 'licenses'
67
79
  ENTITY_OAUTHUSER = 'oauthuser'
68
80
  ENTITY_OU = 'ou'
81
+ ENTITY_OU_NA = 'ou_na'
82
+ ENTITY_OU_ARCH = 'ou_arch'
69
83
  ENTITY_OU_NS = 'ou_ns'
70
84
  ENTITY_OU_SUSP = 'ou_susp'
85
+ ENTITY_OU_NA_NS = 'ou_na_ns'
71
86
  ENTITY_OU_AND_CHILDREN = 'ou_and_children'
87
+ ENTITY_OU_AND_CHILDREN_NA = 'ou_and_children_na'
88
+ ENTITY_OU_AND_CHILDREN_ARCH = 'ou_and_children_arch'
72
89
  ENTITY_OU_AND_CHILDREN_NS = 'ou_and_children_ns'
73
90
  ENTITY_OU_AND_CHILDREN_SUSP = 'ou_and_children_susp'
91
+ ENTITY_OU_AND_CHILDREN_NA_NS = 'ou_and_children_na_ns'
74
92
  ENTITY_OUS = 'ous'
93
+ ENTITY_OUS_NA = 'ous_na'
94
+ ENTITY_OUS_ARCH = 'ous_arch'
75
95
  ENTITY_OUS_NS = 'ous_ns'
76
96
  ENTITY_OUS_SUSP = 'ous_susp'
97
+ ENTITY_OUS_NA_NS = 'ous_na_ns'
77
98
  ENTITY_OUS_AND_CHILDREN = 'ous_and_children'
99
+ ENTITY_OUS_AND_CHILDREN_NA = 'ous_and_children_na'
100
+ ENTITY_OUS_AND_CHILDREN_ARCH = 'ous_and_children_arch'
78
101
  ENTITY_OUS_AND_CHILDREN_NS = 'ous_and_children_ns'
79
102
  ENTITY_OUS_AND_CHILDREN_SUSP = 'ous_and_children_susp'
103
+ ENTITY_OUS_AND_CHILDREN_NA_NS = 'ous_and_children_na_ns'
80
104
  ENTITY_QUERIES = 'queries'
81
105
  ENTITY_QUERY = 'query'
82
106
  ENTITY_STUDENTS = 'students'
83
107
  ENTITY_TEACHERS = 'teachers'
84
108
  ENTITY_USER = 'user'
85
109
  ENTITY_USERS = 'users'
110
+ ENTITY_USERS_NA = 'users_na'
111
+ ENTITY_USERS_ARCH = 'users_arch'
86
112
  ENTITY_USERS_NS = 'users_ns'
87
- ENTITY_USERS_NS_SUSP = 'users_ns_susp'
88
113
  ENTITY_USERS_SUSP = 'users_susp'
114
+ ENTITY_USERS_NA_NS = 'users_na_ns'
115
+ ENTITY_USERS_ARCH_OR_SUSP = 'users_arch_or_susp'
116
+ ENTITY_USERS_NS_SUSP = 'users_ns_susp'
89
117
  #
90
118
  BROWSER_ENTITIES = [
91
119
  ENTITY_BROWSER,
@@ -118,34 +146,58 @@ class GamCLArgs():
118
146
  ENTITY_CIGROUP_USERS,
119
147
  ENTITY_COURSEPARTICIPANTS,
120
148
  ENTITY_DOMAINS,
149
+ ENTITY_DOMAINS_NA,
150
+ ENTITY_DOMAINS_ARCH,
121
151
  ENTITY_DOMAINS_NS,
122
152
  ENTITY_DOMAINS_SUSP,
153
+ ENTITY_DOMAINS_NA_NS,
123
154
  ENTITY_GROUP,
124
155
  ENTITY_GROUP_INDE,
156
+ ENTITY_GROUP_NA,
157
+ ENTITY_GROUP_ARCH,
125
158
  ENTITY_GROUP_NS,
126
159
  ENTITY_GROUP_SUSP,
160
+ ENTITY_GROUP_NA_NS,
127
161
  ENTITY_GROUPS,
128
162
  ENTITY_GROUPS_INDE,
163
+ ENTITY_GROUPS_NA,
164
+ ENTITY_GROUPS_ARCH,
129
165
  ENTITY_GROUPS_NS,
130
166
  ENTITY_GROUPS_SUSP,
167
+ ENTITY_GROUPS_NA_NS,
131
168
  ENTITY_GROUP_USERS,
169
+ ENTITY_GROUP_USERS_NA,
170
+ ENTITY_GROUP_USERS_ARCH,
132
171
  ENTITY_GROUP_USERS_NS,
133
172
  ENTITY_GROUP_USERS_SUSP,
173
+ ENTITY_GROUP_USERS_NA_NS,
134
174
  ENTITY_GROUP_USERS_SELECT,
135
175
  ENTITY_LICENSES,
136
176
  ENTITY_OAUTHUSER,
137
177
  ENTITY_OU,
178
+ ENTITY_OU_NA,
179
+ ENTITY_OU_ARCH,
138
180
  ENTITY_OU_NS,
139
181
  ENTITY_OU_SUSP,
182
+ ENTITY_OU_NA_NS,
140
183
  ENTITY_OU_AND_CHILDREN,
184
+ ENTITY_OU_AND_CHILDREN_NA,
185
+ ENTITY_OU_AND_CHILDREN_ARCH,
141
186
  ENTITY_OU_AND_CHILDREN_NS,
142
187
  ENTITY_OU_AND_CHILDREN_SUSP,
188
+ ENTITY_OU_AND_CHILDREN_NA_NS,
143
189
  ENTITY_OUS,
190
+ ENTITY_OUS_NA,
191
+ ENTITY_OUS_ARCH,
144
192
  ENTITY_OUS_NS,
145
193
  ENTITY_OUS_SUSP,
194
+ ENTITY_OUS_NA_NS,
146
195
  ENTITY_OUS_AND_CHILDREN,
196
+ ENTITY_OUS_AND_CHILDREN_NA,
197
+ ENTITY_OUS_AND_CHILDREN_ARCH,
147
198
  ENTITY_OUS_AND_CHILDREN_NS,
148
199
  ENTITY_OUS_AND_CHILDREN_SUSP,
200
+ ENTITY_OUS_AND_CHILDREN_NA_NS,
149
201
  ENTITY_QUERIES,
150
202
  ENTITY_QUERY,
151
203
  ENTITY_STUDENTS,
@@ -222,29 +274,53 @@ class GamCLArgs():
222
274
  'licence': ENTITY_LICENSES,
223
275
  'licences': ENTITY_LICENSES,
224
276
  'org': ENTITY_OU,
277
+ 'org_na': ENTITY_OU_NA,
278
+ 'org_arch': ENTITY_OU_ARCH,
225
279
  'org_ns': ENTITY_OU_NS,
226
280
  'org_susp': ENTITY_OU_SUSP,
281
+ 'org_na_ns': ENTITY_OU_NA_NS,
227
282
  'org_and_child': ENTITY_OU_AND_CHILDREN,
283
+ 'org_and_child_na': ENTITY_OU_AND_CHILDREN_NA,
284
+ 'org_and_child_arch': ENTITY_OU_AND_CHILDREN_ARCH,
228
285
  'org_and_child_ns': ENTITY_OU_AND_CHILDREN_NS,
229
286
  'org_and_child_susp': ENTITY_OU_AND_CHILDREN_SUSP,
287
+ 'org_and_child_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS,
230
288
  'org_and_children': ENTITY_OU_AND_CHILDREN,
289
+ 'org_and_children_na': ENTITY_OU_AND_CHILDREN_NA,
290
+ 'org_and_children_arch': ENTITY_OU_AND_CHILDREN_ARCH,
231
291
  'org_and_children_ns': ENTITY_OU_AND_CHILDREN_NS,
232
292
  'org_and_children_susp': ENTITY_OU_AND_CHILDREN_SUSP,
293
+ 'org_and_children_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS,
233
294
  'orgs': ENTITY_OUS,
295
+ 'orgs_na': ENTITY_OUS_NA,
296
+ 'orgs_arch': ENTITY_OUS_ARCH,
234
297
  'orgs_ns': ENTITY_OUS_NS,
235
298
  'orgs_susp': ENTITY_OUS_SUSP,
299
+ 'orgs_na_ns': ENTITY_OUS_NA_NS,
236
300
  'orgs_and_child': ENTITY_OUS_AND_CHILDREN,
301
+ 'orgs_and_child_na': ENTITY_OUS_AND_CHILDREN_NA,
302
+ 'orgs_and_child_arch': ENTITY_OUS_AND_CHILDREN_ARCH,
237
303
  'orgs_and_child_ns': ENTITY_OUS_AND_CHILDREN_NS,
238
304
  'orgs_and_child_susp': ENTITY_OUS_AND_CHILDREN_SUSP,
305
+ 'orgs_and_child_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS,
239
306
  'orgs_and_children': ENTITY_OUS_AND_CHILDREN,
307
+ 'orgs_and_children_na': ENTITY_OUS_AND_CHILDREN_NA,
308
+ 'orgs_and_children_arch': ENTITY_OUS_AND_CHILDREN_ARCH,
240
309
  'orgs_and_children_ns': ENTITY_OUS_AND_CHILDREN_NS,
241
310
  'orgs_and_children_susp': ENTITY_OUS_AND_CHILDREN_SUSP,
311
+ 'orgs_and_children_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS,
242
312
  'ou_and_child': ENTITY_OU_AND_CHILDREN,
313
+ 'ou_and_child_na': ENTITY_OU_AND_CHILDREN_NA,
314
+ 'ou_and_child_arch': ENTITY_OU_AND_CHILDREN_ARCH,
243
315
  'ou_and_child_ns': ENTITY_OU_AND_CHILDREN_NS,
244
316
  'ou_and_child_susp': ENTITY_OU_AND_CHILDREN_SUSP,
317
+ 'ou_and_child_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS,
245
318
  'ous_and_child': ENTITY_OUS_AND_CHILDREN,
319
+ 'ous_and_child_na': ENTITY_OUS_AND_CHILDREN_NA,
320
+ 'ous_and_child_arch': ENTITY_OUS_AND_CHILDREN_ARCH,
246
321
  'ous_and_child_ns': ENTITY_OUS_AND_CHILDREN_NS,
247
322
  'ous_and_child_susp': ENTITY_OUS_AND_CHILDREN_SUSP,
323
+ 'ous_and_child_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS,
248
324
  }
249
325
  # CL entity source selectors
250
326
  ENTITY_SELECTOR_ALL = 'all'
@@ -315,30 +391,217 @@ class GamCLArgs():
315
391
  ]
316
392
  USER_ENTITY_SELECTOR_ALL_SUBTYPES = [
317
393
  ENTITY_USERS,
394
+ ENTITY_USERS_NA,
395
+ ENTITY_USERS_ARCH,
318
396
  ENTITY_USERS_NS,
319
- ENTITY_USERS_NS_SUSP,
320
397
  ENTITY_USERS_SUSP,
398
+ ENTITY_USERS_ARCH_OR_SUSP,
399
+ ENTITY_USERS_NA_NS,
400
+ ENTITY_USERS_NS_SUSP,
321
401
  ]
322
402
  #
323
403
  ENTITY_ALL_CROS = ENTITY_SELECTOR_ALL+' '+ENTITY_CROS
324
404
  ENTITY_ALL_USERS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS
405
+ ENTITY_ALL_USERS_NA = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NA
406
+ ENTITY_ALL_USERS_ARCH = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_ARCH
325
407
  ENTITY_ALL_USERS_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NS
326
- ENTITY_ALL_USERS_NS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NS_SUSP
327
408
  ENTITY_ALL_USERS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_SUSP
409
+ ENTITY_ALL_USERS_NA_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NA_NS
410
+ ENTITY_ALL_USERS_ARCH_OR_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_ARCH_OR_SUSP
411
+ ENTITY_ALL_USERS_NS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NS_SUSP
412
+ #
413
+ ALL_USER_ENTITY_TYPES = {
414
+ ENTITY_ALL_USERS,
415
+ ENTITY_ALL_USERS_NA,
416
+ ENTITY_ALL_USERS_ARCH,
417
+ ENTITY_ALL_USERS_NS,
418
+ ENTITY_ALL_USERS_SUSP,
419
+ ENTITY_ALL_USERS_NA_NS,
420
+ ENTITY_ALL_USERS_NS_SUSP,
421
+ }
422
+ DOMAIN_ENTITY_TYPES = {
423
+ ENTITY_DOMAINS,
424
+ ENTITY_DOMAINS_NA,
425
+ ENTITY_DOMAINS_ARCH,
426
+ ENTITY_DOMAINS_NS,
427
+ ENTITY_DOMAINS_SUSP,
428
+ ENTITY_DOMAINS_NA_NS,
429
+ }
430
+ GROUP_ENTITY_TYPES = {
431
+ ENTITY_GROUP,
432
+ ENTITY_GROUP_NA,
433
+ ENTITY_GROUP_ARCH,
434
+ ENTITY_GROUP_NS,
435
+ ENTITY_GROUP_SUSP,
436
+ ENTITY_GROUP_NA_NS,
437
+ ENTITY_GROUP_INDE,
438
+ }
439
+ GROUPS_ENTITY_TYPES = {
440
+ ENTITY_GROUPS,
441
+ ENTITY_GROUPS_NA,
442
+ ENTITY_GROUPS_ARCH,
443
+ ENTITY_GROUPS_NS,
444
+ ENTITY_GROUPS_SUSP,
445
+ ENTITY_GROUPS_NA_NS,
446
+ ENTITY_GROUPS_INDE,
447
+ }
448
+ GROUP_USERS_ENTITY_TYPES = {
449
+ ENTITY_GROUP_USERS,
450
+ ENTITY_GROUP_USERS_NA,
451
+ ENTITY_GROUP_USERS_ARCH,
452
+ ENTITY_GROUP_USERS_NS,
453
+ ENTITY_GROUP_USERS_SUSP,
454
+ ENTITY_GROUP_USERS_NA_NS,
455
+ ENTITY_GROUP_USERS_SELECT,
456
+ }
457
+ OU_ENTITY_TYPES = {
458
+ ENTITY_OU,
459
+ ENTITY_OU_AND_CHILDREN,
460
+ ENTITY_OU_NA,
461
+ ENTITY_OU_AND_CHILDREN_NA,
462
+ ENTITY_OU_ARCH,
463
+ ENTITY_OU_AND_CHILDREN_ARCH,
464
+ ENTITY_OU_NS,
465
+ ENTITY_OU_AND_CHILDREN_NS,
466
+ ENTITY_OU_SUSP,
467
+ ENTITY_OU_AND_CHILDREN_SUSP,
468
+ ENTITY_OU_NA_NS,
469
+ ENTITY_OU_AND_CHILDREN_NA_NS,
470
+ }
471
+ OUS_ENTITY_TYPES = {
472
+ ENTITY_OUS,
473
+ ENTITY_OUS_AND_CHILDREN,
474
+ ENTITY_OUS_NA,
475
+ ENTITY_OUS_AND_CHILDREN_NA,
476
+ ENTITY_OUS_ARCH,
477
+ ENTITY_OUS_AND_CHILDREN_ARCH,
478
+ ENTITY_OUS_NS,
479
+ ENTITY_OUS_AND_CHILDREN_NS,
480
+ ENTITY_OUS_SUSP,
481
+ ENTITY_OUS_AND_CHILDREN_SUSP,
482
+ ENTITY_OUS_NA_NS,
483
+ ENTITY_OUS_AND_CHILDREN_NA_NS,
484
+ }
485
+ OU_DIRECT_ENTITY_TYPES = {
486
+ ENTITY_OU,
487
+ ENTITY_OUS,
488
+ ENTITY_OU_NA,
489
+ ENTITY_OUS_NA,
490
+ ENTITY_OU_ARCH,
491
+ ENTITY_OUS_ARCH,
492
+ ENTITY_OU_NS,
493
+ ENTITY_OUS_NS,
494
+ ENTITY_OU_SUSP,
495
+ ENTITY_OUS_SUSP,
496
+ ENTITY_OU_NA_NS,
497
+ ENTITY_OUS_NA_NS,
498
+ }
499
+ CROS_OU_ENTITY_TYPES = {
500
+ ENTITY_CROS_OU,
501
+ ENTITY_CROS_OU_AND_CHILDREN,
502
+ ENTITY_CROS_OU_QUERY,
503
+ ENTITY_CROS_OU_AND_CHILDREN_QUERY,
504
+ ENTITY_CROS_OU_QUERIES,
505
+ ENTITY_CROS_OU_AND_CHILDREN_QUERIES,
506
+ }
507
+ CROS_OUS_ENTITY_TYPES = {
508
+ ENTITY_CROS_OUS,
509
+ ENTITY_CROS_OUS_AND_CHILDREN,
510
+ ENTITY_CROS_OUS_QUERY,
511
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERY,
512
+ ENTITY_CROS_OUS_QUERIES,
513
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERIES,
514
+ }
515
+ CROS_OU_CHILDREN_ENTITY_TYPES = {
516
+ ENTITY_CROS_OU_AND_CHILDREN,
517
+ ENTITY_CROS_OU_AND_CHILDREN_QUERY,
518
+ ENTITY_CROS_OU_AND_CHILDREN_QUERIES,
519
+ ENTITY_CROS_OUS_AND_CHILDREN,
520
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERY,
521
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERIES,
522
+ }
523
+ CROS_OU_QUERY_ENTITY_TYPES = {
524
+ ENTITY_CROS_OU_QUERY,
525
+ ENTITY_CROS_OU_AND_CHILDREN_QUERY,
526
+ ENTITY_CROS_OUS_QUERY,
527
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERY,
528
+ }
529
+ CROS_OU_QUERIES_ENTITY_TYPES = {
530
+ ENTITY_CROS_OU_QUERIES,
531
+ ENTITY_CROS_OU_AND_CHILDREN_QUERIES,
532
+ ENTITY_CROS_OUS_QUERIES,
533
+ ENTITY_CROS_OUS_AND_CHILDREN_QUERIES,
534
+ }
328
535
  #
329
536
  ALL_USERS_QUERY_MAP = {
330
537
  ENTITY_ALL_USERS: 'isSuspended=False',
538
+ ENTITY_ALL_USERS_NA: 'isArchived=False',
539
+ ENTITY_ALL_USERS_ARCH: 'isArchived=True',
331
540
  ENTITY_ALL_USERS_NS: 'isSuspended=False',
332
- ENTITY_ALL_USERS_NS_SUSP: None,
333
541
  ENTITY_ALL_USERS_SUSP: 'isSuspended=True',
542
+ ENTITY_ALL_USERS_NA_NS: 'isArchived=False isSuspended=False',
543
+ ENTITY_ALL_USERS_NS_SUSP: None,
544
+ }
545
+ DOMAINS_QUERY_MAP = {
546
+ ENTITY_DOMAINS: None,
547
+ ENTITY_DOMAINS_NA: 'isArchived=False',
548
+ ENTITY_DOMAINS_ARCH: 'isArchived=True',
549
+ ENTITY_DOMAINS_NS: 'isSuspended=False',
550
+ ENTITY_DOMAINS_SUSP: 'isSuspended=True',
551
+ ENTITY_DOMAINS_NA_NS: 'isArchived=False isSuspended=False',
552
+ }
553
+ GROUPS_QUERY_MAP = { #(isArchived, isSuspended)
554
+ ENTITY_GROUP_NA: (False, None),
555
+ ENTITY_GROUPS_NA: (False, None),
556
+ ENTITY_GROUP_ARCH: (True, None),
557
+ ENTITY_GROUPS_ARCH: (True, None),
558
+ ENTITY_GROUP_NS: (None, False),
559
+ ENTITY_GROUPS_NS: (None, False),
560
+ ENTITY_GROUP_SUSP: (None, True),
561
+ ENTITY_GROUPS_SUSP: (None, True),
562
+ ENTITY_GROUP_NA_NS: (False, False),
563
+ ENTITY_GROUPS_NA_NS: (False, False),
564
+ }
565
+ GROUP_USERS_QUERY_MAP = { #(isArchived, isSuspended)
566
+ ENTITY_GROUP_USERS_NA: (False, None),
567
+ ENTITY_GROUP_USERS_ARCH: (True, None),
568
+ ENTITY_GROUP_USERS_NS: (None, False),
569
+ ENTITY_GROUP_USERS_SUSP: (None, True),
570
+ ENTITY_GROUP_USERS_NA_NS: (False, False),
571
+ }
572
+ OU_QUERY_MAP = { #(isArchived, isSuspended)
573
+ ENTITY_OU_NA: (False, None),
574
+ ENTITY_OUS_NA: (False, None),
575
+ ENTITY_OU_AND_CHILDREN_NA: (False, None),
576
+ ENTITY_OUS_AND_CHILDREN_NA: (False, None),
577
+ ENTITY_OU_ARCH: (True, None),
578
+ ENTITY_OUS_ARCH: (True, None),
579
+ ENTITY_OU_AND_CHILDREN_ARCH: (True, None),
580
+ ENTITY_OUS_AND_CHILDREN_ARCH: (True, None),
581
+ ENTITY_OU_NS: (None, False),
582
+ ENTITY_OUS_NS: (None, False),
583
+ ENTITY_OU_AND_CHILDREN_NS: (None, False),
584
+ ENTITY_OUS_AND_CHILDREN_NS: (None, False),
585
+ ENTITY_OU_SUSP: (None, True),
586
+ ENTITY_OUS_SUSP: (None, True),
587
+ ENTITY_OU_AND_CHILDREN_SUSP: (None, True),
588
+ ENTITY_OUS_AND_CHILDREN_SUSP: (None, True),
589
+ ENTITY_OU_NA_NS: (False, False),
590
+ ENTITY_OUS_NA_NS: (False, False),
591
+ ENTITY_OU_AND_CHILDREN_NA_NS: (False, False),
592
+ ENTITY_OUS_AND_CHILDREN_NA_NS: (False, False),
334
593
  }
335
594
  #
336
595
  ENTITY_SELECTOR_ALL_SUBTYPES_MAP = {
337
596
  ENTITY_CROS: ENTITY_ALL_CROS,
338
597
  ENTITY_USERS: ENTITY_ALL_USERS,
598
+ ENTITY_USERS_NA: ENTITY_ALL_USERS_NA,
599
+ ENTITY_USERS_ARCH: ENTITY_ALL_USERS_ARCH,
339
600
  ENTITY_USERS_NS: ENTITY_ALL_USERS_NS,
340
- ENTITY_USERS_NS_SUSP: ENTITY_ALL_USERS_NS_SUSP,
341
601
  ENTITY_USERS_SUSP: ENTITY_ALL_USERS_SUSP,
602
+ ENTITY_USERS_NA_NS: ENTITY_ALL_USERS_NA_NS,
603
+ ENTITY_USERS_ARCH_OR_SUSP: ENTITY_ALL_USERS_ARCH_OR_SUSP,
604
+ ENTITY_USERS_NS_SUSP: ENTITY_ALL_USERS_NS_SUSP,
342
605
  }
343
606
  # Allowed values for CL source selector datafile, csvkmd
344
607
  CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES = [
@@ -352,22 +615,37 @@ class GamCLArgs():
352
615
  ENTITY_CIGROUPS,
353
616
  ENTITY_CIGROUP_USERS,
354
617
  ENTITY_DOMAINS,
618
+ ENTITY_DOMAINS_NA,
619
+ ENTITY_DOMAINS_ARCH,
355
620
  ENTITY_DOMAINS_NS,
356
621
  ENTITY_DOMAINS_SUSP,
622
+ ENTITY_DOMAINS_NA_NS,
357
623
  ENTITY_GROUPS,
358
624
  ENTITY_GROUPS_INDE,
625
+ ENTITY_GROUPS_NA,
626
+ ENTITY_GROUPS_ARCH,
359
627
  ENTITY_GROUPS_NS,
360
628
  ENTITY_GROUPS_SUSP,
629
+ ENTITY_GROUPS_NA_NS,
361
630
  ENTITY_GROUP_USERS,
631
+ ENTITY_GROUP_USERS_NA,
632
+ ENTITY_GROUP_USERS_ARCH,
362
633
  ENTITY_GROUP_USERS_NS,
363
634
  ENTITY_GROUP_USERS_SUSP,
635
+ ENTITY_GROUP_USERS_NA_NS,
364
636
  ENTITY_GROUP_USERS_SELECT,
365
637
  ENTITY_OUS,
638
+ ENTITY_OUS_NA,
639
+ ENTITY_OUS_ARCH,
366
640
  ENTITY_OUS_NS,
367
641
  ENTITY_OUS_SUSP,
642
+ ENTITY_OUS_NA_NS,
368
643
  ENTITY_OUS_AND_CHILDREN,
644
+ ENTITY_OUS_AND_CHILDREN_NA,
645
+ ENTITY_OUS_AND_CHILDREN_ARCH,
369
646
  ENTITY_OUS_AND_CHILDREN_NS,
370
647
  ENTITY_OUS_AND_CHILDREN_SUSP,
648
+ ENTITY_OUS_AND_CHILDREN_NA_NS,
371
649
  ENTITY_COURSEPARTICIPANTS,
372
650
  ENTITY_STUDENTS,
373
651
  ENTITY_TEACHERS,
@@ -377,6 +655,7 @@ class GamCLArgs():
377
655
  GAM_CMD = 'gam'
378
656
  COMMIT_BATCH_CMD = 'commit-batch'
379
657
  PRINT_CMD = 'print'
658
+ DATETIME_CMD = 'datetime'
380
659
  SET_CMD = 'set'
381
660
  CLEAR_CMD = 'clear'
382
661
  SLEEP_CMD = 'sleep'
@@ -924,6 +1203,7 @@ class GamCLArgs():
924
1203
  OB_CSE_KEYPAIR_ID = 'CSEKeyPairID'
925
1204
  OB_CUSTOMER_ID = 'CustomerID'
926
1205
  OB_CUSTOMER_AUTH_TOKEN = 'CustomerAuthToken'
1206
+ OB_DATETIME_FORMAT = 'DateTimeFormat'
927
1207
  OB_DEVICE_FILE_ENTITY = 'DeviceFileEntity'
928
1208
  OB_DEVICE_ENTITY = 'DeviceEntity'
929
1209
  OB_DEVICE_ID = 'DeviceID'
gam/gamlib/glentity.py CHANGED
@@ -384,11 +384,13 @@ class GamEntity():
384
384
  URL = 'url '
385
385
  USER = 'user'
386
386
  USER_ALIAS = 'uali'
387
+ USER_NOT_ARCHIVED = 'usna'
388
+ USER_ARCHIVED = 'usar'
387
389
  USER_EMAIL = 'uema'
388
390
  USER_INVITATION = 'uinv'
389
- USER_NOT_SUSPENDED = 'uns'
390
- USER_SCHEMA = 'usch'
391
+ USER_NOT_SUSPENDED = 'usns'
391
392
  USER_SUSPENDED = 'usup'
393
+ USER_SCHEMA = 'usch'
392
394
  VACATION = 'vaca'
393
395
  VACATION_ENABLED = 'vace'
394
396
  VALUE = 'val'
@@ -748,11 +750,13 @@ class GamEntity():
748
750
  URL: ['URLs', 'URL'],
749
751
  USER: ['Users', 'User'],
750
752
  USER_ALIAS: ['User Aliases', 'User Alias'],
753
+ USER_NOT_ARCHIVED: ['Users (Not archived)', 'User (Not archived)'],
754
+ USER_ARCHIVED: ['Users (Archived)', 'User (Archived)'],
751
755
  USER_EMAIL: ['User Emails', 'User Email'],
752
756
  USER_INVITATION: ['User Invitations', 'User Invitation'],
753
757
  USER_NOT_SUSPENDED: ['Users (Not suspended)', 'User (Not suspended)'],
754
- USER_SCHEMA: ['Schemas', 'Schema'],
755
758
  USER_SUSPENDED: ['Users (Suspended)', 'User (Suspended)'],
759
+ USER_SCHEMA: ['Schemas', 'Schema'],
756
760
  VACATION: ['Vacation', 'Vacation'],
757
761
  VACATION_ENABLED: ['Vacation Enabled', 'Vacation Enabled'],
758
762
  VALUE: ['Values', 'Value'],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.21.3
3
+ Version: 7.22.2
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
@@ -27,10 +27,11 @@ Requires-Dist: google-api-python-client>=2.167.0
27
27
  Requires-Dist: google-auth-httplib2>=0.2.0
28
28
  Requires-Dist: google-auth-oauthlib>=1.2.2
29
29
  Requires-Dist: google-auth>=2.39.0
30
- Requires-Dist: httplib2>=0.22.0
30
+ Requires-Dist: httplib2>=0.31.0
31
31
  Requires-Dist: lxml>=5.4.0
32
32
  Requires-Dist: passlib>=1.7.4
33
33
  Requires-Dist: pathvalidate>=3.2.3
34
+ Requires-Dist: pysocks>=1.7.1
34
35
  Provides-Extra: yubikey
35
36
  Requires-Dist: yubikey-manager>=5.6.1; extra == 'yubikey'
36
37
  Description-Content-Type: text/markdown
@@ -55,6 +56,11 @@ this will download GAM, install it and start setup.
55
56
 
56
57
  Download the MSI Installer from the [GitHub Releases] page. Install the MSI and you'll be prompted to setup GAM.
57
58
 
59
+ ## Use your own Python
60
+ If you'd prefer to install GAM as a Python package you can install with pip:
61
+ ```
62
+ pip install gam7
63
+ ```
58
64
  # Documentation
59
65
 
60
66
  The GAM documentation is hosted in the [GitHub Wiki]
@@ -1,4 +1,4 @@
1
- gam/__init__.py,sha256=_1lJp1NkVPUiklWyNKv4HoYleKE0fgRaCH8kB25R6DY,3610215
1
+ gam/__init__.py,sha256=7lJoX_SY-ehsya7kuM16ZczEpgMPJ92Uxeaan900KBo,3609967
2
2
  gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
3
3
  gam/cacerts.pem,sha256=DUsVo2XlFYwfkhe3gnxa-Km4Z4noz74hSApXwTT-nQE,44344
4
4
  gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
@@ -24,8 +24,8 @@ gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
24
24
  gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
25
25
  gam/gamlib/glapi.py,sha256=u97M7Y2BeP3tYEEGYEz-9kY4fdV0fYkeqC3YN-sRwNc,36028
26
26
  gam/gamlib/glcfg.py,sha256=7Ut-7sDTw-WVHZfvDWn_dlVNfuWd6VsPDBpQ3qnyzJE,28100
27
- gam/gamlib/glclargs.py,sha256=vDHe3heii7s-VN0xren0CCS5S6c1e5dCLigWTZlyeY8,44170
28
- gam/gamlib/glentity.py,sha256=8F98YR1ronheiQShD6WHlY-YnBKfMDrc33iRuRoLIvo,35097
27
+ gam/gamlib/glclargs.py,sha256=ARqlKA4s578PLOxQSLVWSnUdKNpv8LForlm1jpcfWeI,53207
28
+ gam/gamlib/glentity.py,sha256=Dp15UbaxGbqDKYyF50z-wjFlQpKvi9mCIuPDsd_kL8Y,35284
29
29
  gam/gamlib/glgapi.py,sha256=pdBbwNtnCwFWxJGaP-_3hdTjSNoOCJF2yo76WdQOi1k,40426
30
30
  gam/gamlib/glgdata.py,sha256=weRppttWm6uRyqtBoGPKoHiNZ2h28nhfUV4J_mbCszY,2707
31
31
  gam/gamlib/glglobals.py,sha256=oJfaLUQj46XqwrOzRfWhGqO0f1P26xjJZefaILJUFGE,9695
@@ -47,8 +47,8 @@ gam/gdata/apps/audit/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrK
47
47
  gam/gdata/apps/audit/service.py,sha256=Z1eueThcNeVUMWP1DRWc_DGHrJCiJI8W_xj6L-cqu-Q,9658
48
48
  gam/gdata/apps/contacts/__init__.py,sha256=Um6zgIkiahZns7yAEuC3pxHSMD8iciZ_EoynSLoYPfU,30463
49
49
  gam/gdata/apps/contacts/service.py,sha256=5lNb-Ii1Gyek6ePFji3kyoYtCBc8CuJTwagx2BL2o14,15684
50
- gam7-7.21.3.dist-info/METADATA,sha256=BZtfkO9lwv8COlmsdv0htZGWOrFGv3cmAhgwn2duGUg,2937
51
- gam7-7.21.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
- gam7-7.21.3.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
- gam7-7.21.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
- gam7-7.21.3.dist-info/RECORD,,
50
+ gam7-7.22.2.dist-info/METADATA,sha256=r9zzrfpu15NU-ibVX75fX5NDQcGY9tUliskOT7VQV70,3092
51
+ gam7-7.22.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
52
+ gam7-7.22.2.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
53
+ gam7-7.22.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
54
+ gam7-7.22.2.dist-info/RECORD,,
File without changes