diff --git a/docs/Cloud-Identity-Policies.md b/docs/Cloud-Identity-Policies.md index 87845c22..f5750ab3 100644 --- a/docs/Cloud-Identity-Policies.md +++ b/docs/Cloud-Identity-Policies.md @@ -1,6 +1,7 @@ # Cloud Identity Policies - [API documentation](#api-documentation) - [Notes](#notes) +- [Python Regular Expressions](Python-Regular-Expressions) Match function - [Definitions](#definitions) - [Policies](#policies) - [Display Cloud Identity Policies](#display-cloud-identity-policies) @@ -322,8 +323,8 @@ gam info policies Select policies:: * `polices/` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4` -* `settings/` - A policy setting type, `settings/workspace_marketplace.apps_allowlist' -* `` - A policy setting type, `workspace_marketplace.apps_allowlist' +* `settings/` - A policy setting type, `settings/workspace_marketplace.apps_allowlist` +* `` - A policy setting type, `workspace_marketplace.apps_allowlist` By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display. @@ -337,10 +338,13 @@ Display all or filtered policies. ``` gam show policies [filter ] [nowarnings] [noappnames] + [group ] [ou|org|orgunit ] [formatjson] ``` By default, all policies are displayed. * `filter ` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list +* `group ` - Only display policies whose group email address matches the `` +* `ou|org|orgunit - Only display policies whose OU path matches the `` By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display. @@ -353,10 +357,13 @@ By default, Gam displays the information as an indented list of keys and values. ``` gam print policies [todrive *] [filter ] [nowarnings] [noappnames] + [group ] [ou|org|orgunit ] [formatjson [quotechar ]] ``` By default, all policies are displayed: * `filter ` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list +* `group ` - Only display policies whose group email address matches the `` +* `ou|org|orgunit - Only display policies whose OU path matches the `` By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display. @@ -371,3 +378,9 @@ the quote character itself, the column delimiter (comma by default) and new-line When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output. The `quotechar ` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output. `quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used. + +### Examples +Print all service status policies. +``` +gam redirect csv ./ServiceStatusPolicies.csv print policies filter "setting.type.matches('.*service_status')" +``` diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 0d2bf9c7..3da129a9 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,16 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation +### 7.00.37 + +Added options `group ` and `ou|org|orgunit ` +to `gam print|show policies` that causes GAM to only display policies whose group email address +or OU path match the ``. + +Updated `gam get|update|delete contactphotos` to use the People API for domain shared contact photos +as Google has deprecated the Domain Shared Contacts API for these commands. Unfortunately, +the People API fails with `gam update|delete contactphotos`. + ### 7.00.36 Updated `gam print chromeapps` to correct a trap caused by an API change. diff --git a/docs/How-to-Upgrade-Legacy-GAM-to-GAM7.md b/docs/How-to-Upgrade-Legacy-GAM-to-GAM7.md index 9c2b8ce6..100b2375 100644 --- a/docs/How-to-Upgrade-Legacy-GAM-to-GAM7.md +++ b/docs/How-to-Upgrade-Legacy-GAM-to-GAM7.md @@ -251,7 +251,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin$ gam version WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found -GAM 7.00.36 - https://github.com/GAM-team/GAM - pyinstaller +GAM 7.00.37 - https://github.com/GAM-team/GAM - pyinstaller GAM Team Python 3.13.0 64-bit final MacOS Sonoma 14.5 x86_64 @@ -923,7 +923,7 @@ writes the credentials into the file oauth2.txt. C:\>del C:\GAMConfig\oauth2.txt C:\>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAM7 7.00.36 - https://github.com/GAM-team/GAM - pythonsource +GAM7 7.00.37 - https://github.com/GAM-team/GAM - pythonsource GAM Team Python 3.13.0 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Users-Calendars.md b/docs/Users-Calendars.md index fcf8c420..2e9690ad 100644 --- a/docs/Users-Calendars.md +++ b/docs/Users-Calendars.md @@ -6,8 +6,8 @@ - [Display calendar UI settings](#display-calendar-ui-settings) - [Manage calendars](#manage-calendars) - [Create and remove calendars](#create-and-remove-calendars) - - [Display calendar settings](#display-calendar-settings) - [Modify calendar settings](#modify-calendar-settings) + - [Display calendar settings](#display-calendar-settings) - [Manage calendar lists](#manage-calendar-lists) - [Display specific calendars from list](#display-specific-calendars-from-list) - [Display calendar lists](#display-calendar-lists) @@ -23,6 +23,8 @@ ::= @ ::= ::= "(,)*" + ::= | | | + See: https://github.com/taers232c/GAMADV-XTD3/wiki/Collections-of-Items ::= ::= |d: ::= "(,)*" @@ -38,6 +40,21 @@ ::= editor|freebusy|freebusyreader|owner|reader|writer + ::= + (description )| + (location )| + (summary )| + (timezone ) + + ::= + conferenceproperties| + description| + id| + location| + summary| + timezone + ::= "(,)*" + ::= minaccessrole | showdeleted| @@ -111,12 +128,6 @@ (selected )| (summary ) - ::= - (description )| - (location )| - (summary )| - (timezone ) - ::= accessrole| backgroundcolor| @@ -189,18 +200,30 @@ gam create calendar gam remove calendars ``` -### Display calendar settings -``` -gam info calendars [formatjson] -``` -By default, Gam displays the information as an indented list of keys and values. -* `formatjson` - Display the fields in JSON format. - ### Modify calendar settings ``` gam modify calendars ``` +### Display calendar settings +``` +gam calendar show settings + [fields ] + [formatjson] +``` +By default, Gam displays the information as an indented list of keys and values. +* `formatjson` - Display the fields in JSON format. +``` +gam calendar print settings [todrive *] + [fields ] + [formatjson [quotechar ]] +``` +By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain +the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled. +When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output. +The `quotechar ` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output. +`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used. + ## Manage calendar lists These commands manage a user's list of calendars. ``` diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 013e30a0..a7c75b28 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -3,7 +3,7 @@ Print the current version of Gam with details ``` gam version -GAM 7.00.36 - https://github.com/GAM-team/GAM - pyinstaller +GAM 7.00.37 - https://github.com/GAM-team/GAM - pyinstaller GAM Team Python 3.13.0 64-bit final MacOS Sonoma 14.5 x86_64 @@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00 Print the current version of Gam with details and time offset information ``` gam version timeoffset -GAM 7.00.36 - https://github.com/GAM-team/GAM - pyinstaller +GAM 7.00.37 - https://github.com/GAM-team/GAM - pyinstaller GAM Team Python 3.13.0 64-bit final MacOS Sonoma 14.5 x86_64 @@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second Print the current version of Gam with extended details and SSL information ``` gam version extended -GAM 7.00.36 - https://github.com/GAM-team/GAM - pyinstaller +GAM 7.00.37 - https://github.com/GAM-team/GAM - pyinstaller GAM Team Python 3.13.0 64-bit final MacOS Sonoma 14.5 x86_64 @@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64 Path: /Users/Admin/bin/gam7 Version Check: Current: 5.35.08 - Latest: 7.00.36 + Latest: 7.00.37 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -7.00.36 +7.00.37 ``` In Linux/MacOS you can do: ``` @@ -82,7 +82,7 @@ echo $VER Print the current version of Gam and address of this Wiki ``` gam help -GAM 7.00.36 - https://github.com/GAM-team/GAM +GAM 7.00.37 - https://github.com/GAM-team/GAM GAM Team Python 3.13.0 64-bit final MacOS Sonoma 14.5 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 727daed7..a958eb56 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -4075,9 +4075,11 @@ gam info policies [formatjson] gam print policies [todrive *] [filter ] [nowarnings] [noappnames] + [group ] [ou|org|orgunit ] [formatjson [quotechar ]] gam show policies [filter ] [nowarnings] [noappnames] + [group ] [ou|org|orgunit ] [formatjson] # Inbound SSO diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index eef6db3a..954dad5c 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -1,3 +1,13 @@ +7.00.37 + +Added options `group ` and `ou|org|orgunit ` +to `gam print|show policies` that causes GAM to only display policies whose group email address +or OU path match the ``. + +Updated `gam get|update|delete contactphotos` to use the People API for domain shared contact photos +as Google has deprecated the Domain Shared Contacts API for these commands. Unfortunately, +the People API fails with `gam update|delete contactphotos`. + 7.00.36 Updated `gam print chromeapps` to correct a trap caused by an API change. diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 1a383192..ab686864 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki """ __author__ = 'GAM Team ' -__version__ = '7.00.36' +__version__ = '7.00.37' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' #pylint: disable=wrong-import-position @@ -2693,6 +2693,11 @@ def performActionNumItems(itemCount, itemType, i=0, count=0): [f'{Act.ToPerform()} {itemCount} {Ent.Choose(itemType, itemCount)}'], currentCountNL(i, count))) +def performActionModifierNumItems(modifier, itemCount, itemType, i=0, count=0): + writeStdout(formatKeyValueList(Ind.Spaces(), + [f'{Act.ToPerform()} {modifier} {itemCount} {Ent.Choose(itemType, itemCount)}'], + currentCountNL(i, count))) + def actionPerformedNumItems(itemCount, itemType, i=0, count=0): writeStderr(formatKeyValueList(Ind.Spaces(), [f'{itemCount} {Ent.Choose(itemType, itemCount)} {Act.Performed()} '], @@ -20287,137 +20292,6 @@ def doPrintShowDomainContacts(): def doPrintShowGAL(): _printShowContacts(False) -def _processContactPhotos(function): - def _makeFilenameFromPattern(): - filename = filenamePattern[:] - if subForContactId: - filename = filename.replace('#contactid#', contactId) - if subForEmail: - for email in fields.get('Emails', []): - if email.get('primary', 'false') == 'true': - filename = filename.replace('#email#', email['value']) - break - else: - filename = filename.replace('#email#', contactId) - return filename - - entityType = Ent.DOMAIN - contactsManager = ContactsManager() - entityList, contactQuery, queriedContacts = _getContactEntityList(1, False) - if function in {'ChangePhoto', 'GetPhoto'}: - targetFolder = os.getcwd() - filenamePattern = '#contactid#.jpg' - while Cmd.ArgumentsRemaining(): - myarg = getArgument() - if myarg == 'drivedir': - targetFolder = GC.Values[GC.DRIVE_DIR] - elif myarg in {'sourcefolder', 'targetfolder'}: - targetFolder = os.path.expanduser(getString(Cmd.OB_FILE_PATH)) - if function == 'GetPhoto' and not os.path.isdir(targetFolder): - os.makedirs(targetFolder) - elif myarg == 'filename': - filenamePattern = getString(Cmd.OB_PHOTO_FILENAME_PATTERN) - else: - unknownArgumentExit() - subForContactId = filenamePattern.find('#contactid#') != -1 - subForEmail = filenamePattern.find('#email#') != -1 - if not subForContactId and not subForEmail: - filename = filenamePattern - else: #elif function == 'DeletePhoto': - checkForExtraneousArguments() - user, contactsObject = getContactsObject(True) - if queriedContacts: - entityList = queryContacts(contactsObject, contactQuery) - if entityList is None: - return - j = 0 - jcount = len(entityList) - entityPerformActionModifierNumItems([entityType, user], Msg.MAXIMUM_OF, jcount, Ent.PHOTO) - if jcount == 0: - setSysExitRC(NO_ENTITIES_FOUND_RC) - return - Ind.Increment() - for contact in entityList: - j += 1 - try: - if not queriedContacts: - contactId = normalizeContactId(contact) - contact = callGData(contactsObject, 'GetContact', - throwErrors=[GDATA.NOT_FOUND, GDATA.BAD_REQUEST, GDATA.SERVICE_NOT_APPLICABLE, GDATA.FORBIDDEN, GDATA.NOT_IMPLEMENTED], - retryErrors=[GDATA.INTERNAL_SERVER_ERROR], - uri=contactsObject.GetContactFeedUri(contact_list=user, contactId=contactId)) - fields = contactsManager.ContactToFields(contact) - else: - contactId = contactsManager.GetContactShortId(contact) - fields = contactsManager.ContactToFields(contact) - if not localContactSelects(contactsManager, contactQuery, fields): - continue - except (GDATA.notFound, GDATA.badRequest) as e: - entityActionFailedWarning([entityType, user, Ent.CONTACT, contactId], str(e), j, jcount) - break - except (GDATA.forbidden, GDATA.notImplemented): - entityServiceNotApplicableWarning(entityType, user) - break - except GDATA.serviceNotApplicable: - entityUnknownWarning(entityType, user) - break - try: - if function == 'ChangePhoto': - if subForContactId or subForEmail: - filename = _makeFilenameFromPattern() - filename = os.path.join(targetFolder, filename) - callGData(contactsObject, function, - throwErrors=[GDATA.NOT_FOUND, GDATA.BAD_REQUEST, GDATA.SERVICE_NOT_APPLICABLE, GDATA.FORBIDDEN, GDATA.NOT_IMPLEMENTED], - retryErrors=[GDATA.INTERNAL_SERVER_ERROR], - media=filename, contact_entry_or_url=contact, - content_type='image/*', content_length=os.path.getsize(filename), extra_headers={'If-Match': '*'}) - entityActionPerformed([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename]) - elif function == 'GetPhoto': - if subForContactId or subForEmail: - filename = _makeFilenameFromPattern() - filename = os.path.join(targetFolder, filename) - photo_data = callGData(contactsObject, function, - throwErrors=[GDATA.NOT_FOUND, GDATA.BAD_REQUEST, GDATA.SERVICE_NOT_APPLICABLE, GDATA.FORBIDDEN, GDATA.NOT_IMPLEMENTED], - retryErrors=[GDATA.INTERNAL_SERVER_ERROR], - contact_entry_or_url=contact) - if photo_data: - status, e = writeFileReturnError(filename, eval(photo_data), mode='wb') #pylint: disable=eval-used - if status: - entityActionPerformed([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename]) - else: - entityActionFailedWarning([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename], str(e)) - else: - entityDoesNotHaveItemWarning([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, '']) - else: #elif function == 'DeletePhoto': - filename = '' - callGData(contactsObject, function, - throwErrors=[GDATA.NOT_FOUND, GDATA.BAD_REQUEST, GDATA.SERVICE_NOT_APPLICABLE, GDATA.FORBIDDEN, GDATA.NOT_IMPLEMENTED], - retryErrors=[GDATA.INTERNAL_SERVER_ERROR], - contact_entry_or_url=contact, extra_headers={'If-Match': '*'}) - entityActionPerformed([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename]) - except GDATA.notFound as e: - entityActionFailedWarning([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename], str(e), j, jcount) - except (GDATA.badRequest, OSError, IOError) as e: - entityActionFailedWarning([entityType, user, Ent.CONTACT, contactId, Ent.PHOTO, filename], str(e), j, jcount) - except (GDATA.forbidden, GDATA.notImplemented): - entityServiceNotApplicableWarning(entityType, user) - break - Ind.Decrement() - -# gam update contactphotos | -# [drivedir|(sourcefolder )] [filename ] -def doUpdateDomainContactPhoto(): - _processContactPhotos('ChangePhoto') - -# gam get contactphotos | -# [drivedir|(targetfolder )] [filename ] -def doGetDomainContactPhoto(): - _processContactPhotos('GetPhoto') - -# gam delete contactphotos | -def doDeleteDomainContactPhoto(): - _processContactPhotos('DeletePhoto') - # Prople commands utilities # def normalizePeopleResourceName(resourceName): @@ -22634,9 +22508,16 @@ def _processPeopleContactPhotos(users, function): filename = filename.replace('#email#', resourceName.split('/')[1]) return filename - entityType = Ent.USER - peopleEntityType = Ent.PEOPLE_CONTACT - sources = [PEOPLE_READ_SOURCES_CHOICE_MAP['contact']] + if users is not None: + entityType = Ent.USER + peopleEntityType = Ent.PEOPLE_CONTACT + sources = [PEOPLE_READ_SOURCES_CHOICE_MAP['contact']] + else: + users = [None] + people = buildGAPIObject(API.PEOPLE_DIRECTORY) + entityType = Ent.DOMAIN + peopleEntityType = Ent.PEOPLE_CONTACT + sources = [PEOPLE_READ_SOURCES_CHOICE_MAP['domaincontact']] entityList, resourceNameLists, contactQuery, queriedContacts = _getPeopleContactEntityList(entityType, 1) if function in {'updateContactPhoto', 'getContactPhoto'}: targetFolder = os.getcwd() @@ -22665,9 +22546,12 @@ def _processPeopleContactPhotos(users, function): i += 1 if resourceNameLists: entityList = resourceNameLists[user] - user, people = buildGAPIServiceObject(API.PEOPLE, user, i, count) - if not people: - continue + if user is not None: + user, people = buildGAPIServiceObject(API.PEOPLE, user, i, count) + if not people: + continue + else: + user = Ent.Singular(entityType) if contactQuery['contactGroupSelect']: groupId, _, contactGroupNames = validatePeopleContactGroup(people, contactQuery['contactGroupSelect'], None, None, entityType, user, i, count) @@ -22774,6 +22658,20 @@ def getUserPeopleContactPhoto(users): def deleteUserPeopleContactPhoto(users): _processPeopleContactPhotos(users, 'deleteContactPhoto') +# gam update contactphotos | +# [drivedir|(sourcefolder )] [filename ] +def doUpdateDomainContactPhoto(): + _processPeopleContactPhotos(None, 'updateContactPhoto') + +# gam get contactphotos | +# [drivedir|(targetfolder )] [filename ] +def doGetDomainContactPhoto(): + _processPeopleContactPhotos(None, 'getContactPhoto') + +# gam delete contactphoto | +def doDeleteDomainContactPhoto(): + _processPeopleContactPhotos(None, 'deleteContactPhoto') + # gam create contactgroup + # [(csv [todrive *] (addcsvdata )*))| returnidonly] def createUserPeopleContactGroup(users): @@ -32648,6 +32546,8 @@ def infoGroups(entityList): getCloudIdentity = True cifields = getFieldsFromFieldsList(groupFieldsLists['ci']) ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS) + else: + cifields = None i = 0 count = len(entityList) for group in entityList: @@ -35131,7 +35031,9 @@ def _getPolicyAppNameFromId(httpObj, app): if a: app['applicationName'] = a.group(1) -def _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci): +def _cleanPolicy(policy, add_warnings, no_appnames, + groupEmailPattern, orgUnitPathPattern, + cd, groups_ci): # convert any wordlists into spaced strings to reduce output complexity if policy['setting']['type'] == 'settings/detector.word_list': policy['setting']['value']['wordList'] = ' '.join(policy['setting']['value']['wordList']['words']) @@ -35145,10 +35047,15 @@ def _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci): policy['warning'] = CIPOLICY_ADDITIONAL_WARNINGS[policy['setting']['type']] if groupId := policy['policyQuery'].get('group'): _, _, policy['policyQuery']['groupEmail'] = convertGroupCloudIDToEmail(groups_ci, groupId) + if groupEmailPattern is not None and not groupEmailPattern.match(policy['policyQuery']['groupEmail']): + return False # all groups are in the root OU so the orgUnit attribute is useless policy['policyQuery'].pop('orgUnit', None) elif orgId := policy['policyQuery'].get('orgUnit'): policy['policyQuery']['orgUnitPath'] = convertOrgUnitIDtoPath(cd, orgId) + if orgUnitPathPattern is not None and not orgUnitPathPattern.match(policy['policyQuery']['orgUnitPath']): + return False + return True def _showPolicy(policy, FJQC, i=0, count=0): if FJQC is not None and FJQC.formatJSON: @@ -35163,15 +35070,22 @@ def _showPolicy(policy, FJQC, i=0, count=0): printBlankLine() Ind.Decrement() -def _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci): +def _showPolicies(policies, FJQC, add_warnings, no_appnames, + groupEmailPattern, orgUnitPathPattern, + cd, groups_ci): count = len(policies) - performActionNumItems(count, Ent.POLICY) + if groupEmailPattern is None and orgUnitPathPattern is None: + performActionNumItems(count, Ent.POLICY) + else: + performActionModifierNumItems(Msg.MAXIMUM_OF, count, Ent.POLICY) Ind.Increment() i = 0 for policy in policies: i += 1 - _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci) - _showPolicy(policy, FJQC, i, count) + if _cleanPolicy(policy, add_warnings, no_appnames, + groupEmailPattern, orgUnitPathPattern, + cd, groups_ci): + _showPolicy(policy, FJQC, i, count) Ind.Decrement() # gam info policies @@ -35213,13 +35127,16 @@ def doInfoCIPolicies(): ifilter = f"setting.type.matches('{pname}')" printGettingAllAccountEntities(Ent.POLICY, ifilter) policies = _filterPolicies(ci, getPageMessage(), ifilter) - _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci) + _showPolicies(policies, FJQC, add_warnings, no_appnames, + None, None, cd, groups_ci) # gam print policies [todrive *] # [filter ] [nowarnings] [noappnames] +# [group ] [ou|org|orgunit ] # [formatjson [quotechar ]] # gam show policies # [filter ] [nowarnings] [noappnames] +# [group ] [ou|org|orgunit ] # [formatjson] def doPrintShowCIPolicies(): @@ -35241,6 +35158,7 @@ def doPrintShowCIPolicies(): ifilter = None add_warnings = True no_appnames = False + groupEmailPattern = orgUnitPathPattern = None while Cmd.ArgumentsRemaining(): myarg = getArgument() if csvPF and myarg == 'todrive': @@ -35250,17 +35168,25 @@ def doPrintShowCIPolicies(): elif myarg == 'nowarnings': add_warnings = False elif myarg == 'noappnames': - no_appnames=True + no_appnames = True + elif myarg == 'group': + groupEmailPattern = getREPattern(re.IGNORECASE) + elif myarg in {'ou', 'org', 'orgunit'}: + orgUnitPathPattern = getREPattern(re.IGNORECASE) else: FJQC.GetFormatJSONQuoteChar(myarg, True) printGettingAllAccountEntities(Ent.POLICY, ifilter) policies = _filterPolicies(ci, getPageMessage(), ifilter) if not csvPF: - _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci) + _showPolicies(policies, FJQC, add_warnings, no_appnames, + groupEmailPattern, orgUnitPathPattern, + cd, groups_ci) else: for policy in policies: - _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci) - _printPolicy(policy) + if _cleanPolicy(policy, add_warnings, no_appnames, + groupEmailPattern, orgUnitPathPattern, + cd, groups_ci): + _printPolicy(policy) if csvPF: csvPF.writeCSVfile('Policies')