mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Compare commits
22 Commits
v7.00.30
...
20241031.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9c4c006b2 | ||
|
|
378c763aa3 | ||
|
|
e46c837416 | ||
|
|
a478d45258 | ||
|
|
5476c4d14f | ||
|
|
2759d59cbf | ||
|
|
d2213709f0 | ||
|
|
d2840b95d5 | ||
|
|
49cdad014b | ||
|
|
532271130c | ||
|
|
628ef4aeff | ||
|
|
34b344baf9 | ||
|
|
b2daeffa36 | ||
|
|
3440fa7415 | ||
|
|
77bf001195 | ||
|
|
5d0003ce93 | ||
|
|
a0c4be1d5c | ||
|
|
95be4e2d53 | ||
|
|
5f8705fc09 | ||
|
|
975833bf87 | ||
|
|
b4e3f25c1e | ||
|
|
bb198c8c1a |
BIN
.github/actions/creds.tar.xz.gpg
vendored
BIN
.github/actions/creds.tar.xz.gpg
vendored
Binary file not shown.
18
.github/actions/decrypt.sh
vendored
Normal file → Executable file
18
.github/actions/decrypt.sh
vendored
Normal file → Executable file
@@ -23,10 +23,16 @@ fi
|
|||||||
gpg --batch \
|
gpg --batch \
|
||||||
--yes \
|
--yes \
|
||||||
--decrypt \
|
--decrypt \
|
||||||
--passphrase="${PASSCODE}" \
|
--passphrase="$PASSCODE" \
|
||||||
--output "${credsfile}" \
|
--output "$credsfile" \
|
||||||
"${gpgfile}"
|
"$gpgfile"
|
||||||
|
|
||||||
tar xvvf "${credsfile}" --directory "${credspath}"
|
if [[ "$RUNNER_OS" == "macOS" ]]; then
|
||||||
rm -rvf "${gpgfile}"
|
tar="gtar"
|
||||||
rm -rvf "${credsfile}"
|
else
|
||||||
|
tar="tar"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$tar" xlvvf "$credsfile" --directory "$credspath"
|
||||||
|
rm -rvf "$gpgfile"
|
||||||
|
rm -rvf "$credsfile"
|
||||||
|
|||||||
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@@ -805,6 +805,8 @@ jobs:
|
|||||||
# cleanup old runs
|
# cleanup old runs
|
||||||
$gam config enable_dasa false save
|
$gam config enable_dasa false save
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultholds || if [ $? != 55 ]; then exit $?; fi | $gam csv - gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~"
|
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print vaultholds || if [ $? != 55 ]; then exit $?; fi | $gam csv - gam delete vaulthold "id:~~holdId~~" matter "id:~~matterId~~"
|
||||||
|
$gam config csv_output_row_filter "name:regex:gha_test_${HID}_" print vaultmatters matterstate OPEN | $gam csv - gam update vaultmatter "id:~~matterId~~" action close
|
||||||
|
$gam config csv_output_row_filter "name:regex:gha_test_${HID}_" print vaultmatters matterstate CLOSED | $gam csv - gam update vaultmatter "id:~~matterId~~" action delete
|
||||||
$gam config enable_dasa true save
|
$gam config enable_dasa true save
|
||||||
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print features | $gam csv - gam delete feature ~name
|
$gam config csv_output_row_filter "name:regex:gha_test_${JID}_" print features | $gam csv - gam delete feature ~name
|
||||||
$gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" user $gam_user print shareddrives asadmin | $gam csv - gam user $gam_user delete shareddrive ~id nukefromorbit
|
$gam config csv_output_row_filter "name:regex:^gha_test_${JID}_" user $gam_user print shareddrives asadmin | $gam csv - gam user $gam_user delete shareddrive ~id nukefromorbit
|
||||||
@@ -824,8 +826,7 @@ jobs:
|
|||||||
done
|
done
|
||||||
driveid=$($gam user $gam_user add shareddrive "${newbase}" returnidonly)
|
driveid=$($gam user $gam_user add shareddrive "${newbase}" returnidonly)
|
||||||
echo "Created shared drive ${driveid}"
|
echo "Created shared drive ${driveid}"
|
||||||
# 9/17/24 - temp create in root due to Google API issues creating users in new OUs
|
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- ou "${newou}"
|
||||||
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- # ou "${newou}"
|
|
||||||
$gam user $newuser add license workspaceenterpriseplus
|
$gam user $newuser add license workspaceenterpriseplus
|
||||||
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff
|
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff
|
||||||
$gam user $newuser get photo
|
$gam user $newuser get photo
|
||||||
@@ -834,7 +835,9 @@ jobs:
|
|||||||
$gam create group $newgroup name "GHA $JID group" description "This is a description" isarchived true
|
$gam create group $newgroup name "GHA $JID group" description "This is a description" isarchived true
|
||||||
$gam user $gam_user sendemail recipient dev-null@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
$gam user $gam_user sendemail recipient dev-null@pdl.jaylee.us subject "test message $newbase" message "GHA test message"
|
||||||
$gam config enable_dasa false save
|
$gam config enable_dasa false save
|
||||||
#$gam create contact firstname GHA lastname "$JID" email work "${newbase}@example.com" primary
|
# don't expose policy output
|
||||||
|
$gam show policies > policies.csv
|
||||||
|
$gam create contact firstname GHA lastname "$JID" email work "${newbase}@example.com" primary
|
||||||
$gam print contacts
|
$gam print contacts
|
||||||
$gam print privileges
|
$gam print privileges
|
||||||
$gam config enable_dasa true save
|
$gam config enable_dasa true save
|
||||||
|
|||||||
@@ -282,7 +282,7 @@
|
|||||||
<GIGroupAlias> ::= <EmailAddress>
|
<GIGroupAlias> ::= <EmailAddress>
|
||||||
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
||||||
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
||||||
<CIPolicyName> ::= policies/<String>
|
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||||
<ClassroomInvitationID> ::= <String>
|
<ClassroomInvitationID> ::= <String>
|
||||||
<ClientID> ::= <String>
|
<ClientID> ::= <String>
|
||||||
<CommandID> ::= <String>
|
<CommandID> ::= <String>
|
||||||
|
|||||||
@@ -11,7 +11,10 @@
|
|||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
To use these commands you must update your client access authentication.
|
To use these commands you must update your client access authentication.
|
||||||
|
You'll enter 19R to turn on the Cloud Identity Policy scope; then continue
|
||||||
|
with authentication.
|
||||||
```
|
```
|
||||||
|
gam oauth delete
|
||||||
gam oauth create
|
gam oauth create
|
||||||
...
|
...
|
||||||
[R] 19) Cloud Identity - Policy
|
[R] 19) Cloud Identity - Policy
|
||||||
@@ -19,7 +22,7 @@ gam oauth create
|
|||||||
|
|
||||||
## Definitions
|
## Definitions
|
||||||
```
|
```
|
||||||
<CIPolicyName> ::= policies/<String>
|
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||||
<CIPolicyNameList> ::= "<CIPolicyName>(,<CIPolicyName>)*"
|
<CIPolicyNameList> ::= "<CIPolicyName>(,<CIPolicyName>)*"
|
||||||
<CIPolicyNameEntity> ::=
|
<CIPolicyNameEntity> ::=
|
||||||
<CIPolicyNameList> | <FileSelector> | <CSVFileSelector>
|
<CIPolicyNameList> | <FileSelector> | <CSVFileSelector>
|
||||||
@@ -27,17 +30,19 @@ gam oauth create
|
|||||||
|
|
||||||
## Policies
|
## Policies
|
||||||
These are the supported policies GAM can show today.
|
These are the supported policies GAM can show today.
|
||||||
|
|
||||||
|
See: https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings
|
||||||
```
|
```
|
||||||
user_takeout_status (is takeout enabled for service)
|
user_takeout_status (is takeout enabled for service)
|
||||||
blogger
|
blogger.user_takeout
|
||||||
books
|
books.user_takeout
|
||||||
location_history
|
location_history.user_takeout
|
||||||
maps
|
maps.user_takeout
|
||||||
pay
|
pay.user_takeout
|
||||||
photos
|
photos.user_takeout
|
||||||
play
|
play.user_takeout
|
||||||
play_console
|
play_console.user_takeout
|
||||||
youtube
|
youtube.user_takeout
|
||||||
service_status (is service enabled)
|
service_status (is service enabled)
|
||||||
ad_manager
|
ad_manager
|
||||||
ads
|
ads
|
||||||
@@ -311,39 +316,53 @@ workspace_marketplace.apps_allowlist
|
|||||||
Display selected policies.
|
Display selected policies.
|
||||||
```
|
```
|
||||||
gam info policies <CIPolicyEntity>
|
gam info policies <CIPolicyEntity>
|
||||||
[nowarnings]
|
[nowarnings] [noappnames]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Select policies::
|
||||||
|
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||||
|
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist'
|
||||||
|
* `<String>` - A policy setting type, `workspace_marketplace.apps_allowlist'
|
||||||
|
|
||||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||||
|
|
||||||
|
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||||
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
Display all or filtered policies.
|
Display all or filtered policies.
|
||||||
```
|
```
|
||||||
gam show policies
|
gam show policies
|
||||||
[filter <String>] [nowarnings]
|
[filter <String>] [nowarnings] [noappnames]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
```
|
```
|
||||||
By default, all policies are displayed.
|
By default, all policies are displayed.
|
||||||
* `filter <String>` - Display filtered policies, See https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Policies
|
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
||||||
|
|
||||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||||
|
|
||||||
|
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||||
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
By default, Gam displays the information as an indented list of keys and values.
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
```
|
```
|
||||||
gam print policies [todrive <ToDriveAttribute>*]
|
gam print policies [todrive <ToDriveAttribute>*]
|
||||||
[filter <String>] [nowarnings]
|
[filter <String>] [nowarnings] [noappnames]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
By default, all policies are displayed:
|
By default, all policies are displayed:
|
||||||
* `filter <String>` - Display filtered policies, See https://github.com/taers232c/GAMADV-XTD3/wiki/Cloud-Identity-Policies
|
* `filter <String>` - Display filtered policies, See https://cloud.google.com/identity/docs/reference/rest/v1beta1/policies/list
|
||||||
|
|
||||||
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
By default, policy warnings are displayed, use the 'nowarnings` option to suppress their display.
|
||||||
|
|
||||||
|
By default, additional API calls are made for `settings/workspace_marketplace.apps_allowlist`
|
||||||
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
|
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|
||||||
|
|||||||
@@ -306,26 +306,10 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
|
|||||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||||
|
|
||||||
## Display global address list
|
## Display global address list
|
||||||
```
|
As of mid-October 2024, Google deprecated the API that retrieved the Global Address List.
|
||||||
gam info gal <ContactEntity>
|
|
||||||
[basic|full]
|
|
||||||
[fields <ContactFieldNameList>] [formatjson]
|
|
||||||
gam show gal <ContactSelection>
|
|
||||||
[basic|full] [orderby <ContactOrderByFieldName> [ascending|descending]]
|
|
||||||
[fields <ContactFieldNameList>] [formatjson]
|
|
||||||
```
|
|
||||||
By default, Gam displays the information as an indented list of keys and values.
|
|
||||||
* `formatjson` - Display the fields in JSON format.
|
|
||||||
```
|
|
||||||
gam print gal [todrive <ToDriveAttribute>*] <ContactSelection>
|
|
||||||
[basic|full] [orderby <ContactOrderByFieldName> [ascending|descending]]
|
|
||||||
[fields <ContactFieldNameList>] [formatjson [quotechar <Character>]]
|
|
||||||
```
|
|
||||||
By default, Gam displays the information as columns of fields.
|
|
||||||
* `formatjson` - Display the fields in JSON format.
|
|
||||||
|
|
||||||
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
|
These commands are a work-around.
|
||||||
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.
|
gam config csv_output_row_filter "includeInGlobalAddressList:boolean:true" redirect csv ./UserGAL.csv print users fields name,gal
|
||||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
gam config csv_output_row_filter "includeInGlobalAddressList:boolean:true" batch_size 25 redirect csv ./GroupGAL.csv print groups fields name,gal
|
||||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
```
|
||||||
|
|||||||
@@ -10,6 +10,26 @@ 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
|
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 7.00.34
|
||||||
|
|
||||||
|
Fixed bug introduced in 7.00.33 in `gam print group-members` that caused a trap.
|
||||||
|
|
||||||
|
### 7.00.33
|
||||||
|
|
||||||
|
Fixed bug in `gam print group-members ... cachememberinfo` that caused a trap.
|
||||||
|
|
||||||
|
### 7.00.32
|
||||||
|
|
||||||
|
Updated `gam info policies` to accept different policy specifications:
|
||||||
|
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||||
|
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist`
|
||||||
|
* `<String>` - 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`
|
||||||
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
### 7.00.30
|
### 7.00.30
|
||||||
|
|
||||||
Added command to display selected Cloud Identity policies.
|
Added command to display selected Cloud Identity policies.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
!# Installation - Upgrading from Legacy GAM
|
# Installation - Upgrading from Legacy GAM
|
||||||
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
|
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
|
||||||
and all necessary authentications.
|
and all necessary authentications.
|
||||||
|
|
||||||
@@ -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$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin$ gam version
|
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
|
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||||
GAM 7.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.00.34 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
MacOS Sonoma 14.5 x86_64
|
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:\>del C:\GAMConfig\oauth2.txt
|
||||||
C:\>gam version
|
C:\>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAM7 7.00.30 - https://github.com/GAM-team/GAM - pythonsource
|
GAM7 7.00.34 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.00.34 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
MacOS Sonoma 14.5 x86_64
|
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
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAM 7.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.00.34 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
MacOS Sonoma 14.5 x86_64
|
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
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.00.30 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.00.34 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
MacOS Sonoma 14.5 x86_64
|
MacOS Sonoma 14.5 x86_64
|
||||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 7.00.30
|
Latest: 7.00.34
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -72,7 +72,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
7.00.30
|
7.00.34
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -82,7 +82,7 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 7.00.30 - https://github.com/GAM-team/GAM
|
GAM 7.00.34 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.0 64-bit final
|
Python 3.13.0 64-bit final
|
||||||
MacOS Sonoma 14.5 x86_64
|
MacOS Sonoma 14.5 x86_64
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
<GIGroupAlias> ::= <EmailAddress>
|
<GIGroupAlias> ::= <EmailAddress>
|
||||||
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
<GIGroupItem> ::= <EmailAddress>|<UniqueID>|groups/<String>
|
||||||
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
<CIGroupType> ::= customer|group|other|serviceaccount|user
|
||||||
<CIPolicyName> ::= policies/<String>
|
<CIPolicyName> ::= policies/<String>|settings/<String>|<String>
|
||||||
<ClassroomInvitationID> ::= <String>
|
<ClassroomInvitationID> ::= <String>
|
||||||
<ClientID> ::= <String>
|
<ClientID> ::= <String>
|
||||||
<CommandID> ::= <String>
|
<CommandID> ::= <String>
|
||||||
@@ -4076,14 +4076,13 @@ gam update deviceuserstate <DeviceUserEntity> [clientid <String>]
|
|||||||
# Cloud Identity Policies
|
# Cloud Identity Policies
|
||||||
|
|
||||||
gam info policies <CIPolicyNameEntity>
|
gam info policies <CIPolicyNameEntity>
|
||||||
[nowarnings]
|
[nowarnings] [noappnames]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
gam print policies [todrive <ToDriveAttribute>*]
|
gam print policies [todrive <ToDriveAttribute>*]
|
||||||
[filter <String>] [nowarnings]
|
[filter <String>] [nowarnings] [noappnames]
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
gam show policies
|
gam show policies
|
||||||
[filter <String>] [nowarnings]
|
[filter <String>] [nowarnings] [noappnames]
|
||||||
[formatjson]
|
[formatjson]
|
||||||
|
|
||||||
# Inbound SSO
|
# Inbound SSO
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
|
7.00.34
|
||||||
|
|
||||||
|
Fixed bug introduced in 7.00.33 in `gam print group-members` that caused a trap.
|
||||||
|
|
||||||
|
7.00.33
|
||||||
|
|
||||||
|
Fixed bug in `gam print group-members ... cachememberinfo` that caused a trap.
|
||||||
|
|
||||||
|
7.00.32
|
||||||
|
|
||||||
|
Updated `gam info policies` to accept different policy specifications:
|
||||||
|
* `polices/<String>` - A policy name, `policies/ahv4hg7qc24kvaghb7zihwf4riid4`
|
||||||
|
* `settings/<String>` - A policy setting type, `settings/workspace_marketplace.apps_allowlist`
|
||||||
|
* `<String>` - 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`
|
||||||
|
to get the application name for the application ID. Use option `noappnames` to suppress these calls.
|
||||||
|
|
||||||
7.00.30
|
7.00.30
|
||||||
|
|
||||||
Added command to display selected Cloud Identity policies.
|
Added command to display selected Cloud Identity policies.
|
||||||
|
|||||||
@@ -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.00.30'
|
__version__ = '7.00.34'
|
||||||
__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
|
||||||
@@ -9253,6 +9253,7 @@ def doCheckConnection():
|
|||||||
hosts = ['api.github.com',
|
hosts = ['api.github.com',
|
||||||
'raw.githubusercontent.com',
|
'raw.githubusercontent.com',
|
||||||
'accounts.google.com',
|
'accounts.google.com',
|
||||||
|
'workspace.google.com',
|
||||||
'oauth2.googleapis.com',
|
'oauth2.googleapis.com',
|
||||||
'www.googleapis.com']
|
'www.googleapis.com']
|
||||||
fix_hosts = {'calendar-json.googleapis.com': 'www.googleapis.com',
|
fix_hosts = {'calendar-json.googleapis.com': 'www.googleapis.com',
|
||||||
@@ -33899,22 +33900,24 @@ def doPrintGroupMembers():
|
|||||||
row['name'] = unknownName
|
row['name'] = unknownName
|
||||||
if memberType == Ent.TYPE_USER:
|
if memberType == Ent.TYPE_USER:
|
||||||
try:
|
try:
|
||||||
if not cacheMemberInfo or memberId not in memberNames:
|
if not cacheMemberInfo or memberId not in memberInfo:
|
||||||
mbinfo = callGAPI(cd.users(), 'get',
|
mbinfo = callGAPI(cd.users(), 'get',
|
||||||
throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.SERVICE_NOT_AVAILABLE, GAPI.FAILED_PRECONDITION],
|
throwReasons=GAPI.USER_GET_THROW_REASONS+[GAPI.SERVICE_NOT_AVAILABLE, GAPI.FAILED_PRECONDITION],
|
||||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||||
userKey=memberId, projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'],
|
userKey=memberId, projection=schemaParms['projection'], customFieldMask=schemaParms['customFieldMask'],
|
||||||
fields=userFields)
|
fields=userFields)
|
||||||
if memberOptions[MEMBEROPTION_MEMBERNAMES]:
|
if memberOptions[MEMBEROPTION_MEMBERNAMES]:
|
||||||
row['name'] = mbinfo['name'].pop('fullName')
|
mname = mbinfo['name'].pop('fullName', unknownName)
|
||||||
|
row['name'] = mname
|
||||||
if not mbinfo['name']:
|
if not mbinfo['name']:
|
||||||
mbinfo.pop('name')
|
mbinfo.pop('name')
|
||||||
|
if cacheMemberInfo:
|
||||||
|
memberNames[memberId] = mname
|
||||||
if cacheMemberInfo:
|
if cacheMemberInfo:
|
||||||
memberNames[memberId] = row['name']
|
memberInfo[memberId] = mbinfo
|
||||||
if mbinfo:
|
|
||||||
memberInfo[memberId] = mbinfo
|
|
||||||
else:
|
else:
|
||||||
row['name'] = memberNames[memberId]
|
if memberOptions[MEMBEROPTION_MEMBERNAMES]:
|
||||||
|
row['name'] = memberNames[memberId]
|
||||||
mbinfo = memberInfo.get(memberId, {})
|
mbinfo = memberInfo.get(memberId, {})
|
||||||
if not FJQC.formatJSON:
|
if not FJQC.formatJSON:
|
||||||
csvPF.WriteRowTitles(flattenJSON(mbinfo, flattened=row))
|
csvPF.WriteRowTitles(flattenJSON(mbinfo, flattened=row))
|
||||||
@@ -35089,6 +35092,20 @@ def updateFieldsForCIGroupMatchPatterns(matchPatterns, fieldsList, csvPF=None):
|
|||||||
|
|
||||||
CIPOLICY_TIME_OBJECTS = {'createTime', 'updateTime'}
|
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
|
# Policies where GAM should offer additional guidance and information
|
||||||
CIPOLICY_ADDITIONAL_WARNINGS = {
|
CIPOLICY_ADDITIONAL_WARNINGS = {
|
||||||
'settings/drive_and_docs.external_sharing': {
|
'settings/drive_and_docs.external_sharing': {
|
||||||
@@ -35097,10 +35114,32 @@ CIPOLICY_ADDITIONAL_WARNINGS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def _cleanPolicy(policy, add_warnings, cd, groups_ci):
|
def _getPolicyAppNameFromId(httpObj, app):
|
||||||
|
app['applicationName'] = UNKNOWN
|
||||||
|
appId = app['applicationId']
|
||||||
|
url = f'https://workspace.google.com/marketplace/app/_/{appId}'
|
||||||
|
try:
|
||||||
|
resp, content = httpObj.request(url, 'GET')
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
if resp.status != 200:
|
||||||
|
return
|
||||||
|
if isinstance(content, bytes):
|
||||||
|
content = content.decode()
|
||||||
|
pattern = f'https://workspace.google.com/marketplace/app/(.+?)/{appId}'
|
||||||
|
a = re.search(pattern, content)
|
||||||
|
if a:
|
||||||
|
app['applicationName'] = a.group(1)
|
||||||
|
|
||||||
|
def _cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci):
|
||||||
# convert any wordlists into spaced strings to reduce output complexity
|
# convert any wordlists into spaced strings to reduce output complexity
|
||||||
if policy['setting']['type'] == 'settings/detector.word_list':
|
if policy['setting']['type'] == 'settings/detector.word_list':
|
||||||
policy['setting']['value']['wordList'] = ' '.join(policy['setting']['value']['wordList']['words'])
|
policy['setting']['value']['wordList'] = ' '.join(policy['setting']['value']['wordList']['words'])
|
||||||
|
# get application name for application id
|
||||||
|
if policy['setting']['type'] == 'settings/workspace_marketplace.apps_allowlist' and not no_appnames:
|
||||||
|
httpObj = getHttpObj(timeout=10)
|
||||||
|
for app in policy['setting']['value'].get('apps', []):
|
||||||
|
_getPolicyAppNameFromId(httpObj, app)
|
||||||
# add any warnings to applicable policies
|
# add any warnings to applicable policies
|
||||||
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']]
|
||||||
@@ -35124,8 +35163,20 @@ def _showPolicy(policy, FJQC, i=0, count=0):
|
|||||||
printBlankLine()
|
printBlankLine()
|
||||||
Ind.Decrement()
|
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 <CIPolicyNameEntity>
|
# gam info policies <CIPolicyNameEntity>
|
||||||
# [nowarnings] [formatjson]
|
# [nowarnings] [noappnames]
|
||||||
|
# [formatjson]
|
||||||
def doInfoCIPolicies():
|
def doInfoCIPolicies():
|
||||||
groups_ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
|
groups_ci = buildGAPIObject(API.CLOUDIDENTITY_GROUPS)
|
||||||
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
|
ci = buildGAPIObject(API.CLOUDIDENTITY_POLICY)
|
||||||
@@ -35133,35 +35184,42 @@ 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
|
||||||
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':
|
||||||
|
no_appnames=True
|
||||||
else:
|
else:
|
||||||
FJQC.GetFormatJSON(myarg)
|
FJQC.GetFormatJSON(myarg)
|
||||||
i = 0
|
i = 0
|
||||||
count = len(entityList)
|
count = len(entityList)
|
||||||
for pname in entityList:
|
for pname in entityList:
|
||||||
i += 1
|
i += 1
|
||||||
if not pname.startswith('policies/'):
|
if pname.startswith('policies/'):
|
||||||
pname = 'policies/'+pname
|
try:
|
||||||
try:
|
policies = [callGAPI(ci.policies(), 'get',
|
||||||
policy = callGAPI(ci.policies(), 'get',
|
bailOnInternalError=True,
|
||||||
bailOnInternalError=True,
|
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
||||||
throwReasons=[GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.INTERNAL_ERROR],
|
name=pname,
|
||||||
name=pname,
|
fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')]
|
||||||
fields='name,policyQuery(group,orgUnit,sortOrder),type,setting')
|
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
||||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count)
|
||||||
_showPolicy(policy, FJQC, i, count)
|
continue
|
||||||
except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied, GAPI.internalError) as e:
|
else:
|
||||||
entityActionFailedWarning([Ent.POLICY, pname], str(e), i, count)
|
if pname.startswith('settings/'):
|
||||||
continue
|
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 <ToDriveAttribute>*]
|
# gam print policies [todrive <ToDriveAttribute>*]
|
||||||
# [filter <String>] [nowarnings]
|
# [filter <String>] [nowarnings] [noappnames]
|
||||||
# [formatjson [quotechar <Character>]]
|
# [formatjson [quotechar <Character>]]
|
||||||
# gam show policies
|
# gam show policies
|
||||||
# [filter <String>] [nowarnings]
|
# [filter <String>] [nowarnings] [noappnames]
|
||||||
# [formatjson]
|
# [formatjson]
|
||||||
def doPrintShowCIPolicies():
|
def doPrintShowCIPolicies():
|
||||||
|
|
||||||
@@ -35182,6 +35240,7 @@ def doPrintShowCIPolicies():
|
|||||||
FJQC = FormatJSONQuoteChar(csvPF)
|
FJQC = FormatJSONQuoteChar(csvPF)
|
||||||
ifilter = None
|
ifilter = None
|
||||||
add_warnings = True
|
add_warnings = True
|
||||||
|
no_appnames = False
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if csvPF and myarg == 'todrive':
|
if csvPF and myarg == 'todrive':
|
||||||
@@ -35190,34 +35249,17 @@ def doPrintShowCIPolicies():
|
|||||||
ifilter = getString(Cmd.OB_STRING)
|
ifilter = getString(Cmd.OB_STRING)
|
||||||
elif myarg == 'nowarnings':
|
elif myarg == 'nowarnings':
|
||||||
add_warnings = False
|
add_warnings = False
|
||||||
|
elif myarg == 'noappnames':
|
||||||
|
no_appnames=True
|
||||||
else:
|
else:
|
||||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||||
printGettingAllAccountEntities(Ent.POLICY, ifilter)
|
printGettingAllAccountEntities(Ent.POLICY, ifilter)
|
||||||
pageMessage = getPageMessage()
|
policies = _filterPolicies(ci, getPageMessage(), 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)
|
|
||||||
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', ''))
|
|
||||||
if not csvPF:
|
if not csvPF:
|
||||||
count = len(policies)
|
_showPolicies(policies, FJQC, add_warnings, no_appnames, cd, groups_ci)
|
||||||
performActionNumItems(count, Ent.POLICY)
|
|
||||||
Ind.Increment()
|
|
||||||
i = 0
|
|
||||||
for policy in policies:
|
|
||||||
i += 1
|
|
||||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
|
||||||
_showPolicy(policy, FJQC, i, count)
|
|
||||||
Ind.Decrement()
|
|
||||||
else:
|
else:
|
||||||
for policy in policies:
|
for policy in policies:
|
||||||
_cleanPolicy(policy, add_warnings, cd, groups_ci)
|
_cleanPolicy(policy, add_warnings, no_appnames, cd, groups_ci)
|
||||||
_printPolicy(policy)
|
_printPolicy(policy)
|
||||||
if csvPF:
|
if csvPF:
|
||||||
csvPF.writeCSVfile('Policies')
|
csvPF.writeCSVfile('Policies')
|
||||||
|
|||||||
Reference in New Issue
Block a user