diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 500d811b..1b32a1d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,68 +31,73 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-20.04 + - os: ubuntu-22.04 jid: 1 goal: build arch: x86_64 openssl_archs: linux-x86_64 - - os: [self-hosted, linux, arm64] + - os: ubuntu-20.04 jid: 2 goal: build + arch: x86_64 + openssl_archs: linux-x86_64 + - os: [self-hosted, linux, arm64] + jid: 3 + goal: build arch: aarch64 openssl_archs: linux-aarch64 - os: ubuntu-20.04 - jid: 3 + jid: 4 goal: build arch: x86_64 openssl_archs: linux-x86_64 staticx: yes - os: [self-hosted, linux, arm64] - jid: 4 + jid: 5 goal: build arch: aarch64 openssl_archs: linux-aarch64 staticx: yes - os: macos-12 - jid: 5 + jid: 6 goal: build arch: x86_64 openssl_archs: darwin64-x86_64 - os: macos-14 - jid: 6 + jid: 7 goal: build arch: aarch64 openssl_archs: darwin64-arm64 # - os: macos-14 -# jid: 7 +# jid: 8 # goal: build # arch: universal2 # openssl_archs: darwin64-arm64 darwin64-x86_64 - os: windows-2022 - jid: 8 + jid: 9 goal: build arch: Win64 openssl_archs: VC-WIN64A - os: ubuntu-22.04 goal: test python: "3.8" - jid: 9 - arch: x86_64 - - os: ubuntu-22.04 - goal: test - python: "3.9" jid: 10 arch: x86_64 - os: ubuntu-22.04 goal: test - python: "3.10" + python: "3.9" jid: 11 arch: x86_64 - os: ubuntu-22.04 goal: test - python: "3.11" + python: "3.10" jid: 12 arch: x86_64 + - os: ubuntu-22.04 + goal: test + python: "3.11" + jid: 13 + arch: x86_64 steps: @@ -115,7 +120,7 @@ jobs: with: path: | cache.tar.xz - key: gam-${{ matrix.jid }}-20240903 + key: gam-${{ matrix.jid }}-20240914 - name: Untar Cache archive if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true' diff --git a/docs/Chrome-Policies.md b/docs/Chrome-Policies.md index 62e63410..479ab44c 100644 --- a/docs/Chrome-Policies.md +++ b/docs/Chrome-Policies.md @@ -14,8 +14,10 @@ - [Display Chrome policies](#display-chrome-policies) - [Copy simple policies set directly in one OU to another OU](#copy-simple-policies-set-directly-in-one-ou-to-another-ou) - [Copy simple and complex policies set directly in one OU to another OU](#copy-simple-and-complex-policies-set-directly-in-one-ou-to-another-ou) + - [Copy simple and complex policies set directly in one OU to multiple other OUs](#copy-simple-and-complex-policies-set-directly-in-one-ou-to-multiple-other-ous) - [Copy simple policies in one Group to another Group](#copy-simple-policies-in-one-group-to-another-group) - [Copy simple and complex policies in one Group to another Group](#copy-simple-and-complex-policies-in-one-group-to-another-group) + - [Copy simple and complex policies in one Group to multiple other Groups](#copy-simple-and-complex-policies-in-one-group-to-multiple-other-groups) - [Create Chrome network](#create-chrome-network) - [Delete Chrome network](#delete-chrome-network) - [Chrome Policy Schema Table](#chrome-policy-schema-table) @@ -356,6 +358,22 @@ gam redirect csv ChromePolicies.csv print chromepolicies ou "/Path/To/OU1" forma gam config csv_input_row_filter "direct:boolean:true" csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU2" ``` +## Copy simple and complex policies set directly in one OU to multiple other OUs +Display direct policies, update all +``` +gam redirect csv ChromePolicies.csv print chromepolicies ou "/Path/To/OU1" show direct formatjson quotechar "'" +``` +Make a batch file (SetPolicies.bat) with a line for each target OU +``` +gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU2" +gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU3" +... +``` +Execute batch +``` +gam redirect stdout ./SetPolicies.log multiprocess redirect stderr stdout tbatch SetPolicies.bat +``` + ## Copy simple policies in one Group to another Group Display all policies, update all ``` @@ -369,6 +387,22 @@ gam redirect csv ChromePolicies.csv print chromepolicies group group1@domain.com gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group2@domain.com ``` +## Copy simple and complex policies in one Group to multiple other Groups +Display all policies, update all +``` +gam redirect csv ChromePolicies.csv print chromepolicies group group1@domain.com formatjson quotechar "'" +``` +Make a batch file (SetPolicies.bat) with a line for each target group +``` +gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group2@domain.com +gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group3@domain.com +... +``` +Execute batch +``` +gam redirect stdout ./SetPolicies.log multiprocess redirect stderr stdout tbatch SetPolicies.bat +``` + ## Create Chrome network See: [Chrome Policy Schema Table](#chrome-policy-schema-table) for the allowed network settings. * chrome.networks.ethernet.Details: Ethernet network configuration details. diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 6ad5d80c..ae789be8 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,15 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads-Installs](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation +### 7.00.01 + +Added option `shownames` to `gam print|show sheet` that causes GAM +to make an additional API call to get and display the sheet file name that is not supplied by the Sheets API. + +### 7.00.00 + +Merged GAM-Team version + ### 6.81.02 Updated `gam update group postmaster@domain.com` to handle the error that is generated. diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index e7588a4f..9b6bd2ac 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.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 -GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 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 -GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Users-Spreadsheets.md b/docs/Users-Spreadsheets.md index 4e2991af..0b9badd4 100644 --- a/docs/Users-Spreadsheets.md +++ b/docs/Users-Spreadsheets.md @@ -231,18 +231,24 @@ gam user testuser@domain.com update sheet json file Sheet.json gam info|show sheet [fields ] [sheetsfields ] (range )* (rangelist )* - [includegriddata []] + [includegriddata []] [shownames] [formatjson] ``` +By default, the Sheets API does not return the sheet file name, use the `shownames` option to have GAM +make an additional API call to get and display the sheet file name. + The output is formatted for human readability. Use the following option to produce JSON output for program parsing. * `formatjson` - Display output in JSON format. ``` gam print sheet [todrive *] [fields ] [sheetsfields ] (range )* (rangelist )* - [includegriddata []] + [includegriddata []] [shownames] [formatjson [quotechar ]] ``` +By default, the Sheets API does not return the sheet file name, use the `shownames` option to have GAM +make an additional API call to get and display the sheet file name. + 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. diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 5c40d6ae..25f6ed7c 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 -GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 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 -GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 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 -GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 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/gamadv-xtd3 Version Check: Current: 5.35.08 - Latest: 6.81.02 + Latest: 7.00.01 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.81.02 +7.00.01 ``` 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 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 +GAM 7.00.01 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 diff --git a/src/GamCommands.txt b/src/GamCommands.txt index 9ce64494..f2f1ff7c 100644 --- a/src/GamCommands.txt +++ b/src/GamCommands.txt @@ -3541,11 +3541,11 @@ gam [] show drivelabels [formatjson] [adminaccess|asadmin] ` gam [] create drivelabelpermission - (user ) | (group ) + (user ) | (group ) | (audience ) role applier|editor|organizer|reader [formatjson] [adminaccess|asadmin] gam [] delete drivelabelpermission - (user ) | (group ) + (user ) | (group ) | (audience ) [adminaccess|asadmin] gam [] remove drivelabelpermission [adminaccess|asadmin] @@ -7052,7 +7052,7 @@ gam show filecounts [corpora ] [select ] [anyowner|(showownedby any|me|others)] - [showmimetype [not] ] [`] + [showmimetype [not] ] [showmimetype category ] [sizefield quotabytesused|size] [minimumfilesize ] [maximumfilesize ] [filenamematchpattern ] * [] [] @@ -8244,12 +8244,12 @@ gam update sheet gam info|show sheet [fields ] [sheetsfields ] (range )* (rangelist )* - [includegriddata []] + [includegriddata []] [shownames] [formatjson] gam print sheet [todrive *] [fields ] [sheetsfields ] (range )* (rangelist )* - [includegriddata []] + [includegriddata []] [shownames] [formatjson [quotechar ]] See: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values#ValueRange diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 9909ec20..ca6a96fd 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -1,3 +1,9 @@ +7.00.01 + +Added option `shownames` to `gam print|show sheet` that causes GAM +to make an additional API call to get and display the sheet file name that is not supplied by the Sheets API. + + 7.00.00 Merged GAM-Team version diff --git a/src/gam-install.sh b/src/gam-install.sh index f42637f5..06e522de 100755 --- a/src/gam-install.sh +++ b/src/gam-install.sh @@ -16,7 +16,7 @@ OPTIONS: -u Admin user email address to use with GAM. Default is to prompt. -r Regular user email address. Used to test service account access to user data. Default is to prompt. -v Version to install (latest, prerelease, draft, 3.8, etc). Default is latest. - -s Strip gam7 component from extracted files, files will be downloaded directly to $target_dir + -s Strip gam component from extracted files, files will be downloaded directly to $target_dir EOF } @@ -30,7 +30,7 @@ upgrade_only=false gamversion="latest" adminuser="" regularuser="" -gam_x86_64_glibc_vers="2.31" +gam_x86_64_glibc_vers="2.35 2.31" gam_arm64_glibc_vers="2.31" strip_gam="--strip-components 0" @@ -172,7 +172,9 @@ case $gamos in ;; esac -if [ "$gamversion" == "latest" -o "$gamversion" == "prerelease" -o "$gamversion" == "draft" ]; then +if [ "$gamversion" == "latest" ]; then + release_url="https://api.github.com/repos/GAM-team/GAM/releases/latest" +elif [ "$gamversion" == "prerelease" -o "$gamversion" == "draft" ]; then release_url="https://api.github.com/repos/GAM-team/GAM/releases" else release_url="https://api.github.com/repos/GAM-team/GAM/releases/tags/v$gamversion" diff --git a/src/gam/__init__.py b/src/gam/__init__.py index dac0c730..757c8b72 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.00' +__version__ = '7.00.01' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' #pylint: disable=wrong-import-position @@ -66995,14 +66995,14 @@ SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP = { } # gam info|show sheet -# [fields ] +# [fields ] [sheetsfields ] # (range )* (rangelist )* -# [includegriddata []] +# [includegriddata []] [shownames] # [formatjson] # gam print sheet [todrive *] -# [fields ] +# [fields ] [sheetsfields ] # (range )* (rangelist )* -# [includegriddata []] +# [includegriddata []] [shownames] # [formatjson [quotechar ]] def infoPrintShowSheets(users): csvPF = CSVPrintFile(['User', 'spreadsheetId'], 'sortall') if Act.csvFormat() else None @@ -67010,7 +67010,7 @@ def infoPrintShowSheets(users): spreadsheetIdEntity = getDriveFileEntity() fieldsList = [] ranges = [] - includeGridData = False + includeGridData = showSheetNames = False while Cmd.ArgumentsRemaining(): myarg = getArgument() if csvPF and myarg == 'todrive': @@ -67029,8 +67029,16 @@ def infoPrintShowSheets(users): fieldsList.append(SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP[field]) else: invalidChoiceExit(field, SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP, True) + elif myarg == 'shownames': + showSheetNames = True else: FJQC.GetFormatJSONQuoteChar(myarg, True) + if csvPF and showSheetNames: + csvPF.AddTitles('spreadsheetName') + csvPF.SetSortAllTitles() + if FJQC.formatJSON: + csvPF.AddJSONTitles('spreadsheetName') + csvPF.MoveJSONTitlesToEnd(['JSON']) if includeGridData and fieldsList: fieldsList.append(SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP['data']) fields = getFieldsFromFieldsList(fieldsList) @@ -67040,6 +67048,10 @@ def infoPrintShowSheets(users): user, sheet, jcount = _validateUserGetSpreadsheetIDs(user, i, count, spreadsheetIdEntity, not FJQC.formatJSON) if jcount == 0: continue + if showSheetNames: + _, drive = buildGAPIServiceObject(API.DRIVE3, user, i, count) + if not drive: + continue Ind.Increment() j = 0 for spreadsheetId in spreadsheetIdEntity['list']: @@ -67051,11 +67063,25 @@ def infoPrintShowSheets(users): if not includeGridData and 'sheets' in result: for usheet in result['sheets']: usheet.pop('data', None) + if showSheetNames: + try: + spreadsheetName = callGAPI(drive.files(), 'get', + throwReasons=GAPI.DRIVE_GET_THROW_REASONS, + fileId=spreadsheetId, fields='name', supportsAllDrives=True)['name'] + except (GAPI.fileNotFound, GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy): + spreadsheetName = spreadsheetId if not csvPF: if FJQC.formatJSON: - printLine('{'+f'"User": "{user}", "spreadsheetId": "{spreadsheetId}", "JSON": {json.dumps(result, ensure_ascii=False, sort_keys=False)}'+'}') + baserow = {'User': user, 'spreadsheetId': spreadsheetId} + if showSheetNames: + baserow['spreadsheetName'] = spreadsheetName + baserow['JSON'] = result + printLine(json.dumps(baserow, ensure_ascii=False, sort_keys=False)+'\n') continue - printEntity([Ent.SPREADSHEET, spreadsheetId], j, jcount) + if showSheetNames: + printEntity([Ent.SPREADSHEET, f'{spreadsheetName}({spreadsheetId})'], j, jcount) + else: + printEntity([Ent.SPREADSHEET, spreadsheetId], j, jcount) Ind.Increment() if 'spreadsheetUrl' in result: printKeyValueList(['spreadsheetUrl', result['spreadsheetUrl']]) @@ -67074,12 +67100,15 @@ def infoPrintShowSheets(users): Ind.Decrement() Ind.Decrement() else: - row = flattenJSON(result, flattened={'User': user, 'spreadsheetId': spreadsheetId}) + baserow = {'User': user, 'spreadsheetId': spreadsheetId} + if showSheetNames: + baserow['spreadsheetName'] = spreadsheetName + row = flattenJSON(result, flattened=baserow.copy()) if not FJQC.formatJSON: csvPF.WriteRowTitles(row) elif csvPF.CheckRowTitles(row): - csvPF.WriteRowNoFilter({'User': user, 'spreadsheetId': spreadsheetId, - 'JSON': json.dumps(result, ensure_ascii=False, sort_keys=False)}) + baserow['JSON'] = json.dumps(cleanJSON(result), ensure_ascii=False, sort_keys=False) + csvPF.WriteRowNoFilter(baserow) except (GAPI.notFound, GAPI.forbidden, GAPI.permissionDenied, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.badRequest, GAPI.invalid, GAPI.invalidArgument, GAPI.failedPrecondition) as e: