Пример #1
0
def addACL(function):
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    myarg = sys.argv[4].lower().replace('_', '')
    if myarg not in CALENDAR_ACL_ROLES_MAP:
        controlflow.expected_argument_exit("Role",
                                           ", ".join(CALENDAR_ACL_ROLES_MAP),
                                           myarg)
    body = {'role': CALENDAR_ACL_ROLES_MAP[myarg]}
    i = _getCalendarACLScope(5, body)
    sendNotifications = True
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'sendnotifications':
            sendNotifications = __main__.getBoolean(sys.argv[i + 1], myarg)
            i += 2
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], f"gam calendar <email> {function.lower()}")
    print(f'Calendar: {calendarId}, {function} ACL: {formatACLRule(body)}')
    gapi.call(cal.acl(),
              'insert',
              calendarId=calendarId,
              body=body,
              sendNotifications=sendNotifications)
Пример #2
0
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 = __main__.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 = __main__.convertUIDtoEmailAddress(
                uid, cd, [account_type])
            results['accounts'][i]['email'] = acct_email
    if 'orgUnit' in results:
        results['orgUnit']['orgUnitPath'] = __main__.doGetOrgInfo(
            results['orgUnit']['orgUnitId'], return_attrib='orgUnitPath')
    display.print_json(results)
Пример #3
0
def updateMatter(action=None):
    v = buildGAPIObject()
    matterId = getMatterItem(v, sys.argv[3])
    body = {}
    action_kwargs = {'body': {}}
    add_collaborators = []
    remove_collaborators = []
    cd = None
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'action':
            action = sys.argv[i+1].lower()
            if action not in VAULT_MATTER_ACTIONS:
                controlflow.system_error_exit(3, f'allowed actions are ' \
                    f'{", ".join(VAULT_MATTER_ACTIONS)}, got {action}')
            i += 2
        elif myarg == 'name':
            body['name'] = sys.argv[i+1]
            i += 2
        elif myarg == 'description':
            body['description'] = sys.argv[i+1]
            i += 2
        elif myarg in ['addcollaborator', 'addcollaborators']:
            if not cd:
                cd = __main__.buildGAPIObject('directory')
            add_collaborators.extend(validateCollaborators(sys.argv[i+1], cd))
            i += 2
        elif myarg in ['removecollaborator', 'removecollaborators']:
            if not cd:
                cd = __main__.buildGAPIObject('directory')
            remove_collaborators.extend(
                validateCollaborators(sys.argv[i+1], cd))
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i], "gam update matter")
    if action == 'delete':
        action_kwargs = {}
    if body:
        print(f'Updating matter {sys.argv[3]}...')
        if 'name' not in body or 'description' not in body:
            # bah, API requires name/description to be sent
            # on update even when it's not changing
            result = gapi.call(v.matters(), 'get',
                               matterId=matterId, view='BASIC')
            body.setdefault('name', result['name'])
            body.setdefault('description', result.get('description'))
        gapi.call(v.matters(), 'update', body=body, matterId=matterId)
    if action:
        print(f'Performing {action} on matter {sys.argv[3]}')
        gapi.call(v.matters(), action, matterId=matterId, **action_kwargs)
    for collaborator in add_collaborators:
        print(f' adding collaborator {collaborator["email"]}')
        body = {'matterPermission': {'role': 'COLLABORATOR',
                                     'accountId': collaborator['id']}}
        gapi.call(v.matters(), 'addPermissions', matterId=matterId, body=body)
    for collaborator in remove_collaborators:
        print(f' removing collaborator {collaborator["email"]}')
        gapi.call(v.matters(), 'removePermissions', matterId=matterId,
                  body={'accountId': collaborator['id']})
Пример #4
0
def createMatter():
    v = buildGAPIObject()
    matter_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    body = {'name': f'New Matter - {matter_time}'}
    collaborators = []
    cd = None
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'name':
            body['name'] = sys.argv[i+1]
            i += 2
        elif myarg == 'description':
            body['description'] = sys.argv[i+1]
            i += 2
        elif myarg in ['collaborator', 'collaborators']:
            if not cd:
                cd = __main__.buildGAPIObject('directory')
            collaborators.extend(validateCollaborators(sys.argv[i+1], cd))
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i], "gam create matter")
    matterId = gapi.call(v.matters(), 'create', body=body,
                         fields='matterId')['matterId']
    print(f'Created matter {matterId}')
    for collaborator in collaborators:
        print(f' adding collaborator {collaborator["email"]}')
        body = {'matterPermission': {
            'role': 'COLLABORATOR',
            'accountId': collaborator['id']}}
        gapi.call(v.matters(), 'addPermissions', matterId=matterId, body=body)
Пример #5
0
def printMatters():
    v = buildGAPIObject()
    todrive = False
    csvRows = []
    initialTitles = ['matterId', 'name', 'description', 'state']
    titles = initialTitles[:]
    view = 'FULL'
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in PROJECTION_CHOICES_MAP:
            view = PROJECTION_CHOICES_MAP[myarg]
            i += 1
        else:
            controlflow.invalid_argument_exit(myarg, "gam print matters")
    __main__.printGettingAllItems('Vault Matters', None)
    page_message = gapi.got_total_items_msg('Vault Matters', '...\n')
    matters = gapi.get_all_pages(v.matters(),
                                 'list',
                                 'matters',
                                 page_message=page_message,
                                 view=view)
    for matter in matters:
        display.add_row_titles_to_csv_file(utils.flatten_json(matter), csvRows,
                                           titles)
    display.sort_csv_titles(initialTitles, titles)
    display.write_csv_file(csvRows, titles, 'Vault Matters', todrive)
Пример #6
0
def doUpdateCustomer():
    cd = gapi.directory.buildGAPIObject()
    body = {}
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ADDRESS_FIELDS_ARGUMENT_MAP:
            body.setdefault('postalAddress', {})
            arg = ADDRESS_FIELDS_ARGUMENT_MAP[myarg]
            body['postalAddress'][arg] = sys.argv[i + 1]
            i += 2
        elif myarg in ['adminsecondaryemail', 'alternateemail']:
            body['alternateEmail'] = sys.argv[i + 1]
            i += 2
        elif myarg in ['phone', 'phonenumber']:
            body['phoneNumber'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'language':
            body['language'] = sys.argv[i + 1]
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg, "gam update customer")
    if not body:
        controlflow.system_error_exit(
            2, 'no arguments specified for "gam '
            'update customer"')
    gapi.call(cd.customers(),
              'patch',
              customerKey=GC_Values[GC_CUSTOMER_ID],
              body=body)
    print('Updated customer')
Пример #7
0
def _getBuildingAttributes(args, body={}):
    i = 0
    while i < len(args):
        myarg = args[i].lower().replace('_', '')
        if myarg == 'id':
            body['buildingId'] = args[i + 1]
            i += 2
        elif myarg == 'name':
            body['buildingName'] = args[i + 1]
            i += 2
        elif myarg in ['lat', 'latitude']:
            if 'coordinates' not in body:
                body['coordinates'] = {}
            body['coordinates']['latitude'] = args[i + 1]
            i += 2
        elif myarg in ['long', 'lng', 'longitude']:
            if 'coordinates' not in body:
                body['coordinates'] = {}
            body['coordinates']['longitude'] = args[i + 1]
            i += 2
        elif myarg == 'description':
            body['description'] = args[i + 1]
            i += 2
        elif myarg == 'floors':
            body['floorNames'] = args[i + 1].split(',')
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg,
                                              "gam create|update building")
    return body
Пример #8
0
def transferSecCals(users):
    target_user = sys.argv[5]
    remove_source_user = sendNotifications = True
    i = 6
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'keepuser':
            remove_source_user = False
            i += 1
        elif myarg == 'sendnotifications':
            sendNotifications = __main__.getBoolean(sys.argv[i + 1], myarg)
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              "gam <users> transfer seccals")
    if remove_source_user:
        target_user, target_cal = buildCalendarGAPIObject(target_user)
        if not target_cal:
            return
    for user in users:
        user, source_cal = buildCalendarGAPIObject(user)
        if not source_cal:
            continue
        calendars = gapi.get_all_pages(source_cal.calendarList(),
                                       'list',
                                       'items',
                                       soft_errors=True,
                                       minAccessRole='owner',
                                       showHidden=True,
                                       fields='items(id),nextPageToken')
        for calendar in calendars:
            calendarId = calendar['id']
            if calendarId.find('@group.calendar.google.com') != -1:
                body = {
                    'role': 'owner',
                    'scope': {
                        'type': 'user',
                        'value': target_user
                    }
                }
                gapi.call(source_cal.acl(),
                          'insert',
                          calendarId=calendarId,
                          body=body,
                          sendNotifications=sendNotifications)
                if remove_source_user:
                    body = {
                        'role': 'none',
                        'scope': {
                            'type': 'user',
                            'value': user
                        }
                    }
                    gapi.call(target_cal.acl(),
                              'insert',
                              calendarId=calendarId,
                              body=body,
                              sendNotifications=sendNotifications)
Пример #9
0
def printEvents():
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    q = showDeleted = showHiddenInvitations = timeMin = \
        timeMax = timeZone = updatedMin = None
    toDrive = False
    titles = []
    csvRows = []
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'query':
            q = sys.argv[i + 1]
            i += 2
        elif myarg == 'includedeleted':
            showDeleted = True
            i += 1
        elif myarg == 'includehidden':
            showHiddenInvitations = True
            i += 1
        elif myarg == 'after':
            timeMin = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'before':
            timeMax = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'timezone':
            timeZone = sys.argv[i + 1]
            i += 2
        elif myarg == 'updated':
            updatedMin = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'todrive':
            toDrive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], "gam calendar <email> printevents")
    page_message = gapi.got_total_items_msg(f'Events for {calendarId}', '')
    results = gapi.get_all_pages(cal.events(),
                                 'list',
                                 'items',
                                 page_message=page_message,
                                 calendarId=calendarId,
                                 q=q,
                                 showDeleted=showDeleted,
                                 showHiddenInvitations=showHiddenInvitations,
                                 timeMin=timeMin,
                                 timeMax=timeMax,
                                 timeZone=timeZone,
                                 updatedMin=updatedMin)
    for result in results:
        row = {'calendarId': calendarId}
        display.add_row_titles_to_csv_file(
            utils.flatten_json(result, flattened=row), csvRows, titles)
    display.sort_csv_titles(['calendarId', 'id', 'summary', 'status'], titles)
    display.write_csv_file(csvRows, titles, 'Calendar Events', toDrive)
Пример #10
0
def _getFeatureAttributes(args, body={}):
    i = 0
    while i < len(args):
        myarg = args[i].lower().replace('_', '')
        if myarg == 'name':
            body['name'] = args[i + 1]
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg,
                                              "gam create|update feature")
    return body
Пример #11
0
def printBuildings():
    to_drive = False
    cd = gapi.directory.buildGAPIObject()
    titles = []
    csvRows = []
    fieldsList = ['buildingId']
    # buildings.list() currently doesn't support paging
    # but should soon, attempt to use it now so we
    # won't break when it's turned on.
    fields = 'nextPageToken,buildings(%s)'
    possible_fields = {}
    for pfield in cd._rootDesc['schemas']['Building']['properties']:
        possible_fields[pfield.lower()] = pfield
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'todrive':
            to_drive = True
            i += 1
        elif myarg == 'allfields':
            fields = None
            i += 1
        elif myarg in possible_fields:
            fieldsList.append(possible_fields[myarg])
            i += 1
        # Allows shorter arguments like "name" instead of "buildingname"
        elif 'building' + myarg in possible_fields:
            fieldsList.append(possible_fields['building' + myarg])
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              "gam print buildings")
    if fields:
        fields = fields % ','.join(fieldsList)
    buildings = gapi.get_all_pages(cd.resources().buildings(),
                                   'list',
                                   'buildings',
                                   customer=GC_Values[GC_CUSTOMER_ID],
                                   fields=fields)
    for building in buildings:
        building.pop('etags', None)
        building.pop('etag', None)
        building.pop('kind', None)
        if 'buildingId' in building:
            building['buildingId'] = f'id:{building["buildingId"]}'
        if 'floorNames' in building:
            building['floorNames'] = ','.join(building['floorNames'])
        building = utils.flatten_json(building)
        for item in building:
            if item not in titles:
                titles.append(item)
        csvRows.append(building)
    display.sort_csv_titles('buildingId', titles)
    display.write_csv_file(csvRows, titles, 'Buildings', to_drive)
Пример #12
0
def downloadExport():
    verifyFiles = True
    extractFiles = True
    v = buildGAPIObject()
    s = storage.build_gapi()
    matterId = getMatterItem(v, sys.argv[3])
    exportId = convertExportNameToID(v, sys.argv[4], matterId)
    targetFolder = GC_Values[GC_DRIVE_DIR]
    i = 5
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'targetfolder':
            targetFolder = os.path.expanduser(sys.argv[i + 1])
            if not os.path.isdir(targetFolder):
                os.makedirs(targetFolder)
            i += 2
        elif myarg == 'noverify':
            verifyFiles = False
            i += 1
        elif myarg == 'noextract':
            extractFiles = False
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              "gam download export")
    export = gapi.call(v.matters().exports(),
                       'get',
                       matterId=matterId,
                       exportId=exportId)
    for s_file in export['cloudStorageSink']['files']:
        bucket = s_file['bucketName']
        s_object = s_file['objectName']
        filename = os.path.join(targetFolder, s_object.replace('/', '-'))
        print(f'saving to {filename}')
        request = s.objects().get_media(bucket=bucket, object=s_object)
        f = fileutils.open_file(filename, 'wb')
        downloader = googleapiclient.http.MediaIoBaseDownload(f, request)
        done = False
        while not done:
            status, done = downloader.next_chunk()
            sys.stdout.write(' Downloaded: {0:>7.2%}\r'.format(
                status.progress()))
            sys.stdout.flush()
        sys.stdout.write('\n Download complete. Flushing to disk...\n')
        fileutils.close_file(f, True)
        if verifyFiles:
            expected_hash = s_file['md5Hash']
            sys.stdout.write(f' Verifying file hash is {expected_hash}...')
            sys.stdout.flush()
            utils.md5_matches_file(filename, expected_hash, True)
            print('VERIFIED')
        if extractFiles and re.search(r'\.zip$', filename):
            __main__.extract_nested_zip(filename, targetFolder)
Пример #13
0
def printHolds():
    v = buildGAPIObject()
    todrive = False
    csvRows = []
    initialTitles = ['matterId', 'holdId', 'name', 'corpus', 'updateTime']
    titles = initialTitles[:]
    matters = []
    matterIds = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in ['matter', 'matters']:
            matters = sys.argv[i + 1].split(',')
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg, "gam print holds")
    if not matters:
        fields = 'matters(matterId,state),nextPageToken'
        matters_results = gapi.get_all_pages(v.matters(),
                                             'list',
                                             'matters',
                                             view='BASIC',
                                             fields=fields)
        for matter in matters_results:
            matterState = matter['state']
            matterId = matter['matterId']
            if matterState != 'OPEN':
                print(f'ignoring matter {matterId} in state {matterState}')
                continue
            matterIds.append(matterId)
    else:
        for matter in matters:
            matterIds.append(getMatterItem(v, matter))
    for matterId in matterIds:
        sys.stderr.write(f'Retrieving holds for matter {matterId}\n')
        holds = gapi.get_all_pages(v.matters().holds(),
                                   'list',
                                   'holds',
                                   matterId=matterId)
        for hold in holds:
            display.add_row_titles_to_csv_file(
                utils.flatten_json(hold, flattened={'matterId': matterId}),
                csvRows, titles)
    display.sort_csv_titles(initialTitles, titles)
    display.write_csv_file(csvRows, titles, 'Vault Holds', todrive)
Пример #14
0
def _getResourceCalendarAttributes(cd, args, body={}):
    i = 0
    while i < len(args):
        myarg = args[i].lower().replace('_', '')
        if myarg == 'name':
            body['resourceName'] = args[i + 1]
            i += 2
        elif myarg == 'description':
            body['resourceDescription'] = args[i + 1].replace('\\n', '\n')
            i += 2
        elif myarg == 'type':
            body['resourceType'] = args[i + 1]
            i += 2
        elif myarg in ['building', 'buildingid']:
            body['buildingId'] = getBuildingByNameOrId(cd,
                                                       args[i + 1],
                                                       minLen=0)
            i += 2
        elif myarg in ['capacity']:
            body['capacity'] = __main__.getInteger(args[i + 1],
                                                   myarg,
                                                   minVal=0)
            i += 2
        elif myarg in ['feature', 'features']:
            features = args[i + 1].split(',')
            body['featureInstances'] = []
            for feature in features:
                instance = {'feature': {'name': feature}}
                body['featureInstances'].append(instance)
            i += 2
        elif myarg in ['floor', 'floorname']:
            body['floorName'] = args[i + 1]
            i += 2
        elif myarg in ['floorsection']:
            body['floorSection'] = args[i + 1]
            i += 2
        elif myarg in ['category']:
            body['resourceCategory'] = args[i + 1].upper()
            if body['resourceCategory'] == 'ROOM':
                body['resourceCategory'] = 'CONFERENCE_ROOM'
            i += 2
        elif myarg in ['uservisibledescription', 'userdescription']:
            body['userVisibleDescription'] = args[i + 1]
            i += 2
        else:
            controlflow.invalid_argument_exit(args[i],
                                              "gam create|update resource")
    return body
Пример #15
0
def printFeatures():
    to_drive = False
    cd = gapi.directory.buildGAPIObject()
    titles = []
    csvRows = []
    fieldsList = ['name']
    fields = 'nextPageToken,features(%s)'
    possible_fields = {}
    for pfield in cd._rootDesc['schemas']['Feature']['properties']:
        possible_fields[pfield.lower()] = pfield
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'todrive':
            to_drive = True
            i += 1
        elif myarg == 'allfields':
            fields = None
            i += 1
        elif myarg in possible_fields:
            fieldsList.append(possible_fields[myarg])
            i += 1
        elif 'feature' + myarg in possible_fields:
            fieldsList.append(possible_fields['feature' + myarg])
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              "gam print features")
    if fields:
        fields = fields % ','.join(fieldsList)
    features = gapi.get_all_pages(cd.resources().features(),
                                  'list',
                                  'features',
                                  customer=GC_Values[GC_CUSTOMER_ID],
                                  fields=fields)
    for feature in features:
        feature.pop('etags', None)
        feature.pop('etag', None)
        feature.pop('kind', None)
        feature = utils.flatten_json(feature)
        for item in feature:
            if item not in titles:
                titles.append(item)
        csvRows.append(feature)
    display.sort_csv_titles('name', titles)
    display.write_csv_file(csvRows, titles, 'Features', to_drive)
Пример #16
0
def printShowCalendars(users, csvFormat):
    if csvFormat:
        todrive = False
        titles = []
        csvRows = []
    i = 5
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if csvFormat and myarg == 'todrive':
            todrive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(
                myarg, f"gam <users> {['show', 'print'][csvFormat]} calendars")
    i = 0
    count = len(users)
    for user in users:
        i += 1
        user, cal = buildCalendarGAPIObject(user)
        if not cal:
            continue
        result = gapi.get_all_pages(cal.calendarList(),
                                    'list',
                                    'items',
                                    soft_errors=True)
        jcount = len(result)
        if not csvFormat:
            print(f'User: {user}, Calendars:{display.current_count(i, count)}')
            if jcount == 0:
                continue
            j = 0
            for userCalendar in result:
                j += 1
                _showCalendar(userCalendar, j, jcount)
        else:
            if jcount == 0:
                continue
            for userCalendar in result:
                row = {'primaryEmail': user}
                display.add_row_titles_to_csv_file(
                    utils.flatten_json(userCalendar, flattened=row), csvRows,
                    titles)
    if csvFormat:
        display.sort_csv_titles(['primaryEmail', 'id'], titles)
        display.write_csv_file(csvRows, titles, 'Calendars', todrive)
Пример #17
0
def deleteHold():
    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 delete hold")
    if not matterId:
        controlflow.system_error_exit(
            3, 'you must specify a matter for the hold.')
    print(f'Deleting hold {hold} / {holdId}')
    gapi.call(v.matters().holds(), 'delete', matterId=matterId, holdId=holdId)
Пример #18
0
def printShowACLs(csvFormat):
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    toDrive = False
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if csvFormat and myarg == 'todrive':
            toDrive = True
            i += 1
        else:
            action = ['showacl', 'printacl'][csvFormat]
            message = f"gam calendar <email> {action}"
            controlflow.invalid_argument_exit(sys.argv[i], message)
    acls = gapi.get_all_pages(cal.acl(),
                              'list',
                              'items',
                              calendarId=calendarId)
    i = 0
    if csvFormat:
        titles = []
        rows = []
    else:
        count = len(acls)
    for rule in acls:
        i += 1
        if csvFormat:
            row = utils.flatten_json(rule, None)
            for key in row:
                if key not in titles:
                    titles.append(key)
            rows.append(row)
        else:
            formatted_acl = formatACLRule(rule)
            current_count = display.current_count(i, count)
            print(
                f'Calendar: {calendarId}, ACL: {formatted_acl}{current_count}')
    if csvFormat:
        display.write_csv_file(rows, titles, f'{calendarId} Calendar ACLs',
                               toDrive)
Пример #19
0
def moveOrDeleteEvent(moveOrDelete):
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    sendUpdates = None
    doit = False
    kwargs = {}
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ['notifyattendees', 'sendnotifications', 'sendupdates']:
            sendUpdates, i = getSendUpdates(myarg, i, cal)
        elif myarg in ['id', 'eventid']:
            eventId = sys.argv[i + 1]
            i += 2
        elif myarg in ['query', 'eventquery']:
            controlflow.system_error_exit(
                2, f'query is no longer supported for {moveOrDelete}event. ' \
                   f'Use "gam calendar <email> printevents query <query> | ' \
                   f'gam csv - gam {moveOrDelete}event id ~id" instead.')
        elif myarg == 'doit':
            doit = True
            i += 1
        elif moveOrDelete == 'move' and myarg == 'destination':
            kwargs['destination'] = sys.argv[i + 1]
            i += 2
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], f"gam calendar <email> {moveOrDelete}event")
    if doit:
        print(f' going to {moveOrDelete} eventId {eventId}')
        gapi.call(cal.events(),
                  moveOrDelete,
                  calendarId=calendarId,
                  eventId=eventId,
                  sendUpdates=sendUpdates,
                  **kwargs)
    else:
        print(
            f' would {moveOrDelete} eventId {eventId}. Add doit to command ' \
            f'to actually {moveOrDelete} event')
Пример #20
0
def printMatters():
    v = buildGAPIObject()
    todrive = False
    csvRows = []
    initialTitles = ['matterId', 'name', 'description', 'state']
    titles = initialTitles[:]
    view = 'FULL'
    state = None
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in PROJECTION_CHOICES_MAP:
            view = PROJECTION_CHOICES_MAP[myarg]
            i += 1
        elif myarg == 'matterstate':
            valid_states = gapi.get_enum_values_minus_unspecified(
                v._rootDesc['schemas']['Matter']['properties']['state'][
                    'enum'])
            state = sys.argv[i+1].upper()
            if state not in valid_states:
                controlflow.expected_argument_exit(
                    'state', ', '.join(valid_states), state)
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg, "gam print matters")
    __main__.printGettingAllItems('Vault Matters', None)
    page_message = gapi.got_total_items_msg('Vault Matters', '...\n')
    matters = gapi.get_all_pages(
        v.matters(), 'list', 'matters', page_message=page_message, view=view,
        state=state)
    for matter in matters:
        display.add_row_titles_to_csv_file(
            utils.flatten_json(matter), csvRows, titles)
    display.sort_csv_titles(initialTitles, titles)
    display.write_csv_file(csvRows, titles, 'Vault Matters', todrive)
Пример #21
0
def printExports():
    v = buildGAPIObject()
    todrive = False
    csvRows = []
    initialTitles = ['matterId', 'id', 'name', 'createTime', 'status']
    titles = initialTitles[:]
    matters = []
    matterIds = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in ['matter', 'matters']:
            matters = sys.argv[i+1].split(',')
            i += 2
        else:
            controlflow.invalid_argument_exit(myarg, "gam print exports")
    if not matters:
        fields = 'matters(matterId),nextPageToken'
        matters_results = gapi.get_all_pages(v.matters(
        ), 'list', 'matters', view='BASIC', state='OPEN', fields=fields)
        for matter in matters_results:
            matterIds.append(matter['matterId'])
    else:
        for matter in matters:
            matterIds.append(getMatterItem(v, matter))
    for matterId in matterIds:
        sys.stderr.write(f'Retrieving exports for matter {matterId}\n')
        exports = gapi.get_all_pages(
            v.matters().exports(), 'list', 'exports', matterId=matterId)
        for export in exports:
            display.add_row_titles_to_csv_file(utils.flatten_json(
                export, flattened={'matterId': matterId}), csvRows, titles)
    display.sort_csv_titles(initialTitles, titles)
    display.write_csv_file(csvRows, titles, 'Vault Exports', todrive)
Пример #22
0
def modifySettings():
    calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
    if not cal:
        return
    body = {}
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'description':
            body['description'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'location':
            body['location'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'summary':
            body['summary'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'timezone':
            body['timeZone'] = sys.argv[i + 1]
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              "gam calendar <email> modify")
    gapi.call(cal.calendars(), 'patch', calendarId=calendarId, body=body)
Пример #23
0
def getCalendarAttributes(i, body, function):
    colorRgbFormat = False
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'selected':
            body['selected'] = __main__.getBoolean(sys.argv[i + 1], myarg)
            i += 2
        elif myarg == 'hidden':
            body['hidden'] = __main__.getBoolean(sys.argv[i + 1], myarg)
            i += 2
        elif myarg == 'summary':
            body['summaryOverride'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'colorindex':
            body['colorId'] = __main__.getInteger(
                sys.argv[i + 1],
                myarg,
                minVal=CALENDAR_MIN_COLOR_INDEX,
                maxVal=CALENDAR_MAX_COLOR_INDEX)
            i += 2
        elif myarg == 'backgroundcolor':
            body['backgroundColor'] = __main__.getColor(sys.argv[i + 1])
            colorRgbFormat = True
            i += 2
        elif myarg == 'foregroundcolor':
            body['foregroundColor'] = __main__.getColor(sys.argv[i + 1])
            colorRgbFormat = True
            i += 2
        elif myarg == 'reminder':
            body.setdefault('defaultReminders', [])
            method = sys.argv[i + 1].lower()
            if method not in CLEAR_NONE_ARGUMENT:
                if method not in CALENDAR_REMINDER_METHODS:
                    controlflow.expected_argument_exit(
                        "Method", ", ".join(CALENDAR_REMINDER_METHODS +
                                            CLEAR_NONE_ARGUMENT), method)
                minutes = __main__.getInteger(
                    sys.argv[i + 2],
                    myarg,
                    minVal=0,
                    maxVal=CALENDAR_REMINDER_MAX_MINUTES)
                body['defaultReminders'].append({
                    'method': method,
                    'minutes': minutes
                })
                i += 3
            else:
                i += 2
        elif myarg == 'notification':
            body.setdefault('notificationSettings', {'notifications': []})
            method = sys.argv[i + 1].lower()
            if method not in CLEAR_NONE_ARGUMENT:
                if method not in CALENDAR_NOTIFICATION_METHODS:
                    controlflow.expected_argument_exit(
                        "Method", ", ".join(CALENDAR_NOTIFICATION_METHODS +
                                            CLEAR_NONE_ARGUMENT), method)
                eventType = sys.argv[i + 2].lower()
                if eventType not in CALENDAR_NOTIFICATION_TYPES_MAP:
                    controlflow.expected_argument_exit(
                        "Event", ", ".join(CALENDAR_NOTIFICATION_TYPES_MAP),
                        eventType)
                notice = {
                    'method': method,
                    'type': CALENDAR_NOTIFICATION_TYPES_MAP[eventType]
                }
                body['notificationSettings']['notifications'].append(notice)
                i += 3
            else:
                i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              f"gam {function} calendar")
    return colorRgbFormat
Пример #24
0
def changeAttendees(users):
    do_it = True
    i = 5
    allevents = False
    start_date = end_date = None
    while len(sys.argv) > i:
        myarg = sys.argv[i].lower()
        if myarg == 'csv':
            csv_file = sys.argv[i + 1]
            i += 2
        elif myarg == 'dryrun':
            do_it = False
            i += 1
        elif myarg == 'start':
            start_date = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'end':
            end_date = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'allevents':
            allevents = True
            i += 1
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], "gam <users> update calattendees")
    attendee_map = {}
    f = fileutils.open_file(csv_file)
    csvFile = csv.reader(f)
    for row in csvFile:
        attendee_map[row[0].lower()] = row[1].lower()
    fileutils.close_file(f)
    for user in users:
        sys.stdout.write(f'Checking user {user}\n')
        user, cal = buildCalendarGAPIObject(user)
        if not cal:
            continue
        page_token = None
        while True:
            events_page = gapi.call(cal.events(),
                                    'list',
                                    calendarId=user,
                                    pageToken=page_token,
                                    timeMin=start_date,
                                    timeMax=end_date,
                                    showDeleted=False,
                                    showHiddenInvitations=False)
            print(f'Got {len(events_page.get("items", []))}')
            for event in events_page.get('items', []):
                if event['status'] == 'cancelled':
                    # print u' skipping cancelled event'
                    continue
                try:
                    event_summary = event['summary']
                except (KeyError, UnicodeEncodeError, UnicodeDecodeError):
                    event_summary = event['id']
                try:
                    organizer = event['organizer']['email'].lower()
                    if not allevents and organizer != user:
                        #print(f' skipping not-my-event {event_summary}')
                        continue
                except KeyError:
                    pass  # no email for organizer
                needs_update = False
                try:
                    for attendee in event['attendees']:
                        try:
                            if attendee['email'].lower() in attendee_map:
                                old_email = attendee['email'].lower()
                                new_email = attendee_map[
                                    attendee['email'].lower()]
                                print(f' SWITCHING attendee {old_email} to ' \
                                    f'{new_email} for {event_summary}')
                                event['attendees'].remove(attendee)
                                event['attendees'].append({'email': new_email})
                                needs_update = True
                        except KeyError:  # no email for that attendee
                            pass
                except KeyError:
                    continue  # no attendees
                if needs_update:
                    body = {}
                    body['attendees'] = event['attendees']
                    print(f'UPDATING {event_summary}')
                    if do_it:
                        gapi.call(cal.events(),
                                  'patch',
                                  calendarId=user,
                                  eventId=event['id'],
                                  sendNotifications=False,
                                  body=body)
                    else:
                        print(' not pulling the trigger.')
                # else:
                #  print(f' no update needed for {event_summary}')
            try:
                page_token = events_page['nextPageToken']
            except KeyError:
                break
Пример #25
0
def getEventAttributes(i, calendarId, cal, body, action):
    # Default to external only so non-Google
    # calendars are notified of changes
    sendUpdates = 'externalOnly'
    action = 'update' if body else 'add'
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ['notifyattendees', 'sendnotifications', 'sendupdates']:
            sendUpdates, i = getSendUpdates(myarg, i, cal)
        elif myarg == 'attendee':
            body.setdefault('attendees', [])
            body['attendees'].append({'email': sys.argv[i + 1]})
            i += 2
        elif myarg == 'removeattendee' and action == 'update':
            remove_email = sys.argv[i + 1].lower()
            if 'attendees' in body:
                body['attendees'] = _remove_attendee(body['attendees'],
                                                     remove_email)
            i += 2
        elif myarg == 'optionalattendee':
            body.setdefault('attendees', [])
            body['attendees'].append({
                'email': sys.argv[i + 1],
                'optional': True
            })
            i += 2
        elif myarg == 'anyonecanaddself':
            body['anyoneCanAddSelf'] = True
            i += 1
        elif myarg == 'description':
            body['description'] = sys.argv[i + 1].replace('\\n', '\n')
            i += 2
        elif myarg == 'replacedescription' and action == 'update':
            search = sys.argv[i + 1]
            replace = sys.argv[i + 2]
            if 'description' in body:
                body['description'] = re.sub(search, replace,
                                             body['description'])
            i += 3
        elif myarg == 'start':
            if sys.argv[i + 1].lower() == 'allday':
                body['start'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])}
                i += 3
            else:
                start_time = utils.get_time_or_delta_from_now(sys.argv[i + 1])
                body['start'] = {'dateTime': start_time}
                i += 2
        elif myarg == 'end':
            if sys.argv[i + 1].lower() == 'allday':
                body['end'] = {'date': utils.get_yyyymmdd(sys.argv[i + 2])}
                i += 3
            else:
                end_time = utils.get_time_or_delta_from_now(sys.argv[i + 1])
                body['end'] = {'dateTime': end_time}
                i += 2
        elif myarg == 'guestscantinviteothers':
            body['guestsCanInviteOthers'] = False
            i += 1
        elif myarg == 'guestscaninviteothers':
            body['guestsCanInviteTohters'] = __main__.getBoolean(
                sys.argv[i + 1], 'guestscaninviteothers')
            i += 2
        elif myarg == 'guestscantseeothers':
            body['guestsCanSeeOtherGuests'] = False
            i += 1
        elif myarg == 'guestscanseeothers':
            body['guestsCanSeeOtherGuests'] = __main__.getBoolean(
                sys.argv[i + 1], 'guestscanseeothers')
            i += 2
        elif myarg == 'guestscanmodify':
            body['guestsCanModify'] = __main__.getBoolean(
                sys.argv[i + 1], 'guestscanmodify')
            i += 2
        elif myarg == 'id':
            if action == 'update':
                controlflow.invalid_argument_exit(
                    'id', 'gam calendar <calendar> updateevent')
            body['id'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'summary':
            body['summary'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'location':
            body['location'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'available':
            body['transparency'] = 'transparent'
            i += 1
        elif myarg == 'transparency':
            validTransparency = ['opaque', 'transparent']
            if sys.argv[i + 1].lower() in validTransparency:
                body['transparency'] = sys.argv[i + 1].lower()
            else:
                controlflow.expected_argument_exit(
                    'transparency', ", ".join(validTransparency),
                    sys.argv[i + 1])
            i += 2
        elif myarg == 'visibility':
            validVisibility = ['default', 'public', 'private']
            if sys.argv[i + 1].lower() in validVisibility:
                body['visibility'] = sys.argv[i + 1].lower()
            else:
                controlflow.expected_argument_exit("visibility",
                                                   ", ".join(validVisibility),
                                                   sys.argv[i + 1])
            i += 2
        elif myarg == 'tentative':
            body['status'] = 'tentative'
            i += 1
        elif myarg == 'status':
            validStatus = ['confirmed', 'tentative', 'cancelled']
            if sys.argv[i + 1].lower() in validStatus:
                body['status'] = sys.argv[i + 1].lower()
            else:
                controlflow.expected_argument_exit('visibility',
                                                   ', '.join(validStatus),
                                                   sys.argv[i + 1])
            i += 2
        elif myarg == 'source':
            body['source'] = {'title': sys.argv[i + 1], 'url': sys.argv[i + 2]}
            i += 3
        elif myarg == 'noreminders':
            body['reminders'] = {'useDefault': False}
            i += 1
        elif myarg == 'reminder':
            minutes = \
            __main__.getInteger(sys.argv[i+1], myarg, minVal=0,
                                maxVal=CALENDAR_REMINDER_MAX_MINUTES)
            reminder = {'minutes': minutes, 'method': sys.argv[i + 2]}
            body.setdefault('reminders', {
                'overrides': [],
                'useDefault': False
            })
            body['reminders']['overrides'].append(reminder)
            i += 3
        elif myarg == 'recurrence':
            body.setdefault('recurrence', [])
            body['recurrence'].append(sys.argv[i + 1])
            i += 2
        elif myarg == 'timezone':
            timeZone = sys.argv[i + 1]
            i += 2
        elif myarg == 'privateproperty':
            if 'extendedProperties' not in body:
                body['extendedProperties'] = {'private': {}, 'shared': {}}
            body['extendedProperties']['private'][sys.argv[i +
                                                           1]] = sys.argv[i +
                                                                          2]
            i += 3
        elif myarg == 'sharedproperty':
            if 'extendedProperties' not in body:
                body['extendedProperties'] = {'private': {}, 'shared': {}}
            body['extendedProperties']['shared'][sys.argv[i +
                                                          1]] = sys.argv[i + 2]
            i += 3
        elif myarg == 'colorindex':
            body['colorId'] = __main__.getInteger(
                sys.argv[i + 1], myarg, CALENDAR_EVENT_MIN_COLOR_INDEX,
                CALENDAR_EVENT_MAX_COLOR_INDEX)
            i += 2
        elif myarg == 'hangoutsmeet':
            body['conferenceData'] = {
                'createRequest': {
                    'requestId': f'{str(uuid.uuid4())}'
                }
            }
            i += 1
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], f'gam calendar <email> {action}event')
    if ('recurrence' in body) and (('start' in body) or ('end' in body)):
        if not timeZone:
            timeZone = gapi.call(cal.calendars(),
                                 'get',
                                 calendarId=calendarId,
                                 fields='timeZone')['timeZone']
        if 'start' in body:
            body['start']['timeZone'] = timeZone
        if 'end' in body:
            body['end']['timeZone'] = timeZone
    return (sendUpdates, body)
Пример #26
0
def doPrintCrosDevices():
    def _getSelectedLists(myarg):
        if myarg in CROS_ACTIVE_TIME_RANGES_ARGUMENTS:
            selectedLists['activeTimeRanges'] = True
        elif myarg in CROS_RECENT_USERS_ARGUMENTS:
            selectedLists['recentUsers'] = True
        elif myarg in CROS_DEVICE_FILES_ARGUMENTS:
            selectedLists['deviceFiles'] = True
        elif myarg in CROS_CPU_STATUS_REPORTS_ARGUMENTS:
            selectedLists['cpuStatusReports'] = True
        elif myarg in CROS_DISK_VOLUME_REPORTS_ARGUMENTS:
            selectedLists['diskVolumeReports'] = True
        elif myarg in CROS_SYSTEM_RAM_FREE_REPORTS_ARGUMENTS:
            selectedLists['systemRamFreeReports'] = True

    cd = gapi.directory.buildGAPIObject()
    todrive = False
    fieldsList = []
    fieldsTitles = {}
    titles = []
    csvRows = []
    display.add_field_to_csv_file(
        'deviceid', CROS_ARGUMENT_TO_PROPERTY_MAP, fieldsList, fieldsTitles, titles)
    projection = orderBy = sortOrder = orgUnitPath = None
    queries = [None]
    noLists = sortHeaders = False
    selectedLists = {}
    startDate = endDate = None
    listLimit = 0
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ['query', 'queries']:
            queries = __main__.getQueries(myarg, sys.argv[i+1])
            i += 2
        elif myarg == 'limittoou':
            orgUnitPath = __main__.getOrgUnitItem(sys.argv[i+1])
            i += 2
        elif myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg == 'nolists':
            noLists = True
            selectedLists = {}
            i += 1
        elif myarg == 'listlimit':
            listLimit = __main__.getInteger(sys.argv[i+1], myarg, minVal=0)
            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 == 'orderby':
            orderBy = sys.argv[i+1].lower().replace('_', '')
            validOrderBy = ['location', 'user', 'lastsync',
                            'notes', 'serialnumber', 'status', 'supportenddate']
            if orderBy not in validOrderBy:
                controlflow.expected_argument_exit(
                    "orderby", ", ".join(validOrderBy), orderBy)
            if orderBy == 'location':
                orderBy = 'annotatedLocation'
            elif orderBy == 'user':
                orderBy = 'annotatedUser'
            elif orderBy == 'lastsync':
                orderBy = 'lastSync'
            elif orderBy == 'serialnumber':
                orderBy = 'serialNumber'
            elif orderBy == 'supportenddate':
                orderBy = 'supportEndDate'
            i += 2
        elif myarg in SORTORDER_CHOICES_MAP:
            sortOrder = SORTORDER_CHOICES_MAP[myarg]
            i += 1
        elif myarg in PROJECTION_CHOICES_MAP:
            projection = PROJECTION_CHOICES_MAP[myarg]
            sortHeaders = True
            if projection == 'FULL':
                fieldsList = []
            else:
                fieldsList = CROS_BASIC_FIELDS_LIST[:]
            i += 1
        elif myarg == 'allfields':
            projection = 'FULL'
            sortHeaders = True
            fieldsList = []
            i += 1
        elif myarg == 'sortheaders':
            sortHeaders = True
            i += 1
        elif myarg in CROS_LISTS_ARGUMENTS:
            _getSelectedLists(myarg)
            i += 1
        elif myarg in CROS_ARGUMENT_TO_PROPERTY_MAP:
            display.add_field_to_fields_list(
                myarg, CROS_ARGUMENT_TO_PROPERTY_MAP, fieldsList)
            i += 1
        elif myarg == 'fields':
            fieldNameList = sys.argv[i+1]
            for field in fieldNameList.lower().replace(',', ' ').split():
                if field in CROS_LISTS_ARGUMENTS:
                    _getSelectedLists(field)
                elif field in CROS_ARGUMENT_TO_PROPERTY_MAP:
                    display.add_field_to_fields_list(
                        field, CROS_ARGUMENT_TO_PROPERTY_MAP, fieldsList)
                else:
                    controlflow.invalid_argument_exit(
                        field, "gam print cros fields")
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i], "gam print cros")
    if selectedLists:
        noLists = False
        projection = 'FULL'
        for selectList in selectedLists:
            display.add_field_to_fields_list(
                selectList, CROS_ARGUMENT_TO_PROPERTY_MAP, fieldsList)
    if fieldsList:
        fieldsList.append('deviceId')
        fields = f'nextPageToken,chromeosdevices({",".join(set(fieldsList))})'.replace(
            '.', '/')
    else:
        fields = None
    for query in queries:
        __main__.printGettingAllItems('CrOS Devices', query)
        page_message = gapi.got_total_items_msg('CrOS Devices', '...\n')
        all_cros = gapi.get_all_pages(cd.chromeosdevices(), 'list',
                                      'chromeosdevices',
                                      page_message=page_message, query=query,
                                      customerId=GC_Values[GC_CUSTOMER_ID],
                                      projection=projection,
                                      orgUnitPath=orgUnitPath,
                                      orderBy=orderBy, sortOrder=sortOrder,
                                      fields=fields)
        for cros in all_cros:
            _checkTPMVulnerability(cros)
        if not noLists and not selectedLists:
            for cros in all_cros:
                if 'notes' in cros:
                    cros['notes'] = cros['notes'].replace('\n', '\\n')
                if 'autoUpdateExpiration' in cros:
                    cros['autoUpdateExpiration'] = utils.formatTimestampYMD(
                        cros['autoUpdateExpiration'])
                for cpuStatusReport in cros.get('cpuStatusReports', []):
                    tempInfos = cpuStatusReport.get('cpuTemperatureInfo', [])
                    for tempInfo in tempInfos:
                        tempInfo['label'] = tempInfo['label'].strip()
                display.add_row_titles_to_csv_file(utils.flatten_json(
                    cros, listLimit=listLimit), csvRows, titles)
            continue
        for cros in all_cros:
            if 'notes' in cros:
                cros['notes'] = cros['notes'].replace('\n', '\\n')
            if 'autoUpdateExpiration' in cros:
                cros['autoUpdateExpiration'] = utils.formatTimestampYMD(
                    cros['autoUpdateExpiration'])
            row = {}
            for attrib in cros:
                if attrib not in set(['kind', 'etag', 'tpmVersionInfo',
                                      'recentUsers', 'activeTimeRanges',
                                      'deviceFiles', 'cpuStatusReports',
                                      'diskVolumeReports',
                                      'systemRamFreeReports']):
                    row[attrib] = cros[attrib]
            if selectedLists.get('activeTimeRanges'):
                timergs = cros.get('activeTimeRanges', [])
            else:
                timergs = []
            activeTimeRanges = _filterTimeRanges(timergs, startDate, endDate)
            if selectedLists.get('recentUsers'):
                recentUsers = cros.get('recentUsers', [])
            else:
                recentUsers = []
            if selectedLists.get('deviceFiles'):
                device_files = cros.get('deviceFiles', [])
            else:
                device_files = []
            deviceFiles = _filterCreateReportTime(device_files, 'createTime',
                                                  startDate, endDate)
            if selectedLists.get('cpuStatusReports'):
                cpu_reports = cros.get('cpuStatusReports', [])
            else:
                cpu_reports = []
            cpuStatusReports = _filterCreateReportTime(cpu_reports,
                                                       'reportTime',
                                                       startDate, endDate)
            if selectedLists.get('diskVolumeReports'):
                diskVolumeReports = cros.get('diskVolumeReports', [])
            else:
                diskVolumeReports = []
            if selectedLists.get('systemRamFreeReports'):
                ram_reports = cros.get('systemRamFreeReports', [])
            else:
                ram_reports = []
            systemRamFreeReports = _filterCreateReportTime(ram_reports,
                                                           'reportTime',
                                                           startDate,
                                                           endDate)
            if noLists or (not activeTimeRanges and \
                           not recentUsers and \
                           not deviceFiles and \
                           not cpuStatusReports and \
                           not diskVolumeReports and \
                           not systemRamFreeReports):
                display.add_row_titles_to_csv_file(row, csvRows, titles)
                continue
            lenATR = len(activeTimeRanges)
            lenRU = len(recentUsers)
            lenDF = len(deviceFiles)
            lenCSR = len(cpuStatusReports)
            lenDVR = len(diskVolumeReports)
            lenSRFR = len(systemRamFreeReports)
            max_len = max(lenATR, lenRU, lenDF, lenCSR, lenDVR, lenSRFR)
            for i in range(min(max_len, listLimit or max_len)):
                nrow = row.copy()
                if i < lenATR:
                    nrow['activeTimeRanges.date'] = \
                        activeTimeRanges[i]['date']
                    nrow['activeTimeRanges.activeTime'] = \
                        str(activeTimeRanges[i]['activeTime'])
                    active_time = activeTimeRanges[i]['activeTime']
                    nrow['activeTimeRanges.duration'] = \
                        utils.formatMilliSeconds(active_time)
                    nrow['activeTimeRanges.minutes'] = active_time // 60000
                if i < lenRU:
                    nrow['recentUsers.type'] = recentUsers[i]['type']
                    nrow['recentUsers.email'] = recentUsers[i].get('email')
                    if not nrow['recentUsers.email']:
                        if nrow['recentUsers.type'] == 'USER_TYPE_UNMANAGED':
                            nrow['recentUsers.email'] = 'UnmanagedUser'
                        else:
                            nrow['recentUsers.email'] = 'Unknown'
                if i < lenDF:
                    nrow['deviceFiles.type'] = deviceFiles[i]['type']
                    nrow['deviceFiles.createTime'] = \
                        deviceFiles[i]['createTime']
                if i < lenCSR:
                    nrow['cpuStatusReports.reportTime'] = \
                        cpuStatusReports[i]['reportTime']
                    tempInfos = cpuStatusReports[i].get('cpuTemperatureInfo',
                                                        [])
                    for tempInfo in tempInfos:
                        label = tempInfo["label"].strip()
                        base = 'cpuStatusReports.cpuTemperatureInfo.'
                        nrow[f'{base}{label}'] = tempInfo['temperature']
                    cpu_field = 'cpuUtilizationPercentageInfo'
                    cpu_reports = cpuStatusReports[i][cpu_field]
                    cpu_pcts = [str(x) for x in cpu_reports]
                    nrow[f'cpuStatusReports.{cpu_field}'] = ','.join(cpu_pcts)
                if i < lenDVR:
                    volumeInfo = diskVolumeReports[i]['volumeInfo']
                    j = 0
                    vfield = 'diskVolumeReports.volumeInfo.'
                    for volume in volumeInfo:
                        nrow[f'{vfield}{j}.volumeId'] = \
                            volume['volumeId']
                        nrow[f'{vfield}{j}.storageFree'] = \
                            volume['storageFree']
                        nrow[f'{vfield}{j}.storageTotal'] = \
                            volume['storageTotal']
                        j += 1
                if i < lenSRFR:
                    nrow['systemRamFreeReports.reportTime'] = \
                        systemRamFreeReports[i]['reportTime']
                    ram_reports = systemRamFreeReports[i]['systemRamFreeInfo']
                    ram_info = [str(x) for x in ram_reports]
                    nrow['systenRamFreeReports.systemRamFreeInfo'] = \
                        ','.join(ram_info)
                display.add_row_titles_to_csv_file(nrow, csvRows, titles)
    if sortHeaders:
        display.sort_csv_titles(['deviceId', ], titles)
    display.write_csv_file(csvRows, titles, 'CrOS', todrive)
Пример #27
0
def doPrintCrosActivity():
    cd = gapi.directory.buildGAPIObject()
    todrive = False
    titles = ['deviceId', 'annotatedAssetId',
              'annotatedLocation', 'serialNumber', 'orgUnitPath']
    csvRows = []
    fieldsList = ['deviceId', 'annotatedAssetId',
                  'annotatedLocation', 'serialNumber', 'orgUnitPath']
    startDate = endDate = None
    selectActiveTimeRanges = selectDeviceFiles = selectRecentUsers = False
    listLimit = 0
    delimiter = ','
    orgUnitPath = None
    queries = [None]
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg in ['query', 'queries']:
            queries = __main__.getQueries(myarg, sys.argv[i+1])
            i += 2
        elif myarg == 'limittoou':
            orgUnitPath = __main__.getOrgUnitItem(sys.argv[i+1])
            i += 2
        elif myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in CROS_ACTIVE_TIME_RANGES_ARGUMENTS:
            selectActiveTimeRanges = True
            i += 1
        elif myarg in CROS_DEVICE_FILES_ARGUMENTS:
            selectDeviceFiles = True
            i += 1
        elif myarg in CROS_RECENT_USERS_ARGUMENTS:
            selectRecentUsers = True
            i += 1
        elif myarg == 'both':
            selectActiveTimeRanges = selectRecentUsers = True
            i += 1
        elif myarg == 'all':
            selectActiveTimeRanges = selectDeviceFiles = True
            selectRecentUsers = True
            i += 1
        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 == 'listlimit':
            listLimit = __main__.getInteger(sys.argv[i+1], myarg, minVal=0)
            i += 2
        elif myarg == 'delimiter':
            delimiter = sys.argv[i+1]
            i += 2
        else:
            controlflow.invalid_argument_exit(
                sys.argv[i], "gam print crosactivity")
    if not selectActiveTimeRanges and \
       not selectDeviceFiles and \
       not selectRecentUsers:
        selectActiveTimeRanges = selectRecentUsers = True
    if selectRecentUsers:
        fieldsList.append('recentUsers')
        display.add_titles_to_csv_file(['recentUsers.email', ], titles)
    if selectActiveTimeRanges:
        fieldsList.append('activeTimeRanges')
        titles_to_add = ['activeTimeRanges.date',
                         'activeTimeRanges.duration',
                         'activeTimeRanges.minutes']
        display.add_titles_to_csv_file(titles_to_add, titles)
    if selectDeviceFiles:
        fieldsList.append('deviceFiles')
        titles_to_add = ['deviceFiles.type', 'deviceFiles.createTime']
        display.add_titles_to_csv_file(titles_to_add, titles)
    fields = f'nextPageToken,chromeosdevices({",".join(fieldsList)})'
    for query in queries:
        __main__.printGettingAllItems('CrOS Devices', query)
        page_message = gapi.got_total_items_msg('CrOS Devices', '...\n')
        all_cros = gapi.get_all_pages(cd.chromeosdevices(), 'list',
                                      'chromeosdevices',
                                      page_message=page_message,
                                      query=query,
                                      customerId=GC_Values[GC_CUSTOMER_ID],
                                      projection='FULL',
                                      fields=fields, orgUnitPath=orgUnitPath)
        for cros in all_cros:
            row = {}
            skip_attribs = ['recentUsers', 'activeTimeRanges', 'deviceFiles']
            for attrib in cros:
                if attrib not in skip_attribs:
                    row[attrib] = cros[attrib]
            if selectActiveTimeRanges:
                activeTimeRanges = _filterTimeRanges(
                    cros.get('activeTimeRanges', []), startDate, endDate)
                lenATR = len(activeTimeRanges)
                num_ranges = min(lenATR, listLimit or lenATR)
                for activeTimeRange in activeTimeRanges[:num_ranges]:
                    newrow = row.copy()
                    newrow['activeTimeRanges.date'] = activeTimeRange['date']
                    active_time = activeTimeRange['activeTime']
                    newrow['activeTimeRanges.duration'] = \
                        utils.formatMilliSeconds(active_time)
                    newrow['activeTimeRanges.minutes'] = \
                        activeTimeRange['activeTime']//60000
                    csvRows.append(newrow)
            if selectRecentUsers:
                recentUsers = cros.get('recentUsers', [])
                lenRU = len(recentUsers)
                num_ranges = min(lenRU, listLimit or lenRU)
                recent_users = []
                for recentUser in recentUsers[:num_ranges]:
                    useremail = recentUser.get("email")
                    if not useremail:
                        if recentUser["type"] == "USER_TYPE_UNMANAGED":
                            useremail = 'UnmanagedUser'
                        else:
                            useremail = 'Unknown'
                    recent_users.append(useremail)
                row['recentUsers.email'] = delimiter.join(recent_users)
                csvRows.append(row)
            if selectDeviceFiles:
                deviceFiles = _filterCreateReportTime(
                    cros.get('deviceFiles', []),
                    'createTime', startDate, endDate)
                lenDF = len(deviceFiles)
                num_ranges = min(lenDF, listLimit or lenDF)
                for deviceFile in deviceFiles[:num_ranges]:
                    newrow = row.copy()
                    newrow['deviceFiles.type'] = deviceFile['type']
                    create_time = deviceFile['createTime']
                    newrow['deviceFiles.createTime'] = create_time
                    csvRows.append(newrow)
    display.write_csv_file(csvRows, titles, 'CrOS Activity', todrive)
Пример #28
0
def doUpdateCros():
    cd = gapi.directory.buildGAPIObject()
    i, devices = getCrOSDeviceEntity(3, cd)
    update_body = {}
    action_body = {}
    orgUnitPath = None
    ack_wipe = False
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'user':
            update_body['annotatedUser'] = sys.argv[i+1]
            i += 2
        elif myarg == 'location':
            update_body['annotatedLocation'] = sys.argv[i+1]
            i += 2
        elif myarg == 'notes':
            update_body['notes'] = sys.argv[i+1].replace('\\n', '\n')
            i += 2
        elif myarg in ['tag', 'asset', 'assetid']:
            update_body['annotatedAssetId'] = sys.argv[i+1]
            i += 2
        elif myarg in ['ou', 'org']:
            orgUnitPath = __main__.getOrgUnitItem(sys.argv[i+1])
            i += 2
        elif myarg == 'action':
            action = sys.argv[i+1].lower().replace('_', '').replace('-', '')
            deprovisionReason = None
            if action in ['deprovisionsamemodelreplace',
                          'deprovisionsamemodelreplacement']:
                action = 'deprovision'
                deprovisionReason = 'same_model_replacement'
            elif action in ['deprovisiondifferentmodelreplace',
                            'deprovisiondifferentmodelreplacement']:
                action = 'deprovision'
                deprovisionReason = 'different_model_replacement'
            elif action in ['deprovisionretiringdevice']:
                action = 'deprovision'
                deprovisionReason = 'retiring_device'
            elif action not in ['disable', 'reenable']:
                controlflow.system_error_exit(2, f'expected action of ' \
                    f'deprovision_same_model_replace, ' \
                    f'deprovision_different_model_replace, ' \
                    f'deprovision_retiring_device, disable or reenable,'
                    f' got {action}')
            action_body = {'action': action}
            if deprovisionReason:
                action_body['deprovisionReason'] = deprovisionReason
            i += 2
        elif myarg == 'acknowledgedevicetouchrequirement':
            ack_wipe = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i], "gam update cros")
    i = 0
    count = len(devices)
    if action_body:
        if action_body['action'] == 'deprovision' and not ack_wipe:
            print(f'WARNING: Refusing to deprovision {count} devices because '
                  'acknowledge_device_touch_requirement not specified. ' \
                  'Deprovisioning a device means the device will have to ' \
                  'be physically wiped and re-enrolled to be managed by ' \
                  'your domain again. This requires physical access to ' \
                  'the device and is very time consuming to perform for ' \
                  'each device. Please add ' \
                  '"acknowledge_device_touch_requirement" to the GAM ' \
                  'command if you understand this and wish to proceed ' \
                  'with the deprovision. Please also be aware that ' \
                  'deprovisioning can have an effect on your device ' \
                  'license count. See ' \
                  'https://support.google.com/chrome/a/answer/3523633 '\
                  'for full details.')
            sys.exit(3)
        for deviceId in devices:
            i += 1
            cur_count = __main__.currentCount(i, count)
            print(f' performing action {action} for {deviceId}{cur_count}')
            gapi.call(cd.chromeosdevices(), function='action',
                      customerId=GC_Values[GC_CUSTOMER_ID],
                      resourceId=deviceId, body=action_body)
    else:
        if update_body:
            for deviceId in devices:
                i += 1
                current_count = __main__.currentCount(i, count)
                print(f' updating {deviceId}{current_count}')
                gapi.call(cd.chromeosdevices(), 'update',
                          customerId=GC_Values[GC_CUSTOMER_ID],
                          deviceId=deviceId, body=update_body)
        if orgUnitPath:
            # split moves into max 50 devices per batch
            for l in range(0, len(devices), 50):
                move_body = {'deviceIds': devices[l:l+50]}
                print(f' moving {len(move_body["deviceIds"])} devices to ' \
                      f'{orgUnitPath}')
                gapi.call(cd.chromeosdevices(), 'moveDevicesToOu',
                          customerId=GC_Values[GC_CUSTOMER_ID],
                          orgUnitPath=orgUnitPath, body=move_body)
Пример #29
0
def showReport():
    rep = buildGAPIObject()
    throw_reasons = [gapi.errors.ErrorReason.INVALID]
    report = sys.argv[2].lower()
    report = REPORT_CHOICE_MAP.get(report.replace('_', ''), report)
    valid_apps = gapi.get_enum_values_minus_unspecified(
        rep._rootDesc['resources']['activities']['methods']['list']
        ['parameters']['applicationName']['enum']) + ['customer', 'user']
    if report not in valid_apps:
        controlflow.expected_argument_exit("report",
                                           ", ".join(sorted(valid_apps)),
                                           report)
    customerId = GC_Values[GC_CUSTOMER_ID]
    if customerId == MY_CUSTOMER:
        customerId = None
    filters = parameters = actorIpAddress = startTime = endTime = eventName = orgUnitId = None
    tryDate = datetime.date.today().strftime(YYYYMMDD_FORMAT)
    to_drive = False
    userKey = 'all'
    fullDataRequired = None
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'date':
            tryDate = utils.get_yyyymmdd(sys.argv[i + 1])
            i += 2
        elif myarg in ['orgunit', 'org', 'ou']:
            _, orgUnitId = __main__.getOrgUnitId(sys.argv[i + 1])
            i += 2
        elif myarg == 'fulldatarequired':
            fullDataRequired = []
            fdr = sys.argv[i + 1].lower()
            if fdr and fdr != 'all':
                fullDataRequired = fdr.replace(',', ' ').split()
            i += 2
        elif myarg == 'start':
            startTime = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'end':
            endTime = utils.get_time_or_delta_from_now(sys.argv[i + 1])
            i += 2
        elif myarg == 'event':
            eventName = sys.argv[i + 1]
            i += 2
        elif myarg == 'user':
            userKey = __main__.normalizeEmailAddressOrUID(sys.argv[i + 1])
            i += 2
        elif myarg in ['filter', 'filters']:
            filters = sys.argv[i + 1]
            i += 2
        elif myarg in ['fields', 'parameters']:
            parameters = sys.argv[i + 1]
            i += 2
        elif myarg == 'ip':
            actorIpAddress = sys.argv[i + 1]
            i += 2
        elif myarg == 'todrive':
            to_drive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i], "gam report")
    if report == 'user':
        while True:
            try:
                if fullDataRequired is not None:
                    warnings = gapi.get_items(rep.userUsageReport(),
                                              'get',
                                              'warnings',
                                              throw_reasons=throw_reasons,
                                              date=tryDate,
                                              userKey=userKey,
                                              customerId=customerId,
                                              orgUnitID=orgUnitId,
                                              fields='warnings')
                    fullData, tryDate = _check_full_data_available(
                        warnings, tryDate, fullDataRequired)
                    if fullData < 0:
                        print('No user report available.')
                        sys.exit(1)
                    if fullData == 0:
                        continue
                page_message = gapi.got_total_items_msg('Users', '...\n')
                usage = gapi.get_all_pages(rep.userUsageReport(),
                                           'get',
                                           'usageReports',
                                           page_message=page_message,
                                           throw_reasons=throw_reasons,
                                           date=tryDate,
                                           userKey=userKey,
                                           customerId=customerId,
                                           orgUnitID=orgUnitId,
                                           filters=filters,
                                           parameters=parameters)
                break
            except gapi.errors.GapiInvalidError as e:
                tryDate = _adjust_date(str(e))
        if not usage:
            print('No user report available.')
            sys.exit(1)
        titles = ['email', 'date']
        csvRows = []
        ptypes = ['intValue', 'boolValue', 'datetimeValue', 'stringValue']
        for user_report in usage:
            if 'entity' not in user_report:
                continue
            row = {
                'email': user_report['entity']['userEmail'],
                'date': tryDate
            }
            for item in user_report.get('parameters', []):
                if 'name' not in item:
                    continue
                name = item['name']
                if not name in titles:
                    titles.append(name)
                for ptype in ptypes:
                    if ptype in item:
                        row[name] = item[ptype]
                        break
                else:
                    row[name] = ''
            csvRows.append(row)
        display.write_csv_file(csvRows, titles, f'User Reports - {tryDate}',
                               to_drive)
    elif report == 'customer':
        while True:
            try:
                if fullDataRequired is not None:
                    warnings = gapi.get_items(rep.customerUsageReports(),
                                              'get',
                                              'warnings',
                                              throw_reasons=throw_reasons,
                                              customerId=customerId,
                                              date=tryDate,
                                              fields='warnings')
                    fullData, tryDate = _check_full_data_available(
                        warnings, tryDate, fullDataRequired)
                    if fullData < 0:
                        print('No customer report available.')
                        sys.exit(1)
                    if fullData == 0:
                        continue
                usage = gapi.get_all_pages(rep.customerUsageReports(),
                                           'get',
                                           'usageReports',
                                           throw_reasons=throw_reasons,
                                           customerId=customerId,
                                           date=tryDate,
                                           parameters=parameters)
                break
            except gapi.errors.GapiInvalidError as e:
                tryDate = _adjust_date(str(e))
        if not usage:
            print('No customer report available.')
            sys.exit(1)
        titles = ['name', 'value', 'client_id']
        csvRows = []
        auth_apps = list()
        for item in usage[0]['parameters']:
            if 'name' not in item:
                continue
            name = item['name']
            if 'intValue' in item:
                value = item['intValue']
            elif 'msgValue' in item:
                if name == 'accounts:authorized_apps':
                    for subitem in item['msgValue']:
                        app = {}
                        for an_item in subitem:
                            if an_item == 'client_name':
                                app['name'] = 'App: ' + \
                                    subitem[an_item].replace('\n', '\\n')
                            elif an_item == 'num_users':
                                app['value'] = f'{subitem[an_item]} users'
                            elif an_item == 'client_id':
                                app['client_id'] = subitem[an_item]
                        auth_apps.append(app)
                    continue
                values = []
                for subitem in item['msgValue']:
                    if 'count' in subitem:
                        mycount = myvalue = None
                        for key, value in list(subitem.items()):
                            if key == 'count':
                                mycount = value
                            else:
                                myvalue = value
                            if mycount and myvalue:
                                values.append(f'{myvalue}:{mycount}')
                        value = ' '.join(values)
                    elif 'version_number' in subitem \
                         and 'num_devices' in subitem:
                        values.append(f'{subitem["version_number"]}:'
                                      f'{subitem["num_devices"]}')
                    else:
                        continue
                    value = ' '.join(sorted(values, reverse=True))
            csvRows.append({'name': name, 'value': value})
        for app in auth_apps:  # put apps at bottom
            csvRows.append(app)
        display.write_csv_file(csvRows,
                               titles,
                               f'Customer Report - {tryDate}',
                               todrive=to_drive)
    else:
        page_message = gapi.got_total_items_msg('Activities', '...\n')
        activities = gapi.get_all_pages(rep.activities(),
                                        'list',
                                        'items',
                                        page_message=page_message,
                                        applicationName=report,
                                        userKey=userKey,
                                        customerId=customerId,
                                        actorIpAddress=actorIpAddress,
                                        startTime=startTime,
                                        endTime=endTime,
                                        eventName=eventName,
                                        filters=filters,
                                        orgUnitID=orgUnitId)
        if activities:
            titles = ['name']
            csvRows = []
            for activity in activities:
                events = activity['events']
                del activity['events']
                activity_row = utils.flatten_json(activity)
                purge_parameters = True
                for event in events:
                    for item in event.get('parameters', []):
                        if set(item) == set(['value', 'name']):
                            event[item['name']] = item['value']
                        elif set(item) == set(['intValue', 'name']):
                            if item['name'] in ['start_time', 'end_time']:
                                val = item.get('intValue')
                                if val is not None:
                                    val = int(val)
                                    if val >= 62135683200:
                                        event[item['name']] = \
                                            datetime.datetime.fromtimestamp(
                                                val-62135683200).isoformat()
                            else:
                                event[item['name']] = item['intValue']
                        elif set(item) == set(['boolValue', 'name']):
                            event[item['name']] = item['boolValue']
                        elif set(item) == set(['multiValue', 'name']):
                            event[item['name']] = ' '.join(item['multiValue'])
                        elif item['name'] == 'scope_data':
                            parts = {}
                            for message in item['multiMessageValue']:
                                for mess in message['parameter']:
                                    value = mess.get(
                                        'value',
                                        ' '.join(mess.get('multiValue', [])))
                                    parts[mess['name']] = parts.get(
                                        mess['name'], []) + [value]
                            for part, v in parts.items():
                                if part == 'scope_name':
                                    part = 'scope'
                                event[part] = ' '.join(v)
                        else:
                            purge_parameters = False
                    if purge_parameters:
                        event.pop('parameters', None)
                    row = utils.flatten_json(event)
                    row.update(activity_row)
                    for item in row:
                        if item not in titles:
                            titles.append(item)
                    csvRows.append(row)
            display.sort_csv_titles([
                'name',
            ], titles)
            display.write_csv_file(csvRows, titles,
                                   f'{report.capitalize()} Activity Report',
                                   to_drive)
Пример #30
0
def doGetCrosInfo():
    cd = gapi.directory.buildGAPIObject()
    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 = __main__.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}')
                    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}')