From cc45a7adb78650d13cc921433b897fe415e2c76f Mon Sep 17 00:00:00 2001 From: Ross Scroggs Date: Sun, 27 Oct 2024 09:35:58 -0700 Subject: [PATCH] Updated `gam info policies` to accept different policy specifications --- .github/workflows/winget.yml | 2 +- .travis.yml | 14 +++--- src/GamCommands.txt | 3 +- src/GamUpdate.txt | 7 +++ src/gam/__init__.py | 83 ++++++++++++++++++++---------------- 5 files changed, 63 insertions(+), 46 deletions(-) diff --git a/.github/workflows/winget.yml b/.github/workflows/winget.yml index d6bc7263..523b8396 100644 --- a/.github/workflows/winget.yml +++ b/.github/workflows/winget.yml @@ -10,7 +10,7 @@ jobs: - uses: vedantmgoyal2009/winget-releaser@v2 with: identifier: taers232c.GAMADV-XTD3 - release-tag: v7.00.31 + release-tag: v7.00.32 max-versions-to-keep: 1 # keep only latest versions installers-regex: '\.msi$' token: ${{ secrets.WINGET_TOKEN }} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 244e04c9..87961381 100644 --- a/.travis.yml +++ b/.travis.yml @@ -95,10 +95,10 @@ script: before_deploy: # Comment out for Linux Xenial and Trusty -#- yes | gem update --system --force -#- gem install bundler -#- gem install uri -#- gem install logger +- yes | gem update --system --force +- gem install bundler +- gem install uri +- gem install logger - export TRAVIS_TAG="preview" - unset LD_LIBRARY_PATH @@ -111,10 +111,10 @@ deploy: skip_cleanup: true draft: true # Linux 64-Bit Bionic and Linux ARM64 Focal and Linux ARM64 Bionic and Linux ARM64 Xenial -# edge: true + edge: true # Linux Xenial and Trusty - edge: - branch: v2.0.3-beta.4 +# edge: +# branch: v2.0.3-beta.4 # branch: v2.0.5-beta.1 on: repo: taers232c/GAMADV-XTD3 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 0ca1c1be..580a859a 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -378,7 +378,7 @@ If an item contains spaces, it should be surrounded by ". ::= ::= ||groups/ ::= customer|group|other|serviceaccount|user - ::= policies/ + ::= policies/|settings/| ::= ::= ::= @@ -4078,7 +4078,6 @@ gam update deviceuserstate [clientid ] gam info policies [nowarnings] [noappnames] [formatjson] - gam print policies [todrive *] [filter ] [nowarnings] [noappnames] [formatjson [quotechar ]] diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 27200ed4..e7736872 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -1,3 +1,10 @@ +7.00.32 + +Updated `gam info policies` to accept different policy specifications: +* `polices/` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4` +* `settings/` - A policy setting type, `settings/workspace_marketplace.apps_allowlist' +* `` - A policy setting type, `workspace_marketplace.apps_allowlist' + 7.00.31 Updated `gam info|print|show policies` to make additional API calls for `settings/workspace_marketplace.apps_allowlist` diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 89c882c5..e60a6466 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -25,7 +25,7 @@ """ __author__ = 'Ross Scroggs ' -__version__ = '7.00.31' +__version__ = '7.00.32' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' #pylint: disable=wrong-import-position @@ -9253,6 +9253,7 @@ def doCheckConnection(): hosts = ['api.github.com', 'raw.githubusercontent.com', 'accounts.google.com', + 'workspace.google.com', 'oauth2.googleapis.com', 'www.googleapis.com'] fix_hosts = {'calendar-json.googleapis.com': 'www.googleapis.com', @@ -35089,6 +35090,20 @@ def updateFieldsForCIGroupMatchPatterns(matchPatterns, fieldsList, csvPF=None): CIPOLICY_TIME_OBJECTS = {'createTime', 'updateTime'} +def _filterPolicies(ci, pageMessage, ifilter): + try: + policies = callGAPIpages(ci.policies(), 'list', 'policies', + pageMessage=pageMessage, + throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], + filter=ifilter, + fields='nextPageToken,policies(name,policyQuery(group,orgUnit,sortOrder),type,setting)', + pageSize=100) + # Google returns unordered results, sort them by setting type + return sorted(policies, key=lambda p: p.get('setting', {}).get('type', '')) + except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: + entityActionFailedWarning([Ent.POLICY, ifilter], str(e)) + return [] + # Policies where GAM should offer additional guidance and information CIPOLICY_ADDITIONAL_WARNINGS = { 'settings/drive_and_docs.external_sharing': { @@ -35146,6 +35161,17 @@ def _showPolicy(policy, FJQC, i=0, count=0): printBlankLine() Ind.Decrement() +def _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci): + count = len(policies) + performActionNumItems(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) + Ind.Decrement() + # gam info policies # [nowarnings] [noappnames] # [formatjson] @@ -35169,20 +35195,24 @@ def doInfoCIPolicies(): count = len(entityList) for pname in entityList: i += 1 - if not pname.startswith('policies/'): - pname = 'policies/'+pname - try: - policy = callGAPI(ci.policies(), 'get', - bailOnInternalError=True, - throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR], - name=pname, - fields='name,policyQuery(group,orgUnit,sortOrder),type,setting') - _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci) - _showPolicy(policy, FJQC, i, count) - except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e: - entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count) - continue - + if pname.startswith('policies/'): + try: + policies = [callGAPI(ci.policies(), 'get', + bailOnInternalError=True, + throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR], + name=pname, + fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')] + except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e: + entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count) + continue + else: + if pname.startswith('settings/'): + pname = pname.split('/')[1] + 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) + # gam print policies [todrive *] # [filter ] [nowarnings] [noappnames] # [formatjson [quotechar ]] @@ -35222,28 +35252,9 @@ def _printPolicy(policy): else: FJQC.GetFormatJSONQuoteChar(myarg, True) printGettingAllAccountEntities(Ent.POLICY, ifilter) - pageMessage = getPageMessage() - try: - policies = callGAPIpages(ci.policies(), 'list', 'policies', - pageMessage=pageMessage, - throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED], - filter=ifilter, - fields='nextPageToken,policies(name,policyQuery(group,orgUnit,sortOrder),type,setting)', - pageSize=100) - except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: - entityActionFailedExit([Ent.POLICY, None], str(e)) - # Google returns unordered results, sort them by setting type - policies = sorted(policies, key=lambda p: p.get('setting', {}).get('type', '')) + policies = _filterPolicies(ci, getPageMessage(), ifilter) if not csvPF: - count = len(policies) - performActionNumItems(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) - Ind.Decrement() + _showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci) else: for policy in policies: _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci)