def print_(): cd = gapi_directory.build() privs = gapi.call(cd.privileges(), 'list', customer=GC_Values[GC_CUSTOMER_ID]) privs = flatten_privilege_list(privs.get('items', [])) display.print_json(privs)
def getHoldInfo(): v = buildGAPIObject() hold = sys.argv[3] matterId = None i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i + 1]) holdId = convertHoldNameToID(v, hold, matterId) i += 2 else: controlflow.invalid_argument_exit(myarg, 'gam info hold') if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the hold.') results = gapi.call(v.matters().holds(), 'get', matterId=matterId, holdId=holdId) cd = gam.buildGAPIObject('directory') if 'accounts' in results: account_type = 'group' if results['corpus'] == 'GROUPS' else 'user' for i in range(0, len(results['accounts'])): uid = f'uid:{results["accounts"][i]["accountId"]}' acct_email = gam.convertUIDtoEmailAddress(uid, cd, [account_type]) results['accounts'][i]['email'] = acct_email if 'orgUnit' in results: results['orgUnit']['orgUnitPath'] = gapi_directory_orgunits.info( results['orgUnit']['orgUnitId'], return_attrib='orgUnitPath') display.print_json(results)
def info(): ci = gapi_cloudidentity.build('cloudidentity_beta') group = gam.normalizeEmailAddressOrUID(sys.argv[3]) getUsers = True showJoinDate = True showUpdateDate = False showMemberTree = False i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'nousers': getUsers = False i += 1 elif myarg == 'nojoindate': showJoinDate = False i += 1 elif myarg == 'showupdatedate': showUpdateDate = True i += 1 elif myarg == 'membertree': showMemberTree = True i += 1 else: controlflow.invalid_argument_exit(myarg, 'gam info cigroup') name = group_email_to_id(ci, group) basic_info = gapi.call(ci.groups(), 'get', name=name) display.print_json(basic_info) if getUsers and not showMemberTree: if not showJoinDate and not showUpdateDate: view = 'BASIC' pageSize = 1000 else: view = 'FULL' pageSize = 500 members = gapi.get_all_pages(ci.groups().memberships(), 'list', 'memberships', parent=name, fields='*', pageSize=pageSize, view=view) print(' Members:') for member in members: role = get_single_role(member.get('roles', [])).lower() email = member.get('memberKey', {}).get('id') member_type = member.get('type', 'USER').lower() jc_string = '' if showJoinDate: joined = member.get('createTime', 'Unknown') jc_string += f' joined {joined}' if showUpdateDate: updated = member.get('updateTime', 'Unknown') jc_string += f' updated {updated}' print(f' {role}: {email} ({member_type}){jc_string}') print(f'Total {len(members)} users in group') elif showMemberTree: print(' Membership Tree:') cached_group_members = {} print_member_tree(ci, name, cached_group_members, 2, True)
def getExportInfo(): v = buildGAPIObject() matterId = getMatterItem(v, sys.argv[3]) exportId = convertExportNameToID(v, sys.argv[4], matterId) export = gapi.call(v.matters().exports(), 'get', matterId=matterId, exportId=exportId) display.print_json(export)
def create(): '''gam create printer''' cdapi = gapi_directory.build() parent = _get_customerid() body = _get_printer_attributes(3, cdapi) result = gapi.call(cdapi.customers().chrome().printers(), 'create', parent=parent, body=body) display.print_json(result)
def infoEvent(): calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2]) if not cal: return eventId = sys.argv[4] result = gapi.call(cal.events(), 'get', calendarId=calendarId, eventId=eventId) display.print_json(result)
def getMatterInfo(): v = buildGAPIObject() matterId = getMatterItem(v, sys.argv[3]) result = gapi.call(v.matters(), 'get', matterId=matterId, view='FULL') if 'matterPermissions' in result: cd = gam.buildGAPIObject('directory') for i in range(0, len(result['matterPermissions'])): uid = f'uid:{result["matterPermissions"][i]["accountId"]}' user_email = gam.convertUIDtoEmailAddress(uid, cd) result['matterPermissions'][i]['email'] = user_email display.print_json(result)
def info(): cd = gapi_directory.build() alias = sys.argv[3] result = gapi.call(cd.domainAliases(), 'get', customer=GC_Values[GC_CUSTOMER_ID], domainAliasName=alias) if 'creationTime' in result: result['creationTime'] = utils.formatTimestampYMDHMSF( result['creationTime']) display.print_json(result)
def _generic_get(get_type): '''generic function to call read data APIs''' svc = gapi_cloudidentity.build('cloudidentity_beta') customer = _get_customerid() email = sys.argv[3].lower() encoded_email = quote_plus(email) name = f'{customer}/userinvitations/{encoded_email}' result = gapi.call(svc.customers().userinvitations(), get_type, name=name) if 'name' in result: result['name'] = _reduce_name(result['name']) display.print_json(result)
def info(): ci = gapi_cloudidentity.build_dwd() customer = f'customers/{GC_Values[GC_CUSTOMER_ID]}' name = sys.argv[3] if not name.startswith('devices/'): name = f'devices/{name}' device = gapi.call(ci.devices(), 'get', name=name, customer=customer) device_users = gapi.get_all_pages(ci.devices().deviceUsers(), 'list', 'deviceUsers', parent=name, customer=customer) display.print_json(device) print('Device Users:') display.print_json(device_users)
def info(): ci = gapi_cloudidentity.build_dwd() customer = _get_device_customerid() name = _get_device_name() device = gapi.call(ci.devices(), 'get', name=name, customer=customer) device_users = gapi.get_all_pages(ci.devices().deviceUsers(), 'list', 'deviceUsers', parent=name, customer=customer) display.print_json(device) print('Device Users:') display.print_json(device_users)
def info(): '''gam info printer''' cdapi = gapi_directory.build() customer = _get_customerid() printer_id = sys.argv[3] name = f'{customer}/chrome/printers/{printer_id}' printer = gapi.call(cdapi.customers().chrome().printers(), 'get', name=name) if 'orgUnitId' in printer: printer['orgUnitPath'] = gapi_directory_orgunits.orgunit_from_orgunitid( printer['orgUnitId'], cdapi) display.print_json(printer)
def getBuildingInfo(): cd = gapi_directory.build() buildingId = getBuildingByNameOrId(cd, sys.argv[3]) building = gapi.call(cd.resources().buildings(), 'get', customer=GC_Values[GC_CUSTOMER_ID], buildingId=buildingId) if 'buildingId' in building: building['buildingId'] = f'id:{building["buildingId"]}' if 'floorNames' in building: building['floorNames'] = ','.join(building['floorNames']) if 'buildingName' in building: sys.stdout.write(building.pop('buildingName')) display.print_json(building)
def info(): cd = gapi_directory.build() resourceId = sys.argv[3] info = gapi.call(cd.mobiledevices(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], resourceId=resourceId) if 'deviceId' in info: info['deviceId'] = info['deviceId'].encode('unicode-escape').decode( UTF8) attrib = 'securityPatchLevel' if attrib in info and int(info[attrib]): info[attrib] = utils.formatTimestampYMDHMS(info[attrib]) display.print_json(info)
def _display_cros_command_result(cd, device_id, command_id, times_to_check_status): print(f'deviceId: {device_id}, commandId: {command_id}') final_states = {'EXPIRED', 'CANCELLED', 'EXECUTED_BY_CLIENT'} for _ in range(0, times_to_check_status): time.sleep(2) result = gapi.call(cd.customer().devices().chromeos().commands(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], deviceId=device_id, commandId=command_id) display.print_json(result) if result.get('state') in final_states: return
def _generic_action(action): '''generic function to call actionable APIs''' svc = gapi_cloudidentity.build('cloudidentity_beta') customer = _get_customerid() email = sys.argv[3].lower() encoded_email = quote_plus(email) name = f'{customer}/userinvitations/{encoded_email}' action_map = {'cancel': 'Cancelling', 'send': 'Sending'} print_action = action_map[action] print(f'{print_action} user invitation...') result = gapi.call(svc.customers().userinvitations(), action, name=name) name = result.get('response', {}).get('name') if name: result['response']['name'] = _reduce_name(name) display.print_json(result)
def update(): '''gam update printer''' cdapi = gapi_directory.build() customer = _get_customerid() printer_id = sys.argv[3] name = f'{customer}/chrome/printers/{printer_id}' body = _get_printer_attributes(4, cdapi) update_mask = ','.join(body) # note clearMask seems unnecessary. Updating field to '' clears it. result = gapi.call(cdapi.customers().chrome().printers(), 'patch', name=name, updateMask=update_mask, body=body) display.print_json(result)
def get_command(): cd = gapi_directory.build() i, devices = getCrOSDeviceEntity(3, cd) command_id = None while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'commandid': command_id = sys.argv[i+1] i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam getcommand cros') for device_id in devices: result = gapi.call(cd.customer().devices().chromeos().commands(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], deviceId=device_id, commandId=command_id) display.print_json(result)
def getResourceCalendarInfo(): cd = gapi_directory.build() resId = sys.argv[3] resource = gapi.call(cd.resources().calendars(), 'get', customer=GC_Values[GC_CUSTOMER_ID], calendarResourceId=resId) if 'featureInstances' in resource: features = [] for a_feature in resource.pop('featureInstances'): features.append(a_feature['feature']['name']) resource['features'] = ', '.join(features) if 'buildingId' in resource: resource['buildingName'] = getBuildingNameById(cd, resource['buildingId']) resource['buildingId'] = f'id:{resource["buildingId"]}' display.print_json(resource)
def info_member(): ci = gapi_cloudidentity.build() member = gam.normalizeEmailAddressOrUID(sys.argv[3]) group = gam.normalizeEmailAddressOrUID(sys.argv[4]) group_name = gapi.call(ci.groups(), 'lookup', groupKey_id=group, fields='name').get('name') member_name = gapi.call(ci.groups().memberships(), 'lookup', parent=group_name, memberKey_id=member, fields='name').get('name') member_details = gapi.call(ci.groups().memberships(), 'get', name=member_name) display.print_json(member_details)
def info_state(): ci = gapi_cloudidentity.build_dwd() gapi_directory_customer.setTrueCustomerId() customer = _get_device_customerid() customer_id = customer[10:] client_id = f'{customer_id}-gam' i, deviceuser = _get_deviceuser_name() while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'clientid': client_id = f'{customer_id}-{sys.argv[i+1]}' i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam info deviceuserstate') name = f'{deviceuser}/clientStates/{client_id}' result = gapi.call(ci.devices().deviceUsers().clientStates(), 'get', name=name, customer=customer) display.print_json(result)
def info(): if (len(sys.argv) < 4) or (sys.argv[3] == 'logo'): gapi_directory_customer.doGetCustomerInfo() return cd = gapi_directory.build() domainName = sys.argv[3] result = gapi.call(cd.domains(), 'get', customer=GC_Values[GC_CUSTOMER_ID], domainName=domainName) if 'creationTime' in result: result['creationTime'] = utils.formatTimestampYMDHMSF( result['creationTime']) if 'domainAliases' in result: for i in range(0, len(result['domainAliases'])): if 'creationTime' in result['domainAliases'][i]: result['domainAliases'][i][ 'creationTime'] = utils.formatTimestampYMDHMSF( result['domainAliases'][i]['creationTime']) display.print_json(result)
def info(): cbcm = build() device_id = sys.argv[3] projection = 'BASIC' fields = None i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg in ['basic', 'full']: projection = myarg.upper() i += 1 elif myarg == 'fields': fields = sys.argv[i+1] i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam info browser') browser = gapi.call(cbcm.chromebrowsers(), 'get', customer=GC_Values[GC_CUSTOMER_ID], fields=fields, deviceId=device_id, projection=projection) display.print_json(browser)
def createExport(): v = buildGAPIObject() query_discovery = v._rootDesc['schemas']['Query'] allowed_formats = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['MailExportOptions']['properties'] ['exportFormat']['enum']) export_format = 'MBOX' showConfidentialModeContent = None # default to not even set matterId = None query = None body = {'exportOptions': {}} i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i + 1]) body['matterId'] = matterId i += 2 elif myarg == 'name': body['name'] = sys.argv[i + 1] i += 2 elif myarg in QUERY_ARGS: query, i = _build_query(query, myarg, i, query_discovery) elif myarg in ['format']: export_format = sys.argv[i + 1].upper() if export_format not in allowed_formats: controlflow.expected_argument_exit('export format', ', '.join(allowed_formats), export_format) i += 2 elif myarg in ['showconfidentialmodecontent']: showConfidentialModeContent = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['region']: allowed_regions = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['ExportOptions']['properties']['region'] ['enum']) body['exportOptions']['region'] = sys.argv[i + 1].upper() if body['exportOptions']['region'] not in allowed_regions: controlflow.expected_argument_exit( 'region', ', '.join(allowed_regions), body['exportOptions']['region']) i += 2 elif myarg in ['includeaccessinfo']: body['exportOptions'].setdefault( 'driveOptions', {})['includeAccessInfo'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam create export') if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the new export.') _validate_query(query, query_discovery) body['query'] = query if 'name' not in body: corpus_name = body['query']['corpus'] corpus_date = datetime.datetime.now() body['name'] = f'GAM {corpus_name} export - {corpus_date}' options_field = None if body['query']['corpus'] == 'MAIL': options_field = 'mailOptions' elif body['query']['corpus'] == 'GROUPS': options_field = 'groupsOptions' elif body['query']['corpus'] == 'HANGOUTS_CHAT': options_field = 'hangoutsChatOptions' if options_field: body['exportOptions'].pop('driveOptions', None) body['exportOptions'][options_field] = {'exportFormat': export_format} if showConfidentialModeContent is not None: body['exportOptions'][options_field][ 'showConfidentialModeContent'] = showConfidentialModeContent results = gapi.call(v.matters().exports(), 'create', matterId=matterId, body=body) print(f'Created export {results["id"]}') display.print_json(results)
def info(name=None, return_attrib=None): cd = gapi_directory.build() checkSuspended = None if not name: name = getOrgUnitItem(sys.argv[3]) get_users = True show_children = False i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower() if myarg == 'nousers': get_users = False i += 1 elif myarg in ['children', 'child']: show_children = True i += 1 elif myarg in ['suspended', 'notsuspended']: checkSuspended = myarg == 'suspended' i += 1 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam info org') if name == '/': orgs = gapi.call(cd.orgunits(), 'list', customerId=GC_Values[GC_CUSTOMER_ID], type='children', fields='organizationUnits/parentOrgUnitId') if 'organizationUnits' in orgs and orgs['organizationUnits']: name = orgs['organizationUnits'][0]['parentOrgUnitId'] else: topLevelOrgId = getTopLevelOrgId(cd, '/') if topLevelOrgId: name = topLevelOrgId else: name = makeOrgUnitPathRelative(name) result = gapi.call(cd.orgunits(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], orgUnitPath=encodeOrgUnitPath(name)) if return_attrib: return result[return_attrib] display.print_json(result) if get_users: name = result['orgUnitPath'] page_message = gapi.got_total_items_first_last_msg('Users') users = gapi.get_all_pages( cd.users(), 'list', 'users', page_message=page_message, message_attribute='primaryEmail', customer=GC_Values[GC_CUSTOMER_ID], query=orgUnitPathQuery(name, checkSuspended), fields='users(primaryEmail,orgUnitPath),nextPageToken') if checkSuspended is None: print('Users:') elif not checkSuspended: print('Users (Not suspended):') else: print('Users (Suspended):') for user in users: if show_children or (name.lower() == user['orgUnitPath'].lower()): sys.stdout.write(f' {user["primaryEmail"]}') if name.lower() != user['orgUnitPath'].lower(): print(' (child)') else: print('')
def printShowCrosTelemetry(mode): cm = build() cd = None parent = _get_customerid() todrive = False filter_ = None readMask = [] orgUnitIdPathMap = {} diskpercentonly = False showOrgUnitPath = False supported_readmask_values = list( cm._rootDesc['schemas']['GoogleChromeManagementV1TelemetryDevice'] ['properties'].keys()) supported_readmask_values.sort() supported_readmask_map = { item.lower(): item for item in supported_readmask_values } i = 3 if mode == 'info': if i >= len(sys.argv): controlflow.system_error_exit( 3, f'<SerialNumber> required for "gam info crostelemetry"') filter_ = f'serialNumber={sys.argv[i]}' i += 1 mode = 'show' while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'fields': field_list = sys.argv[i + 1].lower().split(',') for field_item in field_list: if field_item not in supported_readmask_map: controlflow.expected_argument_exit( 'fields', ', '.join(supported_readmask_values), field_item) else: readMask.append(supported_readmask_map[field_item]) i += 2 elif myarg in supported_readmask_map: readMask.append(supported_readmask_map[myarg]) i += 1 elif myarg == 'filter': filter_ = sys.argv[i + 1] i += 2 elif myarg in ['ou', 'org', 'orgunit']: _, orgUnitId = gapi_directory_orgunits.getOrgUnitId( sys.argv[i + 1], None) filter_ = f'orgUnitId={orgUnitId[3:]}' i += 2 elif myarg == 'crossn': filter_ = f'serialNumber={sys.argv[i + 1]}' i += 2 elif myarg == 'todrive': todrive = True i += 1 elif myarg == 'showorgunitpath': showOrgUnitPath = True cd = gapi_directory.build() i += 1 elif myarg == 'storagepercentonly': diskpercentonly = True i += 1 else: msg = f'{myarg} is not a valid argument to "gam print crostelemetry"' controlflow.system_error_exit(3, msg) if not readMask: readMask = ','.join(supported_readmask_values) else: if 'deviceId' not in readMask: readMask.append('deviceId') readMask = ','.join(readMask) gam.printGettingAllItems('Chrome Device Telemetry...', filter_) page_message = gapi.got_total_items_msg('Chrome Device Telemetry', '...\n') devices = gapi.get_all_pages(cm.customers().telemetry().devices(), 'list', 'devices', page_message=page_message, parent=parent, filter=filter_, readMask=readMask) for device in devices: if 'totalDiskBytes' in device.get( 'storageInfo', {}) and 'availableDiskBytes' in device.get( 'storageInfo', {}): disk_avail = int(device['storageInfo']['availableDiskBytes']) disk_size = int(device['storageInfo']['totalDiskBytes']) if diskpercentonly: device['storageInfo'] = {} device['storageInfo']['percentDiskFree'] = int( (disk_avail / disk_size) * 100) device['storageInfo']['percentDiskUsed'] = 100 - device[ 'storageInfo']['percentDiskFree'] for cpuStatusReport in device.get('cpuStatusReport', []): for tempInfo in cpuStatusReport.pop('cpuTemperatureInfo', []): cpuStatusReport[ f"cpuTemperatureInfo.{tempInfo['label'].strip()}"] = tempInfo[ 'temperatureCelsius'] if showOrgUnitPath: orgUnitId = device.get('orgUnitId') if orgUnitId not in orgUnitIdPathMap: orgUnitIdPathMap[ orgUnitId] = gapi_directory_orgunits.orgunit_from_orgunitid( orgUnitId, cd) device['orgUnitPath'] = orgUnitIdPathMap[orgUnitId] if mode == 'show': for device in devices: display.print_json(device) print() print() else: csvRows = [] titles = [] for device in devices: display.add_row_titles_to_csv_file(utils.flatten_json(device), csvRows, titles) display.write_csv_file(csvRows, titles, 'Telemetry Devices', todrive)
def issue_command(): cd = gapi_directory.build() i, devices = getCrOSDeviceEntity(3, cd) body = {} final_states = ['EXPIRED', 'CANCELLED', 'EXECUTED_BY_CLIENT'] valid_commands = gapi.get_enum_values_minus_unspecified( cd._rootDesc['schemas'] ['DirectoryChromeosdevicesIssueCommandRequest'] ['properties']['commandType']['enum']) command_map = {} for valid_command in valid_commands: v = valid_command.lower().replace('_', '') command_map[v] = valid_command times_to_check_status = 1 doit = False while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'command': command = sys.argv[i+1].lower().replace('_', '') if command not in command_map: controlflow.system_error_exit(2, f'expected command of ' \ f'{", ".join(valid_commands)} got {command}') body['commandType'] = command_map[command] i += 2 if command == 'setvolume': body['payload'] = json.dumps({'volume': sys.argv[i]}) i += 1 elif myarg == 'timestocheckstatus': times_to_check_status = int(sys.argv[i+1]) i += 2 elif myarg == 'doit': doit = True i += 1 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam issuecommand cros') if body['commandType'] == 'WIPE_USERS' and not doit: controlflow.system_error_exit(2, 'wipe_users command requires admin ' \ 'acknowledge user data will be destroyed with the ' \ 'doit argument') if body['commandType'] == 'REMOTE_POWERWASH' and not doit: controlflow.system_error_exit(2, 'remote_powerwash command requires ' \ 'admin acknowledge user data will be destroyed, device will need' \ ' to be reconnected to WiFi and re-enrolled with the doit argument') for device_id in devices: try: result = gapi.call(cd.customer().devices().chromeos(), 'issueCommand', customerId=GC_Values[GC_CUSTOMER_ID], deviceId=device_id, throw_reasons=[gapi_errors.ErrorReason.FOUR_O_O], body=body) except googleapiclient.errors.HttpError: controlflow.system_error_exit(4, '400 response from Google. This ' \ 'usually indicates the devices was not in a state where it will' \ ' accept the command. For example, reboot and take_a_screenshot' \ ' require the device to be in auto-start kiosk app mode.') display.print_json(result) command_id = result.get('commandId') for i in range(0, times_to_check_status): time.sleep(2) result = gapi.call(cd.customer().devices().chromeos().commands(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], deviceId=device_id, commandId=command_id) display.print_json(result) state = result.get('state') if state in final_states: break
def doGetCrosInfo(): cd = gapi_directory.build() i, devices = getCrOSDeviceEntity(3, cd) downloadfile = None targetFolder = GC_Values[GC_DRIVE_DIR] projection = None fieldsList = [] noLists = False startDate = endDate = None listLimit = 0 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'nolists': noLists = True i += 1 elif myarg == 'listlimit': listLimit = gam.getInteger(sys.argv[i + 1], myarg, minVal=-1) i += 2 elif myarg in CROS_START_ARGUMENTS: startDate = _getFilterDate(sys.argv[i + 1]) i += 2 elif myarg in CROS_END_ARGUMENTS: endDate = _getFilterDate(sys.argv[i + 1]) i += 2 elif myarg == 'allfields': projection = 'FULL' fieldsList = [] i += 1 elif myarg in PROJECTION_CHOICES_MAP: projection = PROJECTION_CHOICES_MAP[myarg] if projection == 'FULL': fieldsList = [] else: fieldsList = CROS_BASIC_FIELDS_LIST[:] i += 1 elif myarg in CROS_ARGUMENT_TO_PROPERTY_MAP: fieldsList.extend(CROS_ARGUMENT_TO_PROPERTY_MAP[myarg]) i += 1 elif myarg == 'fields': fieldNameList = sys.argv[i + 1] for field in fieldNameList.lower().replace(',', ' ').split(): if field in CROS_ARGUMENT_TO_PROPERTY_MAP: fieldsList.extend(CROS_ARGUMENT_TO_PROPERTY_MAP[field]) if field in CROS_ACTIVE_TIME_RANGES_ARGUMENTS + \ CROS_DEVICE_FILES_ARGUMENTS + \ CROS_RECENT_USERS_ARGUMENTS: projection = 'FULL' noLists = False else: controlflow.invalid_argument_exit(field, 'gam info cros fields') i += 2 elif myarg == 'downloadfile': downloadfile = sys.argv[i + 1] if downloadfile.lower() == 'latest': downloadfile = downloadfile.lower() i += 2 elif myarg == 'targetfolder': targetFolder = os.path.expanduser(sys.argv[i + 1]) if not os.path.isdir(targetFolder): os.makedirs(targetFolder) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam info cros') if fieldsList: fieldsList.append('deviceId') fields = ','.join(set(fieldsList)).replace('.', '/') else: fields = None i = 0 device_count = len(devices) for deviceId in devices: i += 1 cros = gapi.call(cd.chromeosdevices(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], deviceId=deviceId, projection=projection, fields=fields) print(f'CrOS Device: {deviceId} ({i} of {device_count})') if 'notes' in cros: cros['notes'] = cros['notes'].replace('\n', '\\n') if 'autoUpdateExpiration' in cros: cros['autoUpdateExpiration'] = utils.formatTimestampYMD( cros['autoUpdateExpiration']) _checkTPMVulnerability(cros) for up in CROS_SCALAR_PROPERTY_PRINT_ORDER: if up in cros: if isinstance(cros[up], str): print(f' {up}: {cros[up]}') else: sys.stdout.write(f' {up}:') display.print_json(cros[up], ' ') if not noLists: activeTimeRanges = _filterTimeRanges( cros.get('activeTimeRanges', []), startDate, endDate) lenATR = len(activeTimeRanges) if lenATR: print(' activeTimeRanges') num_ranges = min(lenATR, listLimit or lenATR) for activeTimeRange in activeTimeRanges[:num_ranges]: active_date = activeTimeRange['date'] active_time = activeTimeRange['activeTime'] duration = utils.formatMilliSeconds(active_time) minutes = active_time // 60000 print(f' date: {active_date}') print(f' activeTime: {active_time}') print(f' duration: {duration}') print(f' minutes: {minutes}') recentUsers = cros.get('recentUsers', []) lenRU = len(recentUsers) if lenRU: print(' recentUsers') num_ranges = min(lenRU, listLimit or lenRU) for recentUser in recentUsers[:num_ranges]: useremail = recentUser.get('email') if not useremail: if recentUser['type'] == 'USER_TYPE_UNMANAGED': useremail = 'UnmanagedUser' else: useremail = 'Unknown' print(f' type: {recentUser["type"]}') print(f' email: {useremail}') deviceFiles = _filterCreateReportTime(cros.get('deviceFiles', []), 'createTime', startDate, endDate) lenDF = len(deviceFiles) if lenDF: num_ranges = min(lenDF, listLimit or lenDF) print(' deviceFiles') for deviceFile in deviceFiles[:num_ranges]: device_type = deviceFile['type'] create_time = deviceFile['createTime'] print(f' {device_type}: {create_time}') if downloadfile: deviceFiles = cros.get('deviceFiles', []) lenDF = len(deviceFiles) if lenDF: if downloadfile == 'latest': deviceFile = deviceFiles[-1] else: for deviceFile in deviceFiles: if deviceFile['createTime'] == downloadfile: break else: print(f'ERROR: file {downloadfile} not ' \ f'available to download.') deviceFile = None if deviceFile: created = deviceFile['createTime'] downloadfile = f'cros-logs-{deviceId}-{created}.zip' downloadfilename = os.path.join( targetFolder, downloadfile) dl_url = deviceFile['downloadUrl'] _, content = cd._http.request(dl_url) fileutils.write_file(downloadfilename, content, mode='wb', continue_on_error=True) print(f'Downloaded: {downloadfilename}') elif downloadfile: print('ERROR: no files to download.') cpuStatusReports = _filterCreateReportTime( cros.get('cpuStatusReports', []), 'reportTime', startDate, endDate) lenCSR = len(cpuStatusReports) if lenCSR: print(' cpuStatusReports') num_ranges = min(lenCSR, listLimit or lenCSR) for cpuStatusReport in cpuStatusReports[:num_ranges]: print(f' reportTime: {cpuStatusReport["reportTime"]}') print(' cpuTemperatureInfo') tempInfos = cpuStatusReport.get('cpuTemperatureInfo', []) for tempInfo in tempInfos: temp_label = tempInfo['label'].strip() temperature = tempInfo['temperature'] print(f' {temp_label}: {temperature}') if 'cpuUtilizationPercentageInfo' in cpuStatusReport: pct_info = cpuStatusReport[ 'cpuUtilizationPercentageInfo'] util = ','.join([str(x) for x in pct_info]) print(f' cpuUtilizationPercentageInfo: {util}') diskVolumeReports = cros.get('diskVolumeReports', []) lenDVR = len(diskVolumeReports) if lenDVR: print(' diskVolumeReports') print(' volumeInfo') num_ranges = min(lenDVR, listLimit or lenDVR) for diskVolumeReport in diskVolumeReports[:num_ranges]: volumeInfo = diskVolumeReport['volumeInfo'] for volume in volumeInfo: vid = volume['volumeId'] vstorage_free = volume['storageFree'] vstorage_total = volume['storageTotal'] print(f' volumeId: {vid}') print(f' storageFree: {vstorage_free}') print(f' storageTotal: {vstorage_total}') systemRamFreeReports = _filterCreateReportTime( cros.get('systemRamFreeReports', []), 'reportTime', startDate, endDate) lenSRFR = len(systemRamFreeReports) if lenSRFR: print(' systemRamFreeReports') num_ranges = min(lenSRFR, listLimit or lenSRFR) for systemRamFreeReport in systemRamFreeReports[:num_ranges]: report_time = systemRamFreeReport['reportTime'] free_info = systemRamFreeReport['systemRamFreeInfo'] free_ram = ','.join(free_info) print(f' reportTime: {report_time}') print(f' systemRamFreeInfo: {free_ram}')
def createExport(): v = buildGAPIObject() allowed_corpuses = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['corpus']['enum']) allowed_scopes = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['Query']['properties']['dataScope']['enum']) allowed_formats = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['MailExportOptions']['properties'] ['exportFormat']['enum']) export_format = 'MBOX' showConfidentialModeContent = None # default to not even set matterId = None body = {'query': {'dataScope': 'ALL_DATA'}, 'exportOptions': {}} i = 3 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'matter': matterId = getMatterItem(v, sys.argv[i + 1]) body['matterId'] = matterId i += 2 elif myarg == 'name': body['name'] = sys.argv[i + 1] i += 2 elif myarg == 'corpus': body['query']['corpus'] = sys.argv[i + 1].upper() if body['query']['corpus'] not in allowed_corpuses: controlflow.expected_argument_exit('corpus', ', '.join(allowed_corpuses), sys.argv[i + 1]) i += 2 elif myarg in VAULT_SEARCH_METHODS_MAP: if body['query'].get('searchMethod'): message = f'Multiple search methods ' \ f'({", ".join(VAULT_SEARCH_METHODS_LIST)})' \ f'specified, only one is allowed' controlflow.system_error_exit(3, message) searchMethod = VAULT_SEARCH_METHODS_MAP[myarg] body['query']['searchMethod'] = searchMethod if searchMethod == 'ACCOUNT': body['query']['accountInfo'] = { 'emails': sys.argv[i + 1].split(',') } i += 2 elif searchMethod == 'ORG_UNIT': body['query']['orgUnitInfo'] = { 'orgUnitId': gam.getOrgUnitId(sys.argv[i + 1])[1] } i += 2 elif searchMethod == 'SHARED_DRIVE': body['query']['sharedDriveInfo'] = { 'sharedDriveIds': sys.argv[i + 1].split(',') } i += 2 elif searchMethod == 'ROOM': body['query']['hangoutsChatInfo'] = { 'roomId': sys.argv[i + 1].split(',') } i += 2 else: i += 1 elif myarg == 'scope': body['query']['dataScope'] = sys.argv[i + 1].upper() if body['query']['dataScope'] not in allowed_scopes: controlflow.expected_argument_exit('scope', ', '.join(allowed_scopes), sys.argv[i + 1]) i += 2 elif myarg in ['terms']: body['query']['terms'] = sys.argv[i + 1] i += 2 elif myarg in ['start', 'starttime']: body['query']['startTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i + 1]) i += 2 elif myarg in ['end', 'endtime']: body['query']['endTime'] = utils.get_date_zero_time_or_full_time( sys.argv[i + 1]) i += 2 elif myarg in ['timezone']: body['query']['timeZone'] = sys.argv[i + 1] i += 2 elif myarg in ['excludedrafts']: body['query']['mailOptions'] = { 'excludeDrafts': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 elif myarg in ['driveversiondate']: body['query'].setdefault('driveOptions', {})['versionDate'] = \ utils.get_date_zero_time_or_full_time(sys.argv[i+1]) i += 2 elif myarg in ['includeshareddrives', 'includeteamdrives']: body['query'].setdefault( 'driveOptions', {})['includeSharedDrives'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['includerooms']: body['query']['hangoutsChatOptions'] = { 'includeRooms': gam.getBoolean(sys.argv[i + 1], myarg) } i += 2 elif myarg in ['format']: export_format = sys.argv[i + 1].upper() if export_format not in allowed_formats: controlflow.expected_argument_exit('export format', ', '.join(allowed_formats), export_format) i += 2 elif myarg in ['showconfidentialmodecontent']: showConfidentialModeContent = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 elif myarg in ['region']: allowed_regions = gapi.get_enum_values_minus_unspecified( v._rootDesc['schemas']['ExportOptions']['properties']['region'] ['enum']) body['exportOptions']['region'] = sys.argv[i + 1].upper() if body['exportOptions']['region'] not in allowed_regions: controlflow.expected_argument_exit( 'region', ', '.join(allowed_regions), body['exportOptions']['region']) i += 2 elif myarg in ['includeaccessinfo']: body['exportOptions'].setdefault( 'driveOptions', {})['includeAccessInfo'] = gam.getBoolean( sys.argv[i + 1], myarg) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam create export') if not matterId: controlflow.system_error_exit( 3, 'you must specify a matter for the new export.') if 'corpus' not in body['query']: controlflow.system_error_exit(3, f'you must specify a corpus for the ' \ f'new export. Choose one of {", ".join(allowed_corpuses)}') if 'searchMethod' not in body['query']: controlflow.system_error_exit(3, f'you must specify a search method ' \ 'for the new export. Choose one of ' \ f'{", ".join(VAULT_SEARCH_METHODS_LIST)}') if 'name' not in body: corpus_name = body['query']['corpus'] corpus_date = datetime.datetime.now() body['name'] = f'GAM {corpus_name} export - {corpus_date}' options_field = None if body['query']['corpus'] == 'MAIL': options_field = 'mailOptions' elif body['query']['corpus'] == 'GROUPS': options_field = 'groupsOptions' elif body['query']['corpus'] == 'HANGOUTS_CHAT': options_field = 'hangoutsChatOptions' if options_field: body['exportOptions'].pop('driveOptions', None) body['exportOptions'][options_field] = {'exportFormat': export_format} if showConfidentialModeContent is not None: body['exportOptions'][options_field][ 'showConfidentialModeContent'] = showConfidentialModeContent results = gapi.call(v.matters().exports(), 'create', matterId=matterId, body=body) print(f'Created export {results["id"]}') display.print_json(results)
def update_state(): ci = gapi_cloudidentity.build_dwd() gapi_directory_customer.setTrueCustomerId() customer = _get_device_customerid() customer_id = customer[10:] client_id = f'{customer_id}-gam' body = {} i, deviceuser = _get_deviceuser_name() while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'clientid': client_id = f'{customer_id}-{sys.argv[i+1]}' i += 2 elif myarg in ['assettag', 'assettags']: body['assetTags'] = gam.shlexSplitList(sys.argv[i + 1]) if body['assetTags'] == ['clear']: # TODO: this doesn't work to clear # existing values. Figure out why. body['assetTags'] = [None] i += 2 elif myarg in ['compliantstate', 'compliancestate']: comp_states = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['complianceState']['enum']) body['complianceState'] = sys.argv[i + 1].upper() if body['complianceState'] not in comp_states: controlflow.expected_argument_exit('compliant_state', ', '.join(comp_states), sys.argv[i + 1]) i += 2 elif myarg == 'customid': body['customId'] = sys.argv[i + 1] i += 2 elif myarg == 'healthscore': health_scores = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['healthScore']['enum']) body['healthScore'] = sys.argv[i + 1].upper() if body['healthScore'] == 'CLEAR': body['healthScore'] = None if body['healthScore'] and body['healthScore'] not in health_scores: controlflow.expected_argument_exit('health_score', ', '.join(health_scores), sys.argv[i + 1]) i += 2 elif myarg == 'customvalue': allowed_types = ['bool', 'number', 'string'] value_type = sys.argv[i + 1].lower() if value_type not in allowed_types: controlflow.expected_argument_exit('custom_value', ', '.join(allowed_types), sys.argv[i + 1]) key = sys.argv[i + 2] value = sys.argv[i + 3] if value_type == 'bool': value = gam.getBoolean(value, key) elif value_type == 'number': value = int(value) body.setdefault('keyValuePairs', {}) body['keyValuePairs'][key] = {f'{value_type}Value': value} i += 4 elif myarg in ['managedstate']: managed_states = gapi.get_enum_values_minus_unspecified( ci._rootDesc['schemas'] ['GoogleAppsCloudidentityDevicesV1ClientState']['properties'] ['managed']['enum']) body['managed'] = sys.argv[i + 1].upper() if body['managed'] == 'CLEAR': body['managed'] = None if body['managed'] and body['managed'] not in managed_states: controlflow.expected_argument_exit('managed_state', ', '.join(managed_states), sys.argv[i + 1]) i += 2 elif myarg in ['scorereason']: body['scoreReason'] = sys.argv[i + 1] if body['scoreReason'] == 'clear': body['scoreReason'] = None i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam update deviceuserstate') name = f'{deviceuser}/clientStates/{client_id}' updateMask = ','.join(body.keys()) result = gapi.call(ci.devices().deviceUsers().clientStates(), 'patch', name=name, customer=customer, updateMask=updateMask, body=body) display.print_json(result)