OrgUnit Support for Shared Drives

This commit is contained in:
Jay Lee
2022-04-07 19:48:23 +00:00
parent c97495ab05
commit bac3451c21
4 changed files with 118 additions and 67 deletions

View File

@@ -659,6 +659,9 @@ jobs:
$gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition $gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition
$gam print caalevels $gam print caalevels
$gam delete caalevel "zzz_${newbase}" $gam delete caalevel "zzz_${newbase}"
$gam user $gamuser add shareddrive "${newbase}"
$gam user $gamuser update shareddrive "name:${newbase}" ou "/GitHub Actions Testing"
$gam user $gamuser show shareddrives asadmin
export CUSTOMER_ID="C01wfv983" export CUSTOMER_ID="C01wfv983"
export GA_DOMAIN="pdl.jaylee.us" export GA_DOMAIN="pdl.jaylee.us"
touch $gampath/enabledasa.txt touch $gampath/enabledasa.txt

View File

@@ -65,6 +65,7 @@ from gam.gapi import chromemanagement as gapi_chromemanagement
from gam.gapi import chromepolicy as gapi_chromepolicy from gam.gapi import chromepolicy as gapi_chromepolicy
from gam.gapi.cloudidentity import devices as gapi_cloudidentity_devices from gam.gapi.cloudidentity import devices as gapi_cloudidentity_devices
from gam.gapi.cloudidentity import groups as gapi_cloudidentity_groups from gam.gapi.cloudidentity import groups as gapi_cloudidentity_groups
from gam.gapi.cloudidentity import orgunits as gapi_cloudidentity_orgunits
from gam.gapi.cloudidentity import userinvitations as gapi_cloudidentity_userinvitations from gam.gapi.cloudidentity import userinvitations as gapi_cloudidentity_userinvitations
from gam.gapi import contactdelegation as gapi_contactdelegation from gam.gapi import contactdelegation as gapi_contactdelegation
from gam.gapi.directory import asps as gapi_directory_asps from gam.gapi.directory import asps as gapi_directory_asps
@@ -81,6 +82,7 @@ from gam.gapi.directory import resource as gapi_directory_resource
from gam.gapi.directory import roles as gapi_directory_roles from gam.gapi.directory import roles as gapi_directory_roles
from gam.gapi.directory import roleassignments as gapi_directory_roleassignments from gam.gapi.directory import roleassignments as gapi_directory_roleassignments
from gam.gapi.directory import users as gapi_directory_users from gam.gapi.directory import users as gapi_directory_users
from gam.gapi.drive import drives as gapi_drive_drives
from gam.gapi import licensing as gapi_licensing from gam.gapi import licensing as gapi_licensing
from gam.gapi import siteverification as gapi_siteverification from gam.gapi import siteverification as gapi_siteverification
from gam.gapi import errors as gapi_errors from gam.gapi import errors as gapi_errors
@@ -2733,7 +2735,7 @@ def printDriveSettings(users):
display.write_csv_file(csvRows, titles, 'User Drive Settings', todrive) display.write_csv_file(csvRows, titles, 'User Drive Settings', todrive)
def getTeamDriveThemes(users): def getSharedDriveThemes(users):
for user in users: for user in users:
user, drive = buildDrive3GAPIObject(user) user, drive = buildDrive3GAPIObject(user)
if not drive: if not drive:
@@ -8017,8 +8019,8 @@ def doPrintShowProjects(csvFormat):
display.write_csv_file(csvRows, titles, 'Projects', todrive) display.write_csv_file(csvRows, titles, 'Projects', todrive)
def doGetTeamDriveInfo(users): def doGetSharedDriveInfo(users):
teamDriveId = sys.argv[5] driveId = sys.argv[5]
useDomainAdminAccess = False useDomainAdminAccess = False
i = 6 i = 6
while i < len(sys.argv): while i < len(sys.argv):
@@ -8028,7 +8030,7 @@ def doGetTeamDriveInfo(users):
i += 1 i += 1
else: else:
controlflow.invalid_argument_exit(myarg, controlflow.invalid_argument_exit(myarg,
'gam <users> show teamdrive') 'gam <users> show shareddrive')
for user in users: for user in users:
drive = buildGAPIServiceObject('drive3', user) drive = buildGAPIServiceObject('drive3', user)
if not drive: if not drive:
@@ -8036,13 +8038,15 @@ def doGetTeamDriveInfo(users):
continue continue
result = gapi.call(drive.drives(), result = gapi.call(drive.drives(),
'get', 'get',
driveId=teamDriveId, driveId=driveId,
useDomainAdminAccess=useDomainAdminAccess, useDomainAdminAccess=useDomainAdminAccess,
fields='*') fields='*')
if useDomainAdminAccess and 'orgUnitId' in result:
result['orgUnit'] = gapi_directory_orgunits.orgunit_from_orgunitid(f'id:{result["orgUnitId"]}')
display.print_json(result) display.print_json(result)
def doCreateTeamDrive(users): def doCreateSharedDrive(users):
body = {'name': sys.argv[5]} body = {'name': sys.argv[5]}
i = 6 i = 6
while i < len(sys.argv): while i < len(sys.argv):
@@ -8052,7 +8056,7 @@ def doCreateTeamDrive(users):
i += 2 i += 2
else: else:
controlflow.invalid_argument_exit(sys.argv[i], controlflow.invalid_argument_exit(sys.argv[i],
'gam <users> create teamdrive') 'gam <users> create shareddrive')
for user in users: for user in users:
drive = buildGAPIServiceObject('drive3', user) drive = buildGAPIServiceObject('drive3', user)
if not drive: if not drive:
@@ -8064,7 +8068,7 @@ def doCreateTeamDrive(users):
requestId=requestId, requestId=requestId,
body=body, body=body,
fields='id') fields='id')
print(f'Created Team Drive {body["name"]} with id {result["id"]}') print(f'Created Shared Drive {body["name"]} with id {result["id"]}')
TEAMDRIVE_RESTRICTIONS_MAP = { TEAMDRIVE_RESTRICTIONS_MAP = {
@@ -8075,17 +8079,23 @@ TEAMDRIVE_RESTRICTIONS_MAP = {
} }
def doUpdateTeamDrive(users): def doUpdateSharedDrive(users):
teamDriveId = sys.argv[5] teamDriveId = sys.argv[5]
if teamDriveId.lower().startswith('name'):
teamDriveId = gapi_drive_drives.drive_name_to_id(sys.argv[6])
body = {} body = {}
useDomainAdminAccess = False useDomainAdminAccess = False
change_hide = None change_hide = None
orgUnit = None
i = 6 i = 6
while i < len(sys.argv): while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '') myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'name': if myarg == 'name':
body['name'] = sys.argv[i + 1] body['name'] = sys.argv[i + 1]
i += 2 i += 2
elif myarg in ['ou', 'orgunit']:
orgUnit = sys.argv[i+1]
i += 2
elif myarg == 'theme': elif myarg == 'theme':
body['themeId'] = sys.argv[i + 1] body['themeId'] = sys.argv[i + 1]
i += 2 i += 2
@@ -8120,8 +8130,8 @@ def doUpdateTeamDrive(users):
i += 2 i += 2
else: else:
controlflow.invalid_argument_exit(sys.argv[i], controlflow.invalid_argument_exit(sys.argv[i],
'gam <users> update teamdrive') 'gam <users> update shareddrive')
if not body and not change_hide: if not body and not change_hide and not orgUnit:
controlflow.system_error_exit( controlflow.system_error_exit(
4, 'nothing to update. Need at least a name argument.') 4, 'nothing to update. Need at least a name argument.')
for user in users: for user in users:
@@ -8144,12 +8154,16 @@ def doUpdateTeamDrive(users):
driveId=teamDriveId, driveId=teamDriveId,
fields='id', fields='id',
soft_errors=True) soft_errors=True)
print(f'Updated Team Drive {teamDriveId}') if orgUnit:
gapi_cloudidentity_orgunits.move_shared_drive(teamDriveId,
orgUnit)
print(f'Updated Shared Drive {teamDriveId}')
def printShowTeamDrives(users, csvFormat): def printShowSharedDrives(users, csvFormat):
todrive = False todrive = False
useDomainAdminAccess = False useDomainAdminAccess = False
q = None q = None
get_orgunits = True
i = 5 i = 5
while i < len(sys.argv): while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '') myarg = sys.argv[i].lower().replace('_', '')
@@ -8162,13 +8176,18 @@ def printShowTeamDrives(users, csvFormat):
elif myarg == 'query': elif myarg == 'query':
q = sys.argv[i + 1] q = sys.argv[i + 1]
i += 2 i += 2
elif myarg == 'noorgunits':
get_orgunits = False
i += 1
else: else:
controlflow.invalid_argument_exit( controlflow.invalid_argument_exit(
myarg, f"gam {['show', 'print'][csvFormat]} teamdrives") myarg, f"gam {['show', 'print'][csvFormat]} shareddrives")
tds = [] tds = []
titles = [] titles = []
if get_orgunits and useDomainAdminAccess:
ou_map = gapi_directory_orgunits.orgid_to_org_map()
for user in users: for user in users:
sys.stderr.write(f'Getting Team Drives for {user}\n') sys.stderr.write(f'Getting Shared Drives for {user}\n')
user, drive = buildDrive3GAPIObject(user) user, drive = buildDrive3GAPIObject(user)
if not drive: if not drive:
continue continue
@@ -8183,12 +8202,16 @@ def printShowTeamDrives(users, csvFormat):
continue continue
for td in results: for td in results:
td = utils.flatten_json(td) td = utils.flatten_json(td)
if get_orgunits and useDomainAdminAccess:
td_ouid = td.get('orgUnitId')
if td_ouid:
td['orgUnit'] = ou_map.get(f'id:{td_ouid}', 'Unknown')
for key in td: for key in td:
if key not in titles: if key not in titles:
titles.append(key) titles.append(key)
tds.append(td) tds.append(td)
if csvFormat: if csvFormat:
display.write_csv_file(tds, titles, 'Team Drives', todrive) display.write_csv_file(tds, titles, 'Shared Drives', todrive)
else: else:
for td in tds: for td in tds:
name = td.pop('name') name = td.pop('name')
@@ -8198,14 +8221,13 @@ def printShowTeamDrives(users, csvFormat):
print() print()
def doDeleteSharedDrive(users):
def doDeleteTeamDrive(users):
teamDriveId = sys.argv[5] teamDriveId = sys.argv[5]
for user in users: for user in users:
user, drive = buildDrive3GAPIObject(user) user, drive = buildDrive3GAPIObject(user)
if not drive: if not drive:
continue continue
print(f'Deleting Team Drive {teamDriveId}') print(f'Deleting Shared Drive {teamDriveId}')
gapi.call(drive.drives(), gapi.call(drive.drives(),
'delete', 'delete',
driveId=teamDriveId, driveId=teamDriveId,
@@ -10456,6 +10478,11 @@ OAUTH2_SCOPES = [
'subscopes': ['readonly'], 'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.groups' 'scopes': 'https://www.googleapis.com/auth/cloud-identity.groups'
}, },
{
'name': 'Cloud Identity - OrgUnits',
'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.orgunits',
},
{ {
'name': 'Cloud Identity - User Invitations', 'name': 'Cloud Identity - User Invitations',
'subscopes': ['readonly'], 'subscopes': ['readonly'],
@@ -11710,6 +11737,8 @@ def ProcessGAMCommand(args):
gapi_chat.print_members() gapi_chat.print_members()
elif argument in ['caalevels']: elif argument in ['caalevels']:
gapi_caa.print_access_levels() gapi_caa.print_access_levels()
elif argument in ['oushareddrives', 'orgunitshareddrives']:
gapi_cloudidentity_orgunits.print_orgunit_shared_drives()
else: else:
controlflow.invalid_argument_exit(argument, 'gam print') controlflow.invalid_argument_exit(argument, 'gam print')
sys.exit(0) sys.exit(0)
@@ -11898,8 +11927,8 @@ def ProcessGAMCommand(args):
gapi_calendar.showCalSettings(users) gapi_calendar.showCalSettings(users)
elif showWhat == 'drivesettings': elif showWhat == 'drivesettings':
printDriveSettings(users) printDriveSettings(users)
elif showWhat == 'teamdrivethemes': elif showWhat in ['teamdrivethemes', 'shareddrivethemes']:
getTeamDriveThemes(users) getSharedDriveThemes(users)
elif showWhat == 'drivefileacl': elif showWhat == 'drivefileacl':
showDriveFileACL(users) showDriveFileACL(users)
elif showWhat == 'filelist': elif showWhat == 'filelist':
@@ -11942,10 +11971,10 @@ def ProcessGAMCommand(args):
printShowFilters(users, False) printShowFilters(users, False)
elif showWhat in ['forwardingaddress', 'forwardingaddresses']: elif showWhat in ['forwardingaddress', 'forwardingaddresses']:
printShowForwardingAddresses(users, False) printShowForwardingAddresses(users, False)
elif showWhat in ['teamdrive', 'teamdrives']: elif showWhat in shared_drive_values:
printShowTeamDrives(users, False) printShowSharedDrives(users, False)
elif showWhat in ['teamdriveinfo']: elif showWhat in ['shareddriveinfo', 'teamdriveinfo']:
doGetTeamDriveInfo(users) doGetSharedDriveInfo(users)
elif showWhat in ['contactdelegate', 'contactdelegates']: elif showWhat in ['contactdelegate', 'contactdelegates']:
gapi_contactdelegation.print_(users, False) gapi_contactdelegation.print_(users, False)
elif showWhat in ['holds', 'vaultholds']: elif showWhat in ['holds', 'vaultholds']:
@@ -11976,8 +12005,8 @@ def ProcessGAMCommand(args):
printShowSmime(users, True) printShowSmime(users, True)
elif printWhat in ['token', 'tokens', 'oauth', '3lo']: elif printWhat in ['token', 'tokens', 'oauth', '3lo']:
printShowTokens(5, 'users', users, True) printShowTokens(5, 'users', users, True)
elif printWhat in ['teamdrive', 'teamdrives']: elif printWhat in shared_drive_values:
printShowTeamDrives(users, True) printShowSharedDrives(users, True)
elif printWhat in ['contactdelegate', 'contactdelegates']: elif printWhat in ['contactdelegate', 'contactdelegates']:
gapi_contactdelegation.print_(users, True) gapi_contactdelegation.print_(users, True)
elif printWhat in ['labels']: elif printWhat in ['labels']:
@@ -12060,8 +12089,8 @@ def ProcessGAMCommand(args):
deleteSendAs(users) deleteSendAs(users)
elif delWhat == 'smime': elif delWhat == 'smime':
deleteSmime(users) deleteSmime(users)
elif delWhat == 'teamdrive': elif delWhat in shared_drive_values:
doDeleteTeamDrive(users) doDeleteSharedDrive(users)
elif delWhat == 'contactdelegate': elif delWhat == 'contactdelegate':
gapi_contactdelegation.delete(users) gapi_contactdelegation.delete(users)
else: else:
@@ -12094,8 +12123,8 @@ def ProcessGAMCommand(args):
addUpdateSendAs(users, 5, True) addUpdateSendAs(users, 5, True)
elif addWhat == 'smime': elif addWhat == 'smime':
addSmime(users) addSmime(users)
elif addWhat == 'teamdrive': elif addWhat in shared_drive_values:
doCreateTeamDrive(users) doCreateSharedDrive(users)
elif addWhat == 'contactdelegate': elif addWhat == 'contactdelegate':
gapi_contactdelegation.create(users) gapi_contactdelegation.create(users)
else: else:
@@ -12136,8 +12165,8 @@ def ProcessGAMCommand(args):
addUpdateSendAs(users, 5, False) addUpdateSendAs(users, 5, False)
elif updateWhat == 'smime': elif updateWhat == 'smime':
updateSmime(users) updateSmime(users)
elif updateWhat == 'teamdrive': elif updateWhat in shared_drive_values:
doUpdateTeamDrive(users) doUpdateSharedDrive(users)
else: else:
controlflow.invalid_argument_exit(updateWhat, controlflow.invalid_argument_exit(updateWhat,
'gam <users> update') 'gam <users> update')

View File

@@ -160,42 +160,15 @@ def info(name=None, return_attrib=None):
print('') print('')
def print_(): def list_orgunits(listType='all', orgUnitPath=None, fields=None):
print_order = [
'orgUnitPath', 'orgUnitId', 'name', 'description', 'parentOrgUnitPath',
'parentOrgUnitId', 'blockInheritance'
]
cd = gapi_directory.build()
listType = 'all'
orgUnitPath = '/'
todrive = False
fields = ['orgUnitPath', 'name', 'orgUnitId', 'parentOrgUnitId']
titles = []
csvRows = []
parentOrgIds = []
retrievedOrgIds = [] retrievedOrgIds = []
i = 3 parentOrgIds = []
while i < len(sys.argv): cd = gapi_directory.build()
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'todrive':
todrive = True
i += 1
elif myarg == 'toplevelonly':
listType = 'children'
i += 1
elif myarg == 'fromparent':
orgUnitPath = getOrgUnitItem(sys.argv[i + 1])
i += 2
elif myarg == 'allfields':
fields = None
i += 1
elif myarg == 'fields':
fields += sys.argv[i + 1].split(',')
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i], 'gam print orgs')
gam.printGettingAllItems('Organizational Units', None)
if fields: if fields:
# Always get parentOrgUnitId so we can
# find missing parents
if 'parentOrgUnitId' not in fields:
fields.append('parentOrgUnitId')
get_fields = ','.join(fields) get_fields = ','.join(fields)
list_fields = f'organizationUnits({get_fields})' list_fields = f'organizationUnits({get_fields})'
else: else:
@@ -230,6 +203,44 @@ def print_():
orgunits.append(result) orgunits.append(result)
except: except:
pass pass
return orgunits
def print_():
print_order = [
'orgUnitPath', 'orgUnitId', 'name', 'description', 'parentOrgUnitPath',
'parentOrgUnitId', 'blockInheritance'
]
listType = 'all'
orgUnitPath = '/'
todrive = False
fields = ['orgUnitPath', 'name', 'orgUnitId', 'parentOrgUnitId']
titles = []
csvRows = []
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'todrive':
todrive = True
i += 1
elif myarg == 'toplevelonly':
listType = 'children'
i += 1
elif myarg == 'fromparent':
orgUnitPath = getOrgUnitItem(sys.argv[i + 1])
i += 2
elif myarg == 'allfields':
fields = None
i += 1
elif myarg == 'fields':
fields += sys.argv[i + 1].split(',')
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i], 'gam print orgs')
gam.printGettingAllItems('Organizational Units', None)
orgunits = list_orgunits(listType=listType,
orgUnitPath=orgUnitPath,
fields=fields)
for row in orgunits: for row in orgunits:
orgEntity = {} orgEntity = {}
for key, value in list(row.items()): for key, value in list(row.items()):
@@ -248,6 +259,11 @@ def print_():
display.write_csv_file(csvRows, titles, 'Orgs', todrive) display.write_csv_file(csvRows, titles, 'Orgs', todrive)
def orgid_to_org_map():
orgunits = list_orgunits(fields=['orgUnitPath', 'orgUnitId'])
result = {ou['orgUnitId']:ou['orgUnitPath'] for ou in orgunits}
return result
def update(): def update():
cd = gapi_directory.build() cd = gapi_directory.build()
orgUnitPath = getOrgUnitItem(sys.argv[3]) orgUnitPath = getOrgUnitItem(sys.argv[3])

View File

@@ -1525,6 +1525,9 @@ MESSAGE_UPDATE_GAM_TO_64BIT = 'You\'re running a 32-bit version of GAM on a' \
MESSAGE_YOUR_SYSTEM_TIME_DIFFERS_FROM_GOOGLE_BY = 'Your system time differs' \ MESSAGE_YOUR_SYSTEM_TIME_DIFFERS_FROM_GOOGLE_BY = 'Your system time differs' \
' from %s by %s' ' from %s by %s'
shared_drive_values = ['teamdrive', 'teamdrives',
'shareddrive', 'shareddrives']
USER_ADDRESS_TYPES = ['home', 'work', 'other'] USER_ADDRESS_TYPES = ['home', 'work', 'other']
USER_EMAIL_TYPES = ['home', 'work', 'other'] USER_EMAIL_TYPES = ['home', 'work', 'other']
USER_EXTERNALID_TYPES = [ USER_EXTERNALID_TYPES = [