def create(): cd = gapi_directory.build() body = {'roleName': sys.argv[3]} i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower() if myarg == 'privileges': getPrivileges(body, sys.argv[i + 1].upper(), 'create') i += 2 elif myarg == 'description': body['roleDescription'] = sys.argv[i + 1] i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam create adminrole') if not body.get('rolePrivileges'): controlflow.missing_argument_exit('privileges', 'gam create adminrole') print(f'Creating role {body["roleName"]}') gapi.call(cd.roles(), 'insert', customer=GC_Values[GC_CUSTOMER_ID], body=body)
def issue_command(): cd = gapi_directory.build() i, devices = getCrOSDeviceEntity(3, cd) body = {} 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 'commandType' not in body: controlflow.missing_argument_exit('command <CrOSCommand>', '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, set_volume and take_a_screenshot' \ ' require the device to be in auto-start kiosk app mode.') command_id = result.get('commandId') _display_cros_command_result(cd, device_id, command_id, times_to_check_status)
def move(): cbcm = build() body = {'resource_ids': []} i = 3 resource_ids = [] batch_size = 600 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'ids': resource_ids.extend(sys.argv[i + 1].split(',')) i += 2 elif myarg == 'query': query = sys.argv[i + 1] page_message = gapi.got_total_items_msg('Browsers', '...\n') browsers = gapi.get_all_pages(cbcm.chromebrowsers(), 'list', 'browsers', page_message=page_message, customer=GC_Values[GC_CUSTOMER_ID], query=query, projection='BASIC', fields='browsers(deviceId),nextPageToken') ids = [browser['deviceId'] for browser in browsers] resource_ids.extend(ids) i += 2 elif myarg == 'file': with fileutils.open_file(sys.argv[i+1], strip_utf_bom=True) as filed: for row in filed: rid = row.strip() if rid: resource_ids.append(rid) i += 2 elif myarg == 'csvfile': drive, fname_column = os.path.splitdrive(sys.argv[i+1]) if fname_column.find(':') == -1: controlflow.system_error_exit( 2, 'Expected csvfile FileName:FieldName') (filename, column) = fname_column.split(':') with fileutils.open_file(drive + filename) as filed: input_file = csv.DictReader(filed, restval='') if column not in input_file.fieldnames: controlflow.csv_field_error_exit(column, input_file.fieldnames) for row in input_file: rid = row[column].strip() if rid: resource_ids.append(rid) i += 2 elif myarg in ['ou', 'orgunit', 'org']: org_unit = gapi_directory_orgunits.getOrgUnitItem(sys.argv[i + 1]) body['org_unit_path'] = org_unit i += 2 elif myarg == 'batchsize': batch_size = int(sys.argv[i+1]) i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam move browsers') if 'org_unit_path' not in body: controlflow.missing_argument_exit('ou', 'gam move browsers') elif not resource_ids: controlflow.missing_argument_exit('query or ids', 'gam move browsers') # split moves into max 600 devices per batch for chunk in range(0, len(resource_ids), batch_size): body['resource_ids'] = resource_ids[chunk:chunk + batch_size] print(f' moving {len(body["resource_ids"])} browsers to ' \ f'{body["org_unit_path"]}') gapi.call(cbcm.chromebrowsers(), 'moveChromeBrowsersToOu', customer=GC_Values[GC_CUSTOMER_ID], body=body)
def showUsageParameters(): rep = buildGAPIObject() throw_reasons = [ gapi.errors.ErrorReason.INVALID, gapi.errors.ErrorReason.BAD_REQUEST ] todrive = False if len(sys.argv) == 3: controlflow.missing_argument_exit('user or customer', 'report usageparameters') report = sys.argv[3].lower() titles = ['parameter'] if report == 'customer': endpoint = rep.customerUsageReports() kwargs = {} elif report == 'user': endpoint = rep.userUsageReport() kwargs = {'userKey': gam._getValueFromOAuth('email')} else: controlflow.expected_argument_exit('usageparameters', ['user', 'customer'], report) customerId = GC_Values[GC_CUSTOMER_ID] if customerId == MY_CUSTOMER: customerId = None tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT) all_parameters = set() i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'todrive': todrive = True i += 1 else: controlflow.invalid_argument_exit(sys.argv[i], 'gam report usageparameters') fullDataRequired = ['all'] while True: try: result = gapi.call(endpoint, 'get', throw_reasons=throw_reasons, date=tryDate, customerId=customerId, fields='warnings,usageReports(parameters(name))', **kwargs) warnings = result.get('warnings', []) usage = result.get('usageReports') has_reports = bool(usage) fullData, tryDate = _check_full_data_available( warnings, tryDate, fullDataRequired, has_reports) if fullData < 0: print('No usage parameters available.') sys.exit(1) if has_reports: for parameter in usage[0]['parameters']: name = parameter.get('name') if name: all_parameters.add(name) if fullData == 1: break except gapi.errors.GapiInvalidError as e: tryDate = _adjust_date(str(e)) csvRows = [] for parameter in sorted(all_parameters): csvRows.append({'parameter': parameter}) display.write_csv_file(csvRows, titles, f'{report.capitalize()} Report Usage Parameters', todrive)
def showUsage(): rep = buildGAPIObject() throw_reasons = [ gapi.errors.ErrorReason.INVALID, gapi.errors.ErrorReason.BAD_REQUEST ] todrive = False if len(sys.argv) == 3: controlflow.missing_argument_exit('user or customer', 'report usage') report = sys.argv[3].lower() titles = ['date'] if report == 'customer': endpoint = rep.customerUsageReports() kwargs = [{}] elif report == 'user': endpoint = rep.userUsageReport() kwargs = [{'userKey': 'all'}] titles.append('user') else: controlflow.expected_argument_exit('usage', ['user', 'customer'], report) customerId = GC_Values[GC_CUSTOMER_ID] if customerId == MY_CUSTOMER: customerId = None parameters = [] start_date = end_date = orgUnitId = None skip_day_numbers = [] skip_dates = set() one_day = datetime.timedelta(days=1) i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'startdate': start_date = utils.get_yyyymmdd(sys.argv[i + 1], returnDateTime=True) i += 2 elif myarg == 'enddate': end_date = utils.get_yyyymmdd(sys.argv[i + 1], returnDateTime=True) i += 2 elif myarg == 'todrive': todrive = True i += 1 elif myarg in ['fields', 'parameters']: parameters = sys.argv[i + 1].split(',') i += 2 elif myarg == 'skipdates': for skip in sys.argv[i + 1].split(','): if skip.find(':') == -1: skip_dates.add(utils.get_yyyymmdd(skip, returnDateTime=True)) else: skip_start, skip_end = skip.split(':', 1) skip_start = utils.get_yyyymmdd(skip_start, returnDateTime=True) skip_end = utils.get_yyyymmdd(skip_end, returnDateTime=True) while skip_start <= skip_end: skip_dates.add(skip_start) skip_start += one_day i += 2 elif myarg == 'skipdaysofweek': skipdaynames = sys.argv[i + 1].split(',') dow = [d.lower() for d in calendar.day_abbr] skip_day_numbers = [dow.index(d) for d in skipdaynames if d in dow] i += 2 elif report == 'user' and myarg in ['orgunit', 'org', 'ou']: _, orgUnitId = gam.getOrgUnitId(sys.argv[i + 1]) i += 2 elif report == 'user' and myarg in usergroup_types: users = gam.getUsersToModify(myarg, sys.argv[i + 1]) kwargs = [{'userKey': user} for user in users] i += 2 else: controlflow.invalid_argument_exit(sys.argv[i], f'gam report usage {report}') if parameters: titles.extend(parameters) parameters = ','.join(parameters) else: parameters = None if not end_date: end_date = datetime.datetime.now() if not start_date: start_date = end_date + relativedelta(months=-1) if orgUnitId: for kw in kwargs: kw['orgUnitID'] = orgUnitId usage_on_date = start_date start_date = usage_on_date.strftime(YYYYMMDD_FORMAT) usage_end_date = end_date end_date = end_date.strftime(YYYYMMDD_FORMAT) start_use_date = end_use_date = None csvRows = [] while usage_on_date <= usage_end_date: if usage_on_date.weekday() in skip_day_numbers or \ usage_on_date in skip_dates: usage_on_date += one_day continue use_date = usage_on_date.strftime(YYYYMMDD_FORMAT) usage_on_date += one_day try: for kwarg in kwargs: try: usage = gapi.get_all_pages(endpoint, 'get', 'usageReports', throw_reasons=throw_reasons, customerId=customerId, date=use_date, parameters=parameters, **kwarg) except gapi.errors.GapiBadRequestError: continue for entity in usage: row = {'date': use_date} if 'userEmail' in entity['entity']: row['user'] = entity['entity']['userEmail'] for item in entity.get('parameters', []): if 'name' not in item: continue name = item['name'] if name == 'cros:device_version_distribution': for cros_ver in item['msgValue']: v = cros_ver['version_number'] column_name = f'cros:num_devices_chrome_{v}' if column_name not in titles: titles.append(column_name) row[column_name] = cros_ver['num_devices'] else: if not name in titles: titles.append(name) for ptype in REPORTS_PARAMETERS_SIMPLE_TYPES: if ptype in item: row[name] = item[ptype] break else: row[name] = '' if not start_use_date: start_use_date = use_date end_use_date = use_date csvRows.append(row) except gapi.errors.GapiInvalidError as e: display.print_warning(str(e)) break if start_use_date: report_name = f'{report.capitalize()} Usage Report - {start_use_date}:{end_use_date}' else: report_name = f'{report.capitalize()} Usage Report - {start_date}:{end_date} - No Data' display.write_csv_file(csvRows, titles, report_name, todrive)
def showUsageParameters(): rep = buildGAPIObject() throw_reasons = [ gapi.errors.ErrorReason.INVALID, gapi.errors.ErrorReason.BAD_REQUEST ] todrive = False if len(sys.argv) == 3: controlflow.missing_argument_exit('user or customer', 'report usageparameters') report = sys.argv[3].lower() titles = ['parameter'] if report == 'customer': endpoint = rep.customerUsageReports() kwargs = {} elif report == 'user': endpoint = rep.userUsageReport() kwargs = {'userKey': gam._getValueFromOAuth('email')} else: controlflow.expected_argument_exit('usageparameters', ['user', 'customer'], report) customerId = GC_Values[GC_CUSTOMER_ID] if customerId == MY_CUSTOMER: customerId = None tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT) partial_apps = [] all_parameters = [] one_day = datetime.timedelta(days=1) i = 4 while i < len(sys.argv): myarg = sys.argv[i].lower().replace('_', '') if myarg == 'todrive': todrive = True i += 1 else: controlflow.invalid_argument_exit(sys.argv[i], "gam report usageparameters") while True: try: response = gapi.call(endpoint, 'get', throw_reasons=throw_reasons, date=tryDate, customerId=customerId, **kwargs) partial_on_thisday = [] for warning in response.get('warnings', []): for data in warning.get('data', []): if data.get('key') == 'application': partial_on_thisday.append(data['value']) if partial_apps: partial_apps = [ app for app in partial_apps if app in partial_on_thisday ] else: partial_apps = partial_on_thisday for parameter in response['usageReports'][0]['parameters']: name = parameter.get('name') if name and name not in all_parameters: all_parameters.append(name) if not partial_apps: break tryDate = (utils.get_yyyymmdd(tryDate, returnDateTime=True) - \ one_day).strftime(YYYYMMDD_FORMAT) except gapi.errors.GapiInvalidError as e: tryDate = _adjust_date(str(e)) all_parameters.sort() csvRows = [] for parameter in all_parameters: csvRows.append({'parameter': parameter}) display.write_csv_file(csvRows, titles, f'{report.capitalize()} Report Usage Parameters', todrive)