gam info|print|show policies cleanup

This commit is contained in:
Ross Scroggs
2026-03-12 19:30:40 -07:00
parent 8412ba78b2
commit a2b226a124
3 changed files with 50 additions and 43 deletions

View File

@@ -4335,14 +4335,14 @@ gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
# Cloud Identity Policies # Cloud Identity Policies
gam info policies <CIPolicyNameEntity> gam info policies <CIPolicyNameEntity>
[nowarnings] [noappnames] [nowarnings] [noappnames] [noidmappimg]
[formatjson] [formatjson]
gam print policies [todrive <ToDriveAttribute>*] gam print policies [todrive <ToDriveAttribute>*]
[filter <String>] [nowarnings] [noappnames] [filter <String>] [nowarnings] [noappnames] [noidmappimg]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson [quotechar <Character>]] [formatjson [quotechar <Character>]]
gam show policies gam show policies
[filter <String>] [nowarnings] [noappnames] [filter <String>] [nowarnings] [noappnames] [noidmappimg]
[group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
[formatjson] [formatjson]

View File

@@ -1,3 +1,10 @@
7.36.01
Fixed bug in `gam info|print|show policies` where the `policyQuery/query` field was not displayed.
Added option `noidmapping` to `gam info|print|show policies` to suppress adding the `policyQuery/groupEmail` and
`policyQuery/orgUnitPath` name fields that are mapped from the `policyQuery/group` and `policyQuery/orgInit` id fields.
7.36.00 7.36.00
Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and Added options `filtermultiattrtype` and filtermultiattrcustom` to `gam info user` and

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
""" """
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>' __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.36.00' __version__ = '7.36.01'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position # pylint: disable=wrong-import-position
@@ -37743,9 +37743,7 @@ def _filterPolicies(ci, pageMessage, ifilter):
policies = callGAPIpages(ci.policies(), 'list', 'policies', policies = callGAPIpages(ci.policies(), 'list', 'policies',
pageMessage=pageMessage, pageMessage=pageMessage,
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
filter=ifilter, filter=ifilter, pageSize=100)
fields='nextPageToken,policies(name,policyQuery(group,orgUnit,sortOrder),type,setting)',
pageSize=100)
# Google returns unordered results, sort them by setting type # Google returns unordered results, sort them by setting type
return sorted(policies, key=lambda p: p.get('setting', {}).get('type', '')) return sorted(policies, key=lambda p: p.get('setting', {}).get('type', ''))
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e:
@@ -37777,7 +37775,7 @@ def _getPolicyAppNameFromId(httpObj, app):
if a: if a:
app['applicationName'] = a.group(1) app['applicationName'] = a.group(1)
def _cleanPolicy(policy, add_warnings, no_appnames, def _cleanPolicy(policy, add_warnings, no_appnames, no_idmapping,
groupEmailPattern, orgUnitPathPattern, groupEmailPattern, orgUnitPathPattern,
cd, groups_ci): cd, groups_ci):
# convert any wordlists into spaced strings to reduce output complexity # convert any wordlists into spaced strings to reduce output complexity
@@ -37792,19 +37790,19 @@ def _cleanPolicy(policy, add_warnings, no_appnames,
if add_warnings and policy['setting']['type'] in CIPOLICY_ADDITIONAL_WARNINGS: if add_warnings and policy['setting']['type'] in CIPOLICY_ADDITIONAL_WARNINGS:
policy['warning'] = CIPOLICY_ADDITIONAL_WARNINGS[policy['setting']['type']] policy['warning'] = CIPOLICY_ADDITIONAL_WARNINGS[policy['setting']['type']]
if groupId := policy['policyQuery'].get('group'): if groupId := policy['policyQuery'].get('group'):
_, _, policy['policyQuery']['groupEmail'] = convertGroupCloudIDToEmail(groups_ci, groupId) if (not no_idmapping) or (groupEmailPattern is not None):
# all groups are in the root OU so the orgUnit attribute is useless _, _, groupEmail = convertGroupCloudIDToEmail(groups_ci, groupId)
policy['policyQuery'].pop('orgUnit', None) if not no_idmapping:
policy['policyQuery']['groupEmail'] = groupEmail
if groupEmailPattern is not None: if groupEmailPattern is not None:
return groupEmailPattern.match(policy['policyQuery']['groupEmail']) return groupEmailPattern.match(groupEmail)
if orgUnitPathPattern is not None:
return False
elif orgId := policy['policyQuery'].get('orgUnit'): elif orgId := policy['policyQuery'].get('orgUnit'):
policy['policyQuery']['orgUnitPath'] = convertOrgUnitIDtoPath(cd, orgId) if (not no_idmapping) or (orgUnitPathPattern is not None):
orgUnitPath = convertOrgUnitIDtoPath(cd, orgId)
if not no_idmapping:
policy['policyQuery']['orgUnitPath'] = orgUnitPath
if orgUnitPathPattern is not None: if orgUnitPathPattern is not None:
return orgUnitPathPattern.match(policy['policyQuery']['orgUnitPath']) return orgUnitPathPattern.match(orgUnitPath)
if groupEmailPattern is not None:
return False
return True return True
def _showPolicy(policy, FJQC, i=0, count=0): def _showPolicy(policy, FJQC, i=0, count=0):
@@ -37819,9 +37817,8 @@ def _showPolicy(policy, FJQC, i=0, count=0):
printBlankLine() printBlankLine()
Ind.Decrement() Ind.Decrement()
def _showPolicies(policies, FJQC, add_warnings, no_appnames, def _showPolicies(policies, FJQC, add_warnings, no_appnames, no_idmapping,
groupEmailPattern, orgUnitPathPattern, groupEmailPattern, orgUnitPathPattern, cd, groups_ci):
cd, groups_ci):
count = len(policies) count = len(policies)
if FJQC is None or not FJQC.formatJSON: if FJQC is None or not FJQC.formatJSON:
if groupEmailPattern is None and orgUnitPathPattern is None: if groupEmailPattern is None and orgUnitPathPattern is None:
@@ -37832,9 +37829,8 @@ def _showPolicies(policies, FJQC, add_warnings, no_appnames,
i = 0 i = 0
for policy in policies: for policy in policies:
i += 1 i += 1
if _cleanPolicy(policy, add_warnings, no_appnames, if _cleanPolicy(policy, add_warnings, no_appnames, no_idmapping,
groupEmailPattern, orgUnitPathPattern, groupEmailPattern, orgUnitPathPattern, cd, groups_ci):
cd, groups_ci):
_showPolicy(policy, FJQC, i, count) _showPolicy(policy, FJQC, i, count)
Ind.Decrement() Ind.Decrement()
@@ -37884,6 +37880,7 @@ def doCreateUpdateCIPolicy():
if 'setting' in jsonData: if 'setting' in jsonData:
if 'value' in jsonData['setting']: if 'value' in jsonData['setting']:
jsonData['setting']['value'].pop('createTime', None) jsonData['setting']['value'].pop('createTime', None)
jsonData['setting']['value'].pop('deleteTime', None)
jsonData['setting']['value'].pop('updateTime', None) jsonData['setting']['value'].pop('updateTime', None)
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -37891,12 +37888,14 @@ def doCreateUpdateCIPolicy():
orgUnit, targetResource = _getCIPolicyOrgUnitTarget(cd, myarg, groupEmail) orgUnit, targetResource = _getCIPolicyOrgUnitTarget(cd, myarg, groupEmail)
jsonData.setdefault('policyQuery', {}) jsonData.setdefault('policyQuery', {})
jsonData['policyQuery'].pop('group', None) jsonData['policyQuery'].pop('group', None)
jsonData['policyQuery']['orgUnit'] = targetResource jsonData['policyQuery']['orgUnit'] = f"orgUnits/{targetResource}"
jsonData['policyQuery']['query'] = f"entity.org_units.exists(org_unit, org_unit.org_unit_id == orgUnitId('{targetResource}'))"
elif myarg == 'group': elif myarg == 'group':
groupEmail, targetResource = _getCIPolicyGroupTarget(cd, myarg, orgUnit) groupEmail, targetResource = _getCIPolicyGroupTarget(cd, myarg, orgUnit)
jsonData.setdefault('policyQuery', {}) jsonData.setdefault('policyQuery', {})
jsonData['policyQuery'].pop('orgUnit', None) jsonData['policyQuery'].pop('orgUnit', None)
jsonData['policyQuery']['group'] = targetResource jsonData['policyQuery']['group'] = f"groups/{targetResource}"
jsonData['policyQuery']['query'] = f"entity.groups.exists(group, group.group_id == groupId('{targetResource}'))"
else: else:
unknownArgumentExit() unknownArgumentExit()
jsonData['customer'] = _getCustomersCustomerIdWithC() jsonData['customer'] = _getCustomersCustomerIdWithC()
@@ -37906,7 +37905,6 @@ def doCreateUpdateCIPolicy():
bailOnInternalError=True, bailOnInternalError=True,
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.UNIMPLEMENTED_ERROR, throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.UNIMPLEMENTED_ERROR,
GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR], GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
name=pname, body=jsonData) name=pname, body=jsonData)
else: else:
result = callGAPI(ci.policies(), 'create', result = callGAPI(ci.policies(), 'create',
@@ -37979,7 +37977,7 @@ def doDeleteCIPolicies():
Ind.Decrement() Ind.Decrement()
# gam info policies <CIPolicyNameEntity> # gam info policies <CIPolicyNameEntity>
# [nowarnings] [noappnames] # [nowarnings] [noappnames] [noidmappiong]
# [formatjson] # [formatjson]
def doInfoCIPolicies(): def doInfoCIPolicies():
_checkPoliciesWithDASA() _checkPoliciesWithDASA()
@@ -37989,13 +37987,15 @@ def doInfoCIPolicies():
entityList = getEntityList(Cmd.OB_CIPOLICY_NAME_ENTITY) entityList = getEntityList(Cmd.OB_CIPOLICY_NAME_ENTITY)
FJQC = FormatJSONQuoteChar() FJQC = FormatJSONQuoteChar()
add_warnings = True add_warnings = True
no_appnames = False no_appnames = no_idmapping = False
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
if myarg == 'nowarnings': if myarg == 'nowarnings':
add_warnings = False add_warnings = False
elif myarg == 'noappnames': elif myarg == 'noappnames':
no_appnames = True no_appnames = True
elif myarg == 'noidmapping':
no_idmapping = True
else: else:
FJQC.GetFormatJSON(myarg) FJQC.GetFormatJSON(myarg)
i = 0 i = 0
@@ -38008,7 +38008,7 @@ def doInfoCIPolicies():
bailOnInternalError=True, bailOnInternalError=True,
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT,
GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR], GAPI.NOT_FOUND, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
name=pname, fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')] name=pname)]
except (GAPI.invalid, GAPI.invalidArgument, GAPI.notFound, GAPI.permissionDenied, GAPI.internalError) as e: except (GAPI.invalid, GAPI.invalidArgument, GAPI.notFound, GAPI.permissionDenied, GAPI.internalError) as e:
entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count) entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count)
continue continue
@@ -38018,15 +38018,15 @@ def doInfoCIPolicies():
ifilter = f"setting.type.matches('{pname}')" ifilter = f"setting.type.matches('{pname}')"
printGettingAllAccountEntities(Ent.POLICY, ifilter) printGettingAllAccountEntities(Ent.POLICY, ifilter)
policies = _filterPolicies(ci, getPageMessage(), ifilter) policies = _filterPolicies(ci, getPageMessage(), ifilter)
_showPolicies(policies, FJQC, add_warnings, no_appnames, _showPolicies(policies, FJQC, add_warnings, no_appnames, no_idmapping,
None, None, cd, groups_ci) None, None, cd, groups_ci)
# gam print policies [todrive <ToDriveAttribute>*] # gam print policies [todrive <ToDriveAttribute>*]
# [filter <String>] [nowarnings] [noappnames] # [filter <String>] [nowarnings] [noappnames] [noidmappiong]
# [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] # [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
# [formatjson [quotechar <Character>]] # [formatjson [quotechar <Character>]]
# gam show policies # gam show policies
# [filter <String>] [nowarnings] [noappnames] # [filter <String>] [nowarnings] [noappnames] [noidmappiong]
# [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>] # [group <REMatchPattern>] [ou|org|orgunit <REMatchPattern>]
# [formatjson] # [formatjson]
def doPrintShowCIPolicies(): def doPrintShowCIPolicies():
@@ -38048,7 +38048,7 @@ def doPrintShowCIPolicies():
FJQC = FormatJSONQuoteChar(csvPF) FJQC = FormatJSONQuoteChar(csvPF)
ifilter = None ifilter = None
add_warnings = True add_warnings = True
no_appnames = False no_appnames = no_idmapping = False
groupEmailPattern = orgUnitPathPattern = None groupEmailPattern = orgUnitPathPattern = None
while Cmd.ArgumentsRemaining(): while Cmd.ArgumentsRemaining():
myarg = getArgument() myarg = getArgument()
@@ -38060,6 +38060,8 @@ def doPrintShowCIPolicies():
add_warnings = False add_warnings = False
elif myarg == 'noappnames': elif myarg == 'noappnames':
no_appnames = True no_appnames = True
elif myarg == 'noidmapping':
no_idmapping = True
elif myarg == 'group': elif myarg == 'group':
groupEmailPattern = getREPattern(re.IGNORECASE) groupEmailPattern = getREPattern(re.IGNORECASE)
elif myarg in {'ou', 'org', 'orgunit'}: elif myarg in {'ou', 'org', 'orgunit'}:
@@ -38069,14 +38071,12 @@ def doPrintShowCIPolicies():
printGettingAllAccountEntities(Ent.POLICY, ifilter) printGettingAllAccountEntities(Ent.POLICY, ifilter)
policies = _filterPolicies(ci, getPageMessage(), ifilter) policies = _filterPolicies(ci, getPageMessage(), ifilter)
if not csvPF: if not csvPF:
_showPolicies(policies, FJQC, add_warnings, no_appnames, _showPolicies(policies, FJQC, add_warnings, no_appnames, no_idmapping,
groupEmailPattern, orgUnitPathPattern, groupEmailPattern, orgUnitPathPattern, cd, groups_ci)
cd, groups_ci)
else: else:
for policy in policies: for policy in policies:
if _cleanPolicy(policy, add_warnings, no_appnames, if _cleanPolicy(policy, add_warnings, no_appnames, no_idmapping,
groupEmailPattern, orgUnitPathPattern, groupEmailPattern, orgUnitPathPattern, cd, groups_ci):
cd, groups_ci):
_printPolicy(policy) _printPolicy(policy)
if csvPF: if csvPF:
csvPF.writeCSVfile('Policies') csvPF.writeCSVfile('Policies')