Skip to content

Commit

Permalink
Improve Chrome Policy error handling/output
Browse files Browse the repository at this point in the history
  • Loading branch information
taers232c committed Mar 23, 2021
1 parent 39b9994 commit 8e59daa
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 39 deletions.
8 changes: 7 additions & 1 deletion src/GamUpdate.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
6.00.01

Improve error handling in `gam delete|update chromepolicy` and `gam show chromepolicies`.

When showing Chrome Policies, display OU and optional printerid/appid at top of output.

6.00.00

Following Jay's lead, added the capability to manage three new areas.
Expand All @@ -13,7 +19,7 @@ As with any initial release, proceed with care and report any problems.
Updated `gam report customer|user` to continue processing subsequent dates when Google indicates that no data is available
for a particular date.

Improved `Got` messages so it is easier to monitor progress.
Improved `gam report` `Got` messages so it is easier to monitor progress.

Removed extraneous `email` header in `gam report user ... aggregatebydate`.

Expand Down
90 changes: 52 additions & 38 deletions src/gam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"""

__author__ = 'Ross Scroggs <[email protected]>'
__version__ = '6.00.00'
__version__ = '6.00.01'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'

import base64
Expand Down Expand Up @@ -1341,24 +1341,23 @@ def getOrgUnitId(cd=None, orgUnit=None):
cd = buildGAPIObject(API.DIRECTORY)
if orgUnit is None:
orgUnit = getOrgUnitItem()
if orgUnit[:3] == 'id:':
return (orgUnit, orgUnit)
try:
if orgUnit == '/':
result = callGAPI(cd.orgunits(), 'list',
throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath='/', type='children',
fields='organizationUnits(parentOrgUnitId)')
fields='organizationUnits(parentOrgUnitId,parentOrgUnitPath)')
if result.get('organizationUnits', []):
return (orgUnit, result['organizationUnits'][0]['parentOrgUnitId'])
return (result['organizationUnits'][0]['parentOrgUnitPath'], result['organizationUnits'][0]['parentOrgUnitId'])
topLevelOrgId = getTopLevelOrgId(cd, '/')
if topLevelOrgId:
return (orgUnit, topLevelOrgId)
return (orgUnit, '/') #Bogus but should never happen
result = callGAPI(cd.orgunits(), 'get',
throwReasons=GAPI.ORGUNIT_GET_THROW_REASONS,
customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath=encodeOrgUnitPath(makeOrgUnitPathRelative(orgUnit)), fields='orgUnitId')
return (orgUnit, result['orgUnitId'])
customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath=encodeOrgUnitPath(makeOrgUnitPathRelative(orgUnit)),
fields='orgUnitId,orgUnitPath')
return (result['orgUnitPath'], result['orgUnitId'])
except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError):
entityDoesNotExistExit(Ent.ORGANIZATIONAL_UNIT, orgUnit)
except (GAPI.badRequest, GAPI.invalidCustomerId, GAPI.loginRequired):
Expand Down Expand Up @@ -4663,7 +4662,9 @@ def splitEmailAddressOrUID(emailAddressOrUID):
return (normalizedEmailAddressOrUID, normalizedEmailAddressOrUID, GC.Values[GC.DOMAIN])

# Convert Org Unit Id to Org Unit Path
def convertOrgUnitIDtoPath(orgUnitId, cd):
def convertOrgUnitIDtoPath(cd, orgUnitId):
if orgUnitId.startswith('orgunits/'):
orgUnitId = f'id:{orgUnitId[9:]}'
orgUnitPath = GM.Globals[GM.MAP_ORGUNIT_ID_TO_NAME].get(orgUnitId)
if not orgUnitPath:
if cd is None:
Expand Down Expand Up @@ -12440,7 +12441,7 @@ def _setNamesFromIds(admin):
admin['assignedToUser'] = convertUserIDtoEmail(admin['assignedTo'], cd)
admin['role'] = role_from_roleid(admin['roleId'])
if 'orgUnitId' in admin:
admin['orgUnit'] = convertOrgUnitIDtoPath(f'id:{admin["orgUnitId"]}', cd)
admin['orgUnit'] = convertOrgUnitIDtoPath(cd, f'id:{admin["orgUnitId"]}')

cd = buildGAPIObject(API.DIRECTORY)
roleId = None
Expand Down Expand Up @@ -18157,11 +18158,11 @@ def _printBrowserToken(browser):
csvPF.SetSortTitles(['token'])
csvPF.writeCSVfile('Chrome Browser Enrollment Tokens')

def _getOrgunitsOrgUnitId(orgunit):
if orgunit.startswith('orgunits/'):
return orgunit
_, orgunitid = getOrgUnitId(None, orgunit)
return f'orgunits/{orgunitid[3:]}'
def _getOrgunitsOrgUnitIdPath(orgUnit):
if orgUnit.startswith('orgunits/'):
orgUnit = f'id:{orgUnit[9:]}'
orgUnitPath, orgUnitId = getOrgUnitId(None, orgUnit)
return (orgUnitPath, f'orgunits/{orgUnitId[3:]}')

def commonprefix(m):
'''Given a list of strings m, return string which is prefix common to all'''
Expand Down Expand Up @@ -18228,11 +18229,9 @@ def buildChromeSchemas(cp=None, sfilter=None):
schema_objects[schema_name.lower()] = schema_dict
return schema_objects

def updatePolicyRequests(body, orgunit, printer_id, app_id):
if not orgunit:
orgunit = _getOrgunitsOrgUnitId('/')
def updatePolicyRequests(body, orgUnit, printer_id, app_id):
for request in body['requests']:
request['policyTargetKey'] = {'targetResource': orgunit}
request['policyTargetKey'] = {'targetResource': orgUnit}
if printer_id:
request['policyTargetKey']['additionalTargetKeys'] = {'printer_id': printer_id}
elif app_id:
Expand All @@ -18244,12 +18243,12 @@ def doDeleteChromePolicy():
cp = buildGAPIObject(API.CHROMEPOLICY)
customer = _getCustomersCustomerIdWithC()
schemas = buildChromeSchemas(cp)
app_id = orgunit = printer_id = None
app_id = orgUnit = printer_id = None
body = {'requests': []}
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg in {'ou', 'org', 'orgunit'}:
orgunit = _getOrgunitsOrgUnitId(getString(Cmd.OB_ORGUNIT_PATH))
orgUnitPath, orgUnit = _getOrgunitsOrgUnitIdPath(getString(Cmd.OB_ORGUNIT_PATH))
elif myarg == 'printerid':
printer_id = getString(Cmd.OB_PRINTER_ID)
elif myarg == 'appid':
Expand All @@ -18258,18 +18257,20 @@ def doDeleteChromePolicy():
body['requests'].append({'policySchema': schemas[myarg]['name']})
else:
unknownArgumentExit()
if not orgunit:
if not orgUnit:
missingArgumentExit('orgunit')
count = len(body['requests'])
performActionNumItems(count, Ent.CHROME_POLICY)
if count == 0:
return
updatePolicyRequests(body, orgunit, printer_id, app_id)
updatePolicyRequests(body, orgUnit, printer_id, app_id)
try:
callGAPI(cp.customers().policies().orgunits(), 'batchInherit',
throwReasons=[GAPI.INVALID_ARGUMENT],
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.NOT_FOUND],
customer=customer, body=body)
actionPerformedNumItems(count, Ent.CHROME_POLICY)
except GAPI.notFound as e:
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], str(e))
except GAPI.invalidArgument as e:
actionFailedNumItems(count, Ent.CHROME_POLICY, str(e))

Expand All @@ -18279,12 +18280,12 @@ def doUpdateChromePolicy():
cp = buildGAPIObject(API.CHROMEPOLICY)
customer = _getCustomersCustomerIdWithC()
schemas = buildChromeSchemas(cp)
app_id = orgunit = printer_id = None
app_id = orgUnit = printer_id = None
body = {'requests': []}
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg in {'ou', 'org', 'orgunit'}:
orgunit = _getOrgunitsOrgUnitId(getString(Cmd.OB_ORGUNIT_PATH))
orgUnitPath, orgUnit = _getOrgunitsOrgUnitIdPath(getString(Cmd.OB_ORGUNIT_PATH))
elif myarg == 'printerid':
printer_id = getString(Cmd.OB_PRINTER_ID)
elif myarg == 'appid':
Expand All @@ -18299,6 +18300,7 @@ def doUpdateChromePolicy():
Cmd.Backup()
break # field is actually a new policy name or orgunit
if field not in schemas[myarg]['settings']:
Cmd.Backup()
missingChoiceExit(schemas[myarg]['settings'])
casedField = schemas[myarg]['settings'][field]['name']
value = getString(Cmd.OB_STRING)
Expand All @@ -18308,6 +18310,7 @@ def doUpdateChromePolicy():
invalidArgumentExit(integerLimits(None, None))
value = int(value)
elif vtype in ['TYPE_BOOL']:
value = value.lower()
if value in TRUE_VALUES:
value = True
elif value in FALSE_VALUES:
Expand All @@ -18327,18 +18330,20 @@ def doUpdateChromePolicy():
body['requests'][-1]['updateMask'] += f'{casedField},'
else:
unknownArgumentExit()
if not orgunit:
if not orgUnit:
missingArgumentExit('orgunit')
count = len(body['requests'])
performActionNumItems(count, Ent.CHROME_POLICY)
if count == 0:
return
updatePolicyRequests(body, orgunit, printer_id, app_id)
updatePolicyRequests(body, orgUnit, printer_id, app_id)
try:
callGAPI(cp.customers().policies().orgunits(), 'batchModify',
throwReasons=[GAPI.INVALID_ARGUMENT],
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.NOT_FOUND],
customer=customer, body=body)
actionPerformedNumItems(count, Ent.CHROME_POLICY)
except GAPI.notFound as e:
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], str(e))
except GAPI.invalidArgument as e:
actionFailedNumItems(count, Ent.CHROME_POLICY, str(e))

Expand All @@ -18347,20 +18352,20 @@ def doUpdateChromePolicy():
def doPrintShowChromePolicies():
cp = buildGAPIObject(API.CHROMEPOLICY)
customer = _getCustomersCustomerIdWithC()
app_id = orgunit = printer_id = None
app_id = orgUnit = printer_id = None
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg in {'ou', 'org', 'orgunit'}:
orgunit = _getOrgunitsOrgUnitId(getString(Cmd.OB_ORGUNIT_PATH))
orgUnitPath, orgUnit = _getOrgunitsOrgUnitIdPath(getString(Cmd.OB_ORGUNIT_PATH))
elif myarg == 'printerid':
printer_id = getString(Cmd.OB_PRINTER_ID)
elif myarg == 'appid':
app_id = getString(Cmd.OB_APP_ID)
else:
unknownArgumentExit()
if not orgunit:
if not orgUnit:
missingArgumentExit('orgunit')
body = {'policyTargetKey': {'targetResource': orgunit}}
body = {'policyTargetKey': {'targetResource': orgUnit}}
if printer_id:
body['policyTargetKey']['additionalTargetKeys'] = {'printer_id': printer_id}
namespaces = ['chrome.printers']
Expand All @@ -18381,14 +18386,24 @@ def doPrintShowChromePolicies():
body['policySchemaFilter'] = f'{namespace}.*'
try:
policies = callGAPIpages(cp.customers().policies(), 'resolve','resolvedPolicies',
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.SERVICE_NOT_AVAILABLE],
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.NOT_FOUND, GAPI.SERVICE_NOT_AVAILABLE],
customer=customer,
body=body)
except GAPI.notFound as e:
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], str(e))
continue
except (GAPI.invalidArgument, GAPI.serviceNotAvailable) as e:
entityActionFailedWarning([Ent.CHROME_POLICY, body['policySchemaFilter']], str(e))
continue
kvList = []
if printer_id:
kvList.extend(['printerid', printer_id])
elif app_id:
kvList.extend(['appid', app_id])
printEntityKVList([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], kvList)
for policy in sorted(policies, key=lambda k: k.get('value', {}).get('policySchema', '')):
name = policy.get('value', {}).get('policySchema', '')
printBlankLine()
printKeyValueList([name])
Ind.Increment()
values = policy.get('value', {}).get('value', {})
Expand All @@ -18397,7 +18412,6 @@ def doPrintShowChromePolicies():
value = value.split('_ENUM_')[-1]
printKeyValueList([f'{setting}', f'{value}'])
Ind.Decrement()
printBlankLine()

def _getChromePolicySchemaName():
name = getString(Cmd.OB_SCHEMA_NAME)
Expand Down Expand Up @@ -19366,12 +19380,12 @@ def _checkPrinterInheritance(cd, printer, orgUnitId, showInherited):
elif orgUnitId is not None and printer['orgUnitId'] != orgUnitId:
printer['inherited'] = True
printer['parentOrgUnitId'] = printer['orgUnitId']
printer['parentOrgUnitPath'] = convertOrgUnitIDtoPath(f'id:{printer["parentOrgUnitId"]}', cd)
printer['parentOrgUnitPath'] = convertOrgUnitIDtoPath(cd, f'id:{printer["parentOrgUnitId"]}')
printer['orgUnitId'] = orgUnitId
else:
printer['inherited'] = False
printer['parentOrgUnitId'] = printer['parentOrgUnitPath'] = ''
printer['orgUnitPath'] = convertOrgUnitIDtoPath(f'id:{printer["orgUnitId"]}', cd)
printer['orgUnitPath'] = convertOrgUnitIDtoPath(cd, f'id:{printer["orgUnitId"]}')
return True

def _showPrinter(cd, printer, FJQC, orgUnitId=None, showInherited=False, i=0, count=0):
Expand Down Expand Up @@ -27393,7 +27407,7 @@ def _getExportOrgUnitName(export, cd):
query = export.get('query')
if query:
if 'orgUnitInfo' in query:
query['orgUnitInfo']['orgUnitPath'] = convertOrgUnitIDtoPath(query['orgUnitInfo']['orgUnitId'], cd)
query['orgUnitInfo']['orgUnitPath'] = convertOrgUnitIDtoPath(cd, query['orgUnitInfo']['orgUnitId'])

VAULT_EXPORT_TIME_OBJECTS = {'versionDate', 'createTime', 'startTime', 'endTime'}

Expand Down Expand Up @@ -27950,7 +27964,7 @@ def _getHoldEmailAddressesOrgUnitName(hold, cd):
for i in range(0, len(hold['accounts'])):
hold['accounts'][i]['email'] = convertUIDtoEmailAddress(f'uid:{hold["accounts"][i]["accountId"]}', cd, accountType)
if 'orgUnit' in hold:
hold['orgUnit']['orgUnitPath'] = convertOrgUnitIDtoPath(hold['orgUnit']['orgUnitId'], cd)
hold['orgUnit']['orgUnitPath'] = convertOrgUnitIDtoPath(cd, hold['orgUnit']['orgUnitId'])

VAULT_HOLD_TIME_OBJECTS = {'holdTime', 'updateTime', 'startTime', 'endTime'}

Expand Down

0 comments on commit 8e59daa

Please sign in to comment.