Compare commits

..

142 Commits
v6.16 ... v6.20

Author SHA1 Message Date
Jay Lee
be4403331f Update var.py 2022-04-11 08:44:08 -04:00
Ross Scroggs
b84025debf Use new CI orgUnits.memberships/move (#1514)
Old method never seemed to work; commented code can probably be dropped
2022-04-11 02:33:45 -04:00
Jay Lee
4685f29aba Handle Cloud identity OrgUnits update 500 errors 2022-04-10 19:50:06 -04:00
Ross Scroggs
a832698366 Update CAA documentation (#1513) 2022-04-10 10:41:23 -04:00
Ross Scroggs
cf894fd0bd Code cleanup (#1512)
* Code cleanup

* Two fixes
2022-04-10 08:16:10 -04:00
Ross Scroggs
fd6c04bd94 Fix indentaton (#1511) 2022-04-09 14:20:22 -04:00
Ross Scroggs
49a2352d6d Standardize getting Shared Drive ID or Name (#1510) 2022-04-09 07:26:46 -04:00
Ross Scroggs
291871ec45 Update CAA osType in documentation (#1509) 2022-04-08 22:45:19 -04:00
Jay Lee
73c21a1156 Update caa.py 2022-04-08 19:42:20 -04:00
Ross Scroggs
27eed06617 Document CAA, minimumVersion is optional in constraint (#1508) 2022-04-08 19:39:29 -04:00
Ross Scroggs
a440cbbbdc Make print|show oushareddrives consistent with other commands (#1507) 2022-04-08 15:13:04 -04:00
Jay Lee
eb9ca5eb1d Update build.yml 2022-04-08 15:11:15 -04:00
Ross Scroggs
5eb1277691 Do print|show for caalevels and oushareddrives (#1506) 2022-04-08 12:28:11 -04:00
Ross Scroggs
6de424b185 Two updates (#1504) 2022-04-08 10:43:47 -04:00
Jay Lee
f89491d801 Update build.yml 2022-04-08 10:18:36 -04:00
Jay Lee
154de4818e Update build.yml 2022-04-08 09:57:02 -04:00
Jay Lee
c5895a3082 Update build.yml 2022-04-08 09:40:58 -04:00
Jay Lee
e085257a51 Update var.py 2022-04-08 09:37:22 -04:00
Ross Scroggs
d8e84cf045 Delete extraneous code, custom <String> is operative (#1503) 2022-04-07 21:12:37 -04:00
Jay Lee
a5eb61421d Update build.yml 2022-04-07 20:23:22 -04:00
Jay Lee
cddbea2718 don't use dasa for printer cmds 2022-04-08 00:10:38 +00:00
Jay Lee
c9bf5158e4 capture shared drive id 2022-04-07 23:58:32 +00:00
Jay Lee
7822b36f97 enable commands now that scopes should be present 2022-04-07 23:31:41 +00:00
Jay Lee
20d541ca8e juggle command order to give time for propogation 2022-04-07 23:26:50 +00:00
Jay Lee
72af9fb4a9 Update creds.tar.gpg 2022-04-07 23:17:24 +00:00
Jay Lee
a2972a3329 disable shared drive OU update for now, need to Actions 2022-04-07 20:31:22 +00:00
Jay Lee
97b74c0c8f fix shareddrive name 2022-04-07 20:20:02 +00:00
Jay Lee
332519e5d4 fix gam_user 2022-04-07 20:06:54 +00:00
Jay Lee
881641e2b4 gapi_drive 2022-04-07 19:53:11 +00:00
Jay Lee
82bfe74175 orgunits.py 2022-04-07 19:51:15 +00:00
Jay Lee
bac3451c21 OrgUnit Support for Shared Drives 2022-04-07 19:48:23 +00:00
Ross Scroggs
c97495ab05 Fix bug (#1502) 2022-04-07 15:36:56 -04:00
Jay Lee
aa3dad1e07 Merge branch 'main' of https://github.com/GAM-team/GAM 2022-04-07 17:00:05 +00:00
Jay Lee
2d4e15504c GAM 6.19 2022-04-07 16:59:58 +00:00
Jay Lee
3cd41e3d0f Update build.yml 2022-04-07 11:10:03 -04:00
Jay Lee
a94518c48d Update build.yml 2022-04-07 09:39:18 -04:00
Jay Lee
2837671ed7 Merge branch 'main' of https://github.com/GAM-team/GAM 2022-04-07 12:52:34 +00:00
Jay Lee
e49eed2a24 Improve error instructions for CAA 2022-04-07 12:52:21 +00:00
Jay Lee
edfc27c960 Update project-apis.txt 2022-04-07 08:29:25 -04:00
Jay Lee
41a10932cb handle >1 access policies in org, action tests 2022-04-07 01:21:15 +00:00
Jay Lee
119538c10c Support for CAA levels 2022-04-07 00:48:40 +00:00
Ross Scroggs
0a03fbb82e Fix add license message (#1497) 2022-03-31 13:38:18 -04:00
Ross Scroggs
b838054e2f Update pip install version (#1496) 2022-03-30 11:59:23 -04:00
Jay Lee
45ac118381 GAM 6.18 2022-03-30 08:16:20 -04:00
Jay Lee
e1600eadbc remove noupx and onefile args that already exist in spec file 2022-03-30 07:29:11 -04:00
Jay Lee
cc23f98078 [no cd] strip non-Win builds 2022-03-30 07:27:31 -04:00
Jay Lee
b68cc671eb Update build.yml 2022-03-29 20:10:44 -04:00
Jay Lee
8c215a0a0b Update build.yml 2022-03-29 20:10:21 -04:00
Jay Lee
374c6a9367 Update gam-install.sh 2022-03-29 19:53:04 -04:00
Jay Lee
5d93d9893e Update build.yml 2022-03-29 16:04:23 -04:00
Jay Lee
010c26ea89 Update build.yml 2022-03-29 14:23:28 -04:00
Jay Lee
5da90f7585 Update build.yml 2022-03-29 14:22:43 -04:00
Jay Lee
5356591d9c Update build.yml 2022-03-28 20:18:01 -04:00
Jay Lee
8df5d22805 Update build.yml 2022-03-28 19:39:17 -04:00
Jay Lee
5684ab3c05 Update build.yml 2022-03-28 18:33:38 -04:00
Jay Lee
d7b8f4c228 Update build.yml 2022-03-28 18:29:41 -04:00
Jay Lee
66fe03bbcd Update build.yml 2022-03-28 16:09:11 -04:00
Ross Scroggs
e7496dc9cb Fix bug in print vaultcounts ... account emailaddress (#1493) 2022-03-26 16:42:19 -04:00
Jay Lee
3b52af0b8a Update build.yml 2022-03-25 19:57:09 -04:00
Jay Lee
4ffe709ab9 Update build.yml 2022-03-16 12:28:35 -04:00
Jay Lee
c0c15a3ee5 Update build.yml 2022-03-16 08:33:51 -04:00
Jay Lee
b724330cb1 Update var.py 2022-03-14 15:49:11 -04:00
Jay Lee
8b9ce17959 Update gam-install.sh 2022-03-08 14:26:59 -05:00
Jay Lee
26116474c5 Update build.yml 2022-03-08 07:54:50 -05:00
Jay Lee
3411fd8557 Update build.yml 2022-03-08 07:22:01 -05:00
Jay Lee
0bee3e38a0 Update build.yml 2022-03-07 16:00:58 -05:00
Jay Lee
dcc2224657 Update build.yml 2022-03-07 15:24:07 -05:00
Jay Lee
1bf1c43f23 GAM 6.17 2022-03-07 20:11:56 +00:00
Jay Lee
53b336aee9 Try universal ToS. Fixes #1489 2022-03-07 19:51:43 +00:00
Jay Lee
94b5407cb4 Update build.yml 2022-03-04 14:52:59 -05:00
Jay Lee
e7357e69fb Update build.yml 2022-03-04 10:05:51 -05:00
Jay Lee
d5a036dfc6 Update build.yml 2022-03-04 08:23:32 -05:00
Jay Lee
e256de06d9 Update build.yml 2022-03-04 06:05:03 -05:00
Jay Lee
59beba616c Update build.yml 2022-03-03 21:53:50 -05:00
Jay Lee
735747e0d4 Update build.yml 2022-03-03 21:02:10 -05:00
Jay Lee
ab167d8c4c Update build.yml 2022-03-03 20:59:58 -05:00
Jay Lee
944f010a8c Update build.yml 2022-03-03 20:00:40 -05:00
Jay Lee
dd064a3843 Update build.yml 2022-03-03 18:14:20 -05:00
Jay Lee
244b20e1f0 Update build.yml 2022-03-03 18:12:40 -05:00
Jay Lee
88308a352b Update build.yml 2022-03-03 18:07:40 -05:00
Jay Lee
c63df9d245 Update build.yml 2022-03-03 17:20:11 -05:00
Jay Lee
2780ad2edc Update build.yml 2022-03-03 17:15:20 -05:00
Jay Lee
00b3122c2c Update build.yml 2022-03-03 14:13:05 -05:00
Jay Lee
18221be556 Update build.yml 2022-03-03 13:14:04 -05:00
Jay Lee
80abd9284f Update build.yml 2022-03-03 12:10:27 -05:00
Jay Lee
87b6cb073f Update build.yml 2022-03-03 12:03:55 -05:00
Jay Lee
e2cbbb2c93 Update build.yml 2022-03-03 09:30:08 -05:00
Jay Lee
c771b84463 Update build.yml 2022-03-02 20:40:31 -05:00
Jay Lee
2460e6957f Update build.yml 2022-03-02 18:35:55 -05:00
Jay Lee
0ec42eb796 Update build.yml 2022-03-02 10:40:37 -05:00
Jay Lee
b78b5ea9e1 Update build.yml 2022-03-02 10:31:27 -05:00
Jay Lee
d26bfc9aab Update build.yml 2022-03-02 09:21:52 -05:00
Jay Lee
c64730e07b Update build.yml 2022-03-02 09:19:45 -05:00
Jay Lee
f8b00b92b4 Update build.yml 2022-03-02 08:21:24 -05:00
Jay Lee
3c9ec2578e Update build.yml 2022-03-01 21:44:43 -05:00
Jay Lee
5f79f46e30 Update build.yml 2022-03-01 20:41:32 -05:00
Jay Lee
30c250c314 Update build.yml 2022-03-01 20:29:44 -05:00
Jay Lee
69f504d91c Update build.yml 2022-03-01 20:02:45 -05:00
Jay Lee
c505dd9c2b Update build.yml 2022-03-01 19:59:53 -05:00
Jay Lee
a7638dee0a Update build.yml 2022-03-01 17:14:31 -05:00
Jay Lee
b8e5ad5107 Update build.yml 2022-03-01 14:09:39 -05:00
Jay Lee
0b2d04bc6f Update build.yml 2022-03-01 13:22:39 -05:00
Jay Lee
803025b8c5 Update build.yml 2022-03-01 13:17:42 -05:00
Jay Lee
a7154da0b6 Update build.yml 2022-03-01 13:15:19 -05:00
Jay Lee
d04b33d1d9 [no ci] don't install Linux packages on cached runs 2022-03-01 12:26:22 -05:00
Jay Lee
614edc22ca Update gam.spec 2022-03-01 12:20:32 -05:00
Jay Lee
eeb760260a Update build.yml 2022-03-01 11:32:32 -05:00
Jay Lee
eb5d876487 Update build.yml 2022-03-01 10:45:50 -05:00
Jay Lee
3bf2c5c8b6 Update build.yml 2022-03-01 10:07:26 -05:00
Jay Lee
3c24049d66 Update build.yml 2022-03-01 09:27:42 -05:00
Jay Lee
1f1b6d45e3 Update build.yml 2022-03-01 09:00:00 -05:00
Jay Lee
7b8a17a544 Update build.yml 2022-03-01 08:35:41 -05:00
Jay Lee
95d1b1295e Update build.yml 2022-03-01 08:20:09 -05:00
Jay Lee
4abd0407c8 Update build.yml 2022-03-01 08:13:59 -05:00
Jay Lee
65f229875d Update build.yml 2022-03-01 08:11:53 -05:00
Jay Lee
9be84501ec Update build.yml 2022-03-01 07:20:23 -05:00
Jay Lee
6e400cabd0 Update build.yml 2022-02-28 22:11:00 -05:00
Jay Lee
1f00614551 Update build.yml 2022-02-28 21:45:59 -05:00
Jay Lee
1da61d076e Update build.yml 2022-02-28 21:26:08 -05:00
Jay Lee
2ce04b4dd2 Update build.yml 2022-02-28 21:10:38 -05:00
Jay Lee
94a52c80cd Update build.yml 2022-02-28 20:49:17 -05:00
Jay Lee
af71cf9a82 Update build.yml 2022-02-28 20:41:50 -05:00
Jay Lee
594c7d6d29 Update build.yml 2022-02-28 20:30:54 -05:00
Jay Lee
4575c3576f Update build.yml 2022-02-28 20:26:22 -05:00
Jay Lee
243a6d20cc Update build.yml 2022-02-28 20:19:57 -05:00
Jay Lee
9f27cc155a Update build.yml 2022-02-28 20:16:54 -05:00
Jay Lee
64bfa122bd Update build.yml 2022-02-28 20:04:31 -05:00
Jay Lee
5be9a3f219 Update build.yml 2022-02-28 20:01:50 -05:00
Jay Lee
b0a478c156 Update build.yml 2022-02-28 19:58:23 -05:00
Jay Lee
96b6a0bc2c Update build.yml 2022-02-28 19:44:01 -05:00
Jay Lee
c3b79c5330 Update build.yml 2022-02-28 16:43:32 -05:00
Jay Lee
da54738902 Update build.yml 2022-02-28 16:40:02 -05:00
Jay Lee
ced508443a Update build.yml 2022-02-28 16:38:20 -05:00
Jay Lee
22d0446da4 Update build.yml 2022-02-28 16:34:01 -05:00
Jay Lee
8c7b3455c9 Update build.yml 2022-02-28 16:30:58 -05:00
Jay Lee
eac145f010 Update build.yml 2022-02-28 16:20:30 -05:00
Jay Lee
8765d06c2f Update build.yml 2022-02-28 16:17:54 -05:00
Jay Lee
7d19450da7 Update build.yml 2022-02-28 16:14:26 -05:00
Jay Lee
4edaeee883 Update build.yml 2022-02-28 16:12:51 -05:00
Jay Lee
e44ea5dbed Apple M1 support part 1 2022-02-28 16:07:17 -05:00
Jay Lee
7ae61b0c6d Update build.yml 2022-02-28 14:30:45 -05:00
Jay Lee
f0ffdc371f Update build.yml 2022-02-28 14:29:02 -05:00
18 changed files with 848 additions and 189 deletions

Binary file not shown.

View File

@@ -12,10 +12,10 @@ defaults:
working-directory: src
env:
OPENSSL_CONFIG_OPTS: no-asm no-fips
OPENSSL_INSTALL_PATH: ${{ github.workspace }}/src/ssl
OPENSSL_CONFIG_OPTS: no-fips
OPENSSL_INSTALL_PATH: ${{ github.workspace }}/bin/ssl
OPENSSL_SOURCE_PATH: ${{ github.workspace }}/src/openssl
PYTHON_INSTALL_PATH: ${{ github.workspace }}/src/python
PYTHON_INSTALL_PATH: ${{ github.workspace }}/bin/python
PYTHON_SOURCE_PATH: ${{ github.workspace }}/src/cpython
jobs:
@@ -25,44 +25,50 @@ jobs:
matrix:
include:
- os: ubuntu-20.04
jid: 1
goal: build
arch: x86_64
openssl_archs: linux-x86_64
- os: [self-hosted, linux, arm64]
jid: 2
goal: build
arch: x86_64
- os: macos-11
arch: aarch64
openssl_archs: linux-aarch64
- os: [self-hosted, linux, arm]
jid: 3
goal: build
arch: x86_64
- os: windows-2022
arch: armv7l
openssl_archs: linux-armv4
- os: macos-11
jid: 4
goal: build
arch: Win64
arch: universal2
openssl_archs: darwin64-x86_64 darwin64-arm64
- os: windows-2022
jid: 5
goal: build
arch: Win64
openssl_archs: VC-WIN64A
- os: windows-2022
jid: 6
goal: build
arch: Win32
openssl_archs: VC-WIN32
- os: ubuntu-20.04
goal: test
python: "3.7"
jid: 6
arch: x86_64
- os: ubuntu-20.04
goal: test
python: "3.8"
jid: 7
arch: x86_64
- os: ubuntu-20.04
goal: test
python: "3.9"
python: "3.8"
jid: 8
arch: x86_64
- os: [self-hosted, linux, arm64]
- os: ubuntu-20.04
goal: test
python: "3.9"
jid: 9
goal: build
arch: aarch64
- os: [self-hosted, linux, arm]
jid: 10
goal: build
arch: armv7l
arch: x86_64
steps:
@@ -76,9 +82,8 @@ jobs:
id: cache-python-ssl
with:
path: |
src/python
src/ssl
key: gam-${{ matrix.jid }}-20220131
bin
key: gam-${{ matrix.jid }}-20220328-01
- name: Use pre-compiled Python for testing
if: matrix.python != ''
@@ -105,7 +110,6 @@ jobs:
echo "JID=${JID}" >> $GITHUB_ENV
echo "ACTIONS_CACHE=${ACTIONS_CACHE}" >> $GITHUB_ENV
echo "ACTIONS_GOAL=${ACTIONS_GOAL}" >> $GITHUB_ENV
echo "date=date" >> $GITHUB_ENV
- name: Install necessary hosted Linux packages
if: matrix.os == 'ubuntu-20.04'
@@ -114,6 +118,22 @@ jobs:
sudo apt-get -qq --yes update
sudo apt-get -qq --yes install swig libpcsclite-dev
- name: MacOS remove Homebrew
if: matrix.os == 'macos-11'
run: |
# remove everything except the libraries needed by yubikey-manager
brew uninstall $(brew list | grep -v 'pcre\|swig\|pcsc-lite')
- name: MacOS install tools
if: matrix.os == 'macos-11'
run: |
# Install latest Rust
curl -fsS -o rust.sh https://sh.rustup.rs
bash ./rust.sh -y
source $HOME/.cargo/env
# needed for Rust to compile cryptography Python package for universal2
rustup target add aarch64-apple-darwin
- name: Windows Configure VCode
uses: ilammy/msvc-dev-cmd@v1
if: matrix.os == 'windows-2022' && steps.cache-python-ssl.outputs.cache-hit != 'true'
@@ -125,54 +145,44 @@ jobs:
env:
arch: ${{ matrix.arch }}
jid: ${{ matrix.jid }}
openssl_archs: ${{ matrix.openssl_archs }}
run: |
echo "We are running on ${RUNNER_OS}"
if [[ "${arch}" == "Win64" ]]; then
PYEXTERNALS_PATH="amd64"
PYBUILDRELEASE_ARCH="x64"
OPENSSL_CONFIG_TARGET="VC-WIN64A"
GAM_ARCHIVE_ARCH="x86_64"
WIX_ARCH="x64"
CHOC_OPS=""
elif [[ "${arch}" == "Win32" ]]; then
PYEXTERNALS_PATH="win32"
PYBUILDRELEASE_ARCH="Win32"
OPENSSL_CONFIG_TARGET="VC-WIN32"
GAM_ARCHIVE_ARCH="x86"
WIX_ARCH="x86"
CHOC_OPS="--forcex86"
fi
if [[ "${RUNNER_OS}" == "macOS" ]]; then
brew install coreutils
brew install bash
#brew install coreutils
#brew install bash
MAKE=make
MAKEOPT="-j$(sysctl -n hw.logicalcpu)"
PERL=perl
# We only care about non-deprecated OSes
MACOSX_DEPLOYMENT_TARGET="10.15"
echo "MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET}" >> $GITHUB_ENV
echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV
echo "PYTHON=${PYTHON_INSTALL_PATH}/bin/python3" >> $GITHUB_ENV
export date=gdate
export realpath=grealpath
echo "PIP_ARGS=--no-binary=:all:" >> $GITHUB_ENV
elif [[ "${RUNNER_OS}" == "Linux" ]]; then
MAKE=make
MAKEOPT="-j$(nproc)"
PERL=perl
echo "PYTHON=${PYTHON_INSTALL_PATH}/bin/python3" >> $GITHUB_ENV
export date=date
export realpath=realpath
elif [[ "${RUNNER_OS}" == "Windows" ]]; then
MAKE=nmake
MAKEOPT=""
PERL="c:\strawberry\perl\bin\perl.exe"
echo "PYTHON=${PYTHON_INSTALL_PATH}\python.exe" >> $GITHUB_ENV
export date=date
export realpath=realpath
echo "GAM_ARCHIVE_ARCH=${GAM_ARCHIVE_ARCH}" >> $GITHUB_ENV
echo "WIX_ARCH=${WIX_ARCH}" >> $GITHUB_ENV
fi
echo "date=${date}" >> $GITHUB_ENV
echo "realpath=${realpath}" >> $GITHUB_ENV
echo "We'll run make with: ${MAKEOPT}"
echo "JID=${jid}" >> $GITHUB_ENV
echo "arch=${arch}" >> $GITHUB_ENV
@@ -181,13 +191,15 @@ jobs:
echo "PERL=${PERL}" >> $GITHUB_ENV
echo "PYEXTERNALS_PATH=${PYEXTERNALS_PATH}" >> $GITHUB_ENV
echo "PYBUILDRELEASE_ARCH=${PYBUILDRELEASE_ARCH}" >> $GITHUB_ENV
echo "OPENSSL_CONFIG_TARGET=${OPENSSL_CONFIG_TARGET}" >> $GITHUB_ENV
echo "openssl_archs=${openssl_archs}" >> $GITHUB_ENV
echo "LD_LIBRARY_PATH=${OPENSSL_INSTALL_PATH}/lib:${PYTHON_INSTALL_PATH}/lib" >> $GITHUB_ENV
#echo "PATH=${PATH}:${PYTHON_INSTALL_PATH}/scripts" >> $GITHUB_ENV
- name: Get latest stable OpenSSL source
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
mkdir -vp "${GITHUB_WORKSPACE}/src"
cd "${GITHUB_WORKSPACE}/src"
git clone https://github.com/openssl/openssl.git
cd "${OPENSSL_SOURCE_PATH}"
export LATEST_STABLE_TAG=$(git tag --list openssl-* | grep -v alpha | grep -v beta | sort -Vr | head -n1)
@@ -195,6 +207,16 @@ jobs:
git checkout "${LATEST_STABLE_TAG}"
export COMPILED_OPENSSL_VERSION=${LATEST_STABLE_TAG:8} # Trim the openssl- prefix
echo "COMPILED_OPENSSL_VERSION=${COMPILED_OPENSSL_VERSION}" >> $GITHUB_ENV
if [[ "${RUNNER_OS}" == "macOS" ]]; then
for openssl_arch in $openssl_archs; do
ssldir="${OPENSSL_SOURCE_PATH}-${openssl_arch}"
mkdir -v "${ssldir}"
cp -vrf ${OPENSSL_SOURCE_PATH}/* "${ssldir}/"
done
rm -vrf "${OPENSSL_SOURCE_PATH}"
else
mv -v "${OPENSSL_SOURCE_PATH}" "${OPENSSL_SOURCE_PATH}-${openssl_archs}"
fi
- name: Windows NASM Install
uses: ilammy/setup-nasm@v1
@@ -203,9 +225,11 @@ jobs:
- name: Config OpenSSL
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
cd "${OPENSSL_SOURCE_PATH}"
# --libdir=lib is needed so Python can find OpenSSL libraries
"${PERL}" ./Configure "${OPENSSL_CONFIG_TARGET}" --libdir=lib --prefix="${OPENSSL_INSTALL_PATH}" $OPENSSL_CONFIG_OPTS
for openssl_arch in $openssl_archs; do
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
# --libdir=lib is needed so Python can find OpenSSL libraries
"${PERL}" ./Configure "${openssl_arch}" --libdir=lib --prefix="${OPENSSL_INSTALL_PATH}" $OPENSSL_CONFIG_OPTS
done
- name: Rename GNU link on Windows
if: matrix.goal == 'build' && matrix.os == 'windows-2022' && steps.cache-python-ssl.outputs.cache-hit != 'true'
@@ -215,24 +239,54 @@ jobs:
- name: Make OpenSSL
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
cd "${OPENSSL_SOURCE_PATH}"
$MAKE "${MAKEOPT}"
for openssl_arch in $openssl_archs; do
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
$MAKE "${MAKEOPT}"
done
- name: Install OpenSSL
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
cd "${OPENSSL_SOURCE_PATH}"
# install_sw saves us ages processing man pages :-)
$MAKE install_sw
if [[ "${RUNNER_OS}" == "macOS" ]]; then
for openssl_arch in $openssl_archs; do
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
# install_sw saves us ages processing man pages :-)
$MAKE install_sw
mv "${OPENSSL_INSTALL_PATH}" "${GITHUB_WORKSPACE}/bin/ssl-${openssl_arch}"
done
mkdir -vp "${OPENSSL_INSTALL_PATH}/lib"
mkdir -vp "${OPENSSL_INSTALL_PATH}/bin"
for archlib in libcrypto.3.dylib libssl.3.dylib libcrypto.a libssl.a; do
lipo -create "${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/lib/${archlib}" \
"${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64/lib/${archlib}" \
-output "${GITHUB_WORKSPACE}/bin/ssl/lib/${archlib}"
done
mv ${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/include ${GITHUB_WORKSPACE}/bin/ssl/
lipo -create "${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/bin/openssl" \
"${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64/bin/openssl" \
-output "${GITHUB_WORKSPACE}/bin/ssl/bin/openssl"
rm -rf ${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64
rm -rf ${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64
echo "LDFLAGS=-L${OPENSSL_INSTALL_PATH}/lib" >> $GITHUB_ENV
echo "CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1" >> $GITHUB_ENV
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include -arch arm64 -arch x86_64" >> $GITHUB_ENV
echo "ARCHFLAGS=-arch x86_64 -arch arm64" >> $GITHUB_ENV
else
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_archs}"
# install_sw saves us ages processing man pages :-)
$MAKE install_sw
fi
- name: Run OpenSSL
if: matrix.goal == 'build'
run: |
"${OPENSSL_INSTALL_PATH}/bin/openssl" version
file "${OPENSSL_INSTALL_PATH}/bin/openssl"
- name: Get latest stable Python source
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
cd "${GITHUB_WORKSPACE}/src"
git clone https://github.com/python/cpython.git
cd "${PYTHON_SOURCE_PATH}"
export LATEST_STABLE_TAG=$(git tag --list | grep -v a | grep -v rc | grep -v b | sort -Vr | head -n1)
@@ -244,12 +298,18 @@ jobs:
if: matrix.goal == 'build' && matrix.os != 'windows-2022' && steps.cache-python-ssl.outputs.cache-hit != 'true'
run: |
cd "${PYTHON_SOURCE_PATH}"
if [[ "${RUNNER_OS}" == "macOS" ]]; then
extra_args=( "--enable-universalsdk" "--with-universal-archs=universal2" )
else
extra_args=( )
fi
./configure --with-openssl="${OPENSSL_INSTALL_PATH}" \
--prefix="${PYTHON_INSTALL_PATH}" \
--enable-shared \
--with-ensurepip=upgrade \
--enable-optimizations \
--with-lto
--with-lto \
"${extra_args[@]}"
- name: Windows Get External Python deps
if: matrix.goal == 'build' && matrix.os == 'windows-2022' && steps.cache-python-ssl.outputs.cache-hit != 'true'
@@ -271,7 +331,7 @@ jobs:
$env:OPENSSL_EXT_TARGET_PATH = "${env:OPENSSL_EXT_PATH}${env:PYEXTERNALS_PATH}"
echo "Copying our OpenSSL to ${env:OPENSSL_EXT_TARGET_PATH}"
mkdir "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
Copy-Item -Path "${env:OPENSSL_SOURCE_PATH}\LICENSE.txt" -Destination "${env:OPENSSL_EXT_TARGET_PATH}\LICENSE"
Copy-Item -Path "${env:GITHUB_WORKSPACE}/src/openssl-${env:openssl_archs}\LICENSE.txt" -Destination "${env:OPENSSL_EXT_TARGET_PATH}\LICENSE"
cp -v "$env:OPENSSL_INSTALL_PATH\lib\*" "${env:OPENSSL_EXT_TARGET_PATH}"
cp -v "$env:OPENSSL_INSTALL_PATH\bin\*" "${env:OPENSSL_EXT_TARGET_PATH}"
cp -v "$env:OPENSSL_INSTALL_PATH\include\openssl\*" "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
@@ -348,13 +408,27 @@ jobs:
fi
echo "PyInstaller build arguments: ${PYINSTALLER_BUILD_ARGS}"
"${PYTHON}" ./waf all $PYINSTALLER_BUILD_ARGS
cd ..
"${PYTHON}" -m pip install .
cd ../..
echo "---- Installing PyInstaller ----"
"${PYTHON}" -m pip install pyinstaller
- name: Install pip requirements
run: |
set +e
"${PYTHON}" -m pip install --upgrade -r requirements.txt
if [[ "${RUNNER_OS}" == "macOS" ]]; then
for package in cryptography; do
"${PYTHON}" -m pip install --upgrade cffi ${PIP_ARGS}
"${PYTHON}" -m pip download --only-binary :all: \
--dest . \
--no-cache \
--no-deps \
--platform macosx_10_15_universal2 \
$package
"${PYTHON}" -m pip install --force-reinstall --no-deps $package*.whl
done
find $PYTHON_INSTALL_PATH/lib/python3.10/site-packages -type f -name "*.so" -exec du -sh "{}" \;
fi
"${PYTHON}" -m pip install --upgrade -r requirements.txt ${PIP_ARGS}
"${PYTHON}" -m pip list
- name: Build GAM with PyInstaller
@@ -362,12 +436,16 @@ jobs:
run: |
export gampath="./dist/gam"
mkdir -p -v "${gampath}"
export gampath="$($realpath $gampath)"
if [[ "${RUNNER_OS}" == "macOS" ]]; then
export gampath=$($PYTHON -c "import os; print(os.path.realpath('$gampath'))")
else
export gampath=$(realpath "${gampath}")
fi
export gam="${gampath}/gam"
echo "gampath=${gampath}" >> $GITHUB_ENV
echo "gam=${gam}" >> $GITHUB_ENV
echo -e "GAM: ${gam}\nGAMPATH: ${gampath}"
"${PYTHON}" -m PyInstaller --clean --noupx --strip --onefile --distpath="${gampath}" gam.spec
"${PYTHON}" -m PyInstaller --clean --distpath="${gampath}" gam.spec
- name: Basic Tests all jobs
run: |
@@ -383,7 +461,7 @@ jobs:
cp -v LICENSE $gampath
cp -v GamCommands.txt $gampath
if [[ "${RUNNER_OS}" == "macOS" ]]; then
GAM_ARCHIVE="gam-${GAMVERSION}-macos-x86_64.tar.xz"
GAM_ARCHIVE="gam-${GAMVERSION}-macos-universal2.tar.xz"
elif [[ "${RUNNER_OS}" == "Linux" ]]; then
this_glibc_ver=$(ldd --version | awk '/ldd/{print $NF}')
GAM_ARCHIVE="gam-${GAMVERSION}-linux-$(arch)-glibc${this_glibc_ver}.tar.xz"
@@ -452,6 +530,9 @@ jobs:
env:
PASSCODE: ${{ secrets.PASSCODE }}
run: |
if [[ "${RUNNER_OS}" == "macOS" ]]; then
brew install gnupg
fi
source ../.github/actions/decrypt.sh ../.github/actions/creds.tar.gpg creds.tar
export OAUTHFILE="oauth2.txt-gam-gha-${JID}"
echo "OAUTHFILE=${OAUTHFILE}" >> $GITHUB_ENV
@@ -462,8 +543,8 @@ jobs:
$gam oauth refresh
$gam info user
#$gam info user $gam_user grouptree
export tstamp=$($date +%s%3N)
export newbase=gha-test-$JID-$tstamp
export tstamp=$($PYTHON -c "import time; print(time.time_ns())")
export newbase=gha_test_$JID_$tstamp
export newuser=$newbase@pdl.jaylee.us
export newgroup=$newbase-group@pdl.jaylee.us
export newalias=$newbase-alias@pdl.jaylee.us
@@ -471,7 +552,7 @@ jobs:
export newresource=$newbase-resource
export GAM_THREADS=5
echo email > sample.csv;
for i in {01..10}; do
for i in {1..10}; do
echo "${newbase}-bulkuser-$i" >> sample.csv;
done
$gam create user $newuser firstname GHA lastname $JID password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB-
@@ -481,12 +562,12 @@ jobs:
$gam create group $newgroup name "GHA $JID group" description "This is a description" isarchived true
$gam user $gam_user sendemail recipient $newuser subject "test message $newbase" message "GHA test message"
$gam user $gam_user sendemail recipient exchange@pdl.jaylee.us subject "test ${tstamp}" message "test message"
$gam user $newuser add license workspaceenterpriseplus
$gam print privileges
$gam update cigroup $newgroup memberrestriction 'member.type == 1 || member.customer_id == groupCustomerId()'
$gam info cigroup $newgroup
$gam user $newuser add license workspaceenterpriseplus
$gam update group $newgroup add owner $gam_user
$gam update group $newgroup add member $newuser
$gam print privileges
$gam create admin $newuser _GROUPS_EDITOR_ROLE CUSTOMER condition nonsecuritygroup
$gam csv sample.csv gam create user ~~email~~ firstname "GHA Bulk" lastname ~~email~~ gha.jid $JID
$gam csv sample.csv gam update user ~~email~~ recoveryphone 12125121110 recoveryemail jay0lee@gmail.com password random
@@ -502,8 +583,8 @@ jobs:
$gam user $newuser imap on
$gam user $newuser show imap
$gam user $newuser show delegates
#$gam user $newuser add contactdelegate "${newbase}-bulkuser-01"
#$gam user $newuser print contactdelegates
$gam user $newuser add contactdelegate "${newbase}-bulkuser-1"
$gam user $newuser print contactdelegates
export biohazard=$(echo -e '\xe2\x98\xa3')
$gam user $newuser label "$biohazard unicode biohazard $biohazard"
$gam user $newuser show labels
@@ -513,10 +594,10 @@ jobs:
$gam user $gam_user sendemail subject "GHA send $gam_user $newbase" file gam.py recipient admin@pdl.jaylee.us
$gam user $gam_user draftemail subject "GHA draft $newbase" message "Draft message test"
$gam csvfile sample.csv:email waitformailbox
$gam user $newuser delegate to "${newbase}-bulkuser-01"
$gam users "$gam_user $newbase-bulkuser-01 $newbase-bulkuser-02 $newbase-bulkuser-03" delete messages query in:anywhere maxtodelete 99999 doit
$gam users "$newbase-bulkuser-04 $newbase-bulkuser-05 $newbase-bulkuser-06" trash messages query in:anywhere maxtotrash 99999 doit
$gam users "$newbase-bulkuser-07 $newbase-bulkuser-08 $newbase-bulkuser-09" modify messages query in:anywhere maxtomodify 99999 addlabel IMPORTANT addlabel STARRED doit
$gam user $newuser delegate to "${newbase}-bulkuser-1"
$gam users "$gam_user $newbase-bulkuser-1 $newbase-bulkuser-2 $newbase-bulkuser-3" delete messages query in:anywhere maxtodelete 99999 doit
$gam users "$newbase-bulkuser-4 $newbase-bulkuser-5 $newbase-bulkuser-6" trash messages query in:anywhere maxtotrash 99999 doit
$gam users "$newbase-bulkuser-7 $newbase-bulkuser-8 $newbase-bulkuser-9" modify messages query in:anywhere maxtomodify 99999 addlabel IMPORTANT addlabel STARRED doit
$gam user $newuser delete label --ALL_LABELS--
GAM_CSV_ROW_FILTER="name:regex:gha-test-${JID}" $gam print features | $gam csv - gam delete feature ~name
$gam create feature name Whiteboard-$newbase
@@ -531,7 +612,9 @@ jobs:
$gam calendar $gam_user add editor $newuser
$gam calendar $gam_user showacl
$gam calendar $gam_user printacl | $gam csv - gam calendar $gam_user delete id ~id
$gam calendar $gam_user addevent summary "GHA test event" start $($date '+%FT%T.%N%:z' -d "now + 1 hour") end $($date '+%FT%T.%N%:z' -d "now + 2 hours") attendee $newgroup hangoutsmeet guestscanmodify true sendupdates all
starttime=$($PYTHON -c "import datetime; print((datetime.datetime.now() + datetime.timedelta(hours=1)).strftime('%Y-%m-%dT%H:%M:%S.%f+00:00'))")
endtime=$($PYTHON -c "import datetime; print((datetime.datetime.now() + datetime.timedelta(hours=2)).strftime('%Y-%m-%dT%H:%M:%S.%f+00:00'))")
$gam calendar $gam_user addevent summary "GHA test event" start "${starttime}" end "${endtime}" attendee $newgroup hangoutsmeet guestscanmodify true sendupdates all
$gam calendar $gam_user printevents after -0d
matterid=uid:$($gam create vaultmatter name "GHA matter $newbase" description "test matter" collaborators $newuser | head -1 | cut -d ' ' -f 3)
$gam create vaulthold matter $matterid name "GHA hold $newbase" corpus mail accounts $newuser
@@ -564,7 +647,7 @@ jobs:
export sn="$JID$JID$JID$JID-$(openssl rand -base64 32 | sed 's/[^a-zA-Z0-9]//g')"
$gam create device serialnumber $sn devicetype android
$gam print cros allfields orderby serialnumber
#$gam show crostelemetry storagepercentonly
$gam show crostelemetry storagepercentonly
$gam report usageparameters customer
$gam report usage customer parameters gmail:num_emails_sent,accounts:num_1day_logins
$gam report customer todrive
@@ -573,25 +656,34 @@ jobs:
$gam print devices nopersonaldevices nodeviceusers filter "serial:$JID$JID$JID$JID-" | $gam csv - gam delete device id ~name
$gam print userinvitations
$gam print userinvitations | $gam csv - gam send userinvitation ~name
export CUSTOMER_ID="C01wfv983"
export GA_DOMAIN="pdl.jaylee.us"
touch $gampath/enabledasa.txt
$gam create caalevel "zzz_${newbase}" basic condition ipsubnetworks 1.1.1.1/32,2.2.2.2/32 endcondition
$gam print caalevels
$gam delete caalevel "zzz_${newbase}"
driveid=$($gam user $gam_user add shareddrive "${newbase}" | awk '{print $NF}')
echo "Created shared drive ${driveid}"
$gam user $gam_user update shareddrive "${driveid}" ou "id:03ph8a2z1t2ph5z"
$gam user $gam_user show shareddrives asadmin
$gam user $gam_user delete shareddrive "${driveid}"
echo "printer model count:"
$gam print printermodels | wc -l
#$gam print printers
#$gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by $(date)"
rm -f -v $gampath/enabledasa.txt
#$gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by $(gam_user)" ou /
#export CUSTOMER_ID="C01wfv983"
#export GA_DOMAIN="pdl.jaylee.us"
#touch $gampath/enabledasa.txt
#echo "using delegated admin service account"
#$gam print users
- name: Upload to Google Drive, build only.
if: github.event_name == 'push' && matrix.goal != 'test'
run: |
ls gam-$GAMVERSION-*
for gamfile in gam-$GAMVERSION-*; do
echo "Uploading file ${gamfile} to Google Drive..."
fileid=$($gam user $gam_user add drivefile localfile $gamfile drivefilename $GAMVERSION-${GITHUB_SHA:0:7}-$gamfile parentid 1N2zbO33qzUQFsGM49-m9AQC1ijzd_ru1 returnidonly)
echo "file uploaded as ${fileid}, setting ACL..."
$gam user $gam_user add drivefileacl $fileid anyone role reader withlink
done
# - name: Upload to Google Drive, build only.
# if: github.event_name == 'push' && matrix.goal != 'test'
# run: |
# ls gam-$GAMVERSION-*
# for gamfile in gam-$GAMVERSION-*; do
# echo "Uploading file ${gamfile} to Google Drive..."
# fileid=$($gam user $gam_user add drivefile localfile $gamfile drivefilename $GAMVERSION-${GITHUB_SHA:0:7}-$gamfile parentid 1N2zbO33qzUQFsGM49-m9AQC1ijzd_ru1 returnidonly)
# echo "file uploaded as ${fileid}, setting ACL..."
# $gam user $gam_user add drivefileacl $fileid anyone role reader withlink
# done
- name: Archive production artifacts
uses: actions/upload-artifact@v2

View File

@@ -243,6 +243,7 @@ If an item contains spaces, it should be surrounded by ".
<SMTPHostName> ::= <String>
<StudentItem> ::= <EmailAddress>|<UniqueID>|<String>
<TeamDriveID> ::= <String>
<TeamDriveName> ::= <String>
<Timezone> ::= <String>
<Title> ::= <String>
<URI> ::= <String>
@@ -632,6 +633,7 @@ Items, separated by spaces, with spaces, commas or single quotes in the items th
<SchemaNameList> ::= "<SchemaName>(,<SchemaName>)*"
<SerialNumberList> ::= "<SerialNumber>(,<SerialNumber>)*"
<ServiceAccountKeyList> ::= "<ServiceAccountKey>(,<ServiceAccountKey>)*"
<StringList> ::= "<String>(,<String>)*"
<TeamDriveIDList> ::= "<TeamDriveID>(,<TeamDriveID>)*"
<UserFieldNameList> ::= "<UserFieldName>(,<UserFieldName>)*"
<UserList> ::= "<UserItem>(,<UserItem>)*"
@@ -1210,6 +1212,76 @@ gam print browsertokens [todrive]
[fields <BrowserTokenFieldNameList>]
[sortheaders]
<CAAAllowedEncryptionStatus> ::=
encryption_unsupported |
encrypted |
unencrypted
<CAAAllowedEncryptionStatusList> ::= "<CAAAllowedEncryptionStatus>(,<CAAAllowedEncryptionStatus>)"
<CAAAllowedDeviceManagementLevel> ::=
basic |
advanced|complete |
none
<CAAAllowedDeviceManagementLevelList> ::= "<CAAAllowedDeviceManagementLevel>(,<CAAAllowedDeviceManagementLevel>)"
<CAACombiningFunction> ::=
and |
or
<CAAIPSubNetwork> ::=
<CIDRnetmask>
<CAAIPSubNetworkList> ::= "<CAAIPSubNetwork>(,<CAAIPSubNetwork>)"
<CAAMember> ::=
user:<EmailAddress> |
serviceAccount:<EmailAddress>
<CAAMemberList> ::= "<CAAMember>(,<CAAMember>)"
<CAAOsType> ::=
DESKTOP_MAC |
DESKTOP_WINDOWS |
DESKTOP_LINUX |
DESKTOP_CHROME_OS |
VERIFIED_DESKTOP_CHROME_OS |
ANDROID |
IOS
<CAAOsConstraint> ::=
<CAAOsType> |
<CAAOsType>:<String>.<String>.<String>
<CAAOsConstraintList> ::= "<CAAOsConstraint>(,<CAAOsConstraint>)"
<CAARegion> ::=
<Character><Character>
<CAARegionList> ::= "<CAARegion>(,<CAARegion>)"
See: https://www.iso.org/obp/ui/#search
<CAADevicePolicyAttribute> ::=
(requirescreenlock <Boolean>) |
(allowedencryptionstatuses <CAAAllowedEncryptionStatusList>) |
(osconstraints <CAAOsConstraintList>) |
(alloweddevicemanagementlevels <CAAAllowedDeviceManagementLevelList>) |
(requireadminapproval <Boolean>) |
(requirecorpowned <Boolean>)
<CAAConditionAttribute> ::=
(ipsubnetworks <CAAIPSubNetworkList>) |
(devicepolicy <CAADevicePolicyAttribute> enddevicepolicy) |
(requiredaccesslevels <StringList>) |
(negate <Boolean>) |
(members <CAARegionList>) |
(regions <CAAMemberList>)
<CAABasicAttribute> ::+
(combiningfunction <CAACombiningFunction>) |
(condition <CAAConditionAttribute>+ endcondition)
gam create caalevel <String> (basic <CAABasicAttribute>+)|(custom <String>)
gam update caalevel <CAALevelName> (basic <CAABasicAttribute>+)|(custom <String>)
gam delete caalevel <CAALevelName>
gam show caalevels
gam print caalevels [todrive]
gam print chatspaces [todrive]
gam print chatmembers space <ChatSpace> [todrive]
gam create chatmessage space <ChatSpace> [thread <String>]
@@ -1350,11 +1422,11 @@ gam print chromehistory channels [todrive]
gam print chromehistory versions [todrive]
[platform <ChromePlatformType>] [channel <ChromeChannelType>]
[filter <String>]
(orderby <ChromeVersionsOrderByFieldName> [ascending|descending])*
(orderby <ChromeVersionsOrderByFieldName> [ascending|descending])*
gam print chromehistory releases [todrive]
[platform <ChromePlatformType>] [channel <ChromeChannelType>] [version <String>]
[filter <String>]
(orderby <ChromeReleasessOrderByFieldName> [ascending|descending])*
(orderby <ChromeReleasessOrderByFieldName> [ascending|descending])*
gam delete chromepolicy <SchemaName>+ ou|org|orgunit <OrgUnitItem> [(printerid <PrinterID>)|(appid <AppID>)]
gam update chromepolicy (<SchemaName> (<Field> <Value>)+)+ ou|org|orgunit <OrgUnitItem> [(printerid <PrinterID>)|(appid <AppID>)]
@@ -1488,6 +1560,9 @@ gam update feature <Name> name <Name>
gam delete feature <Name>
gam print features [todrive]
gam show oushareddrives|orgunitshareddrives [ou|org|orgunit <OrgUnitItem>]
gam print oushareddrives|orgunitshareddrives [todrive] [ou|org|orgunit <OrgUnitItem>]
gam create resource <ResourceID> <Name> <ResourceAttribute>*
gam update resource <ResourceID> <ResourceAttribute>*
gam delete resource <ResourceID>
@@ -1760,12 +1835,12 @@ gam <UserTypeEntity> show signature|sig [format]
teammembersonly
gam <UserTypeEntity> create|add teamdrive <Name>
gam <UserTypeEntity> update teamdrive <TeamDriveID> [asadmin] [name <Name>]
gam <UserTypeEntity> update teamdrive <TeamDriveID>|(name <TeamDriveName>) [asadmin] [name <Name>]
[(theme|themeid <String>) | ([customtheme <DriveFileID> <Float> <Float> <Float>] [color <ColorValue>])]
(<TeamDriveRestrictionsSubfieldName> <Boolean>)*
[hidden <Boolean>]
gam <UserTypeEntity> delete teamdrive <TeamDriveID>
gam <UserTypeEntity> show teamdriveinfo <TeamDriveID> [asadmin]
gam <UserTypeEntity> delete teamdrive <TeamDriveID>|(name <TeamDriveName>)
gam <UserTypeEntity> show teamdriveinfo <TeamDriveID>|(name <TeamDriveName>) [asadmin]
gam <UserTypeEntity> show teamdrives [query <QueryTeamDrive>] [asadmin]
gam <UserTypeEntity> print teamdrives [query <QueryTeamDrive>] [todrive] [asadmin]
gam <UserTypeEntity> show teamdrivethemes

View File

@@ -128,7 +128,7 @@ case $gamos in
this_macos_ver=$osversion
fi
echo "You are running MacOS $this_macos_ver"
gamfile="macos-x86_64.tar.xz"
gamfile="macos-universal2.tar.xz"
;;
MINGW64_NT*)
gamos="windows"
@@ -223,7 +223,7 @@ trap "rm -rf $temp_archive_dir" EXIT
echo_yellow "Downloading file $name from $browser_download_url to $temp_archive_dir ($check_type)..."
# Save archive to temp w/o losing our path
(cd "$temp_archive_dir" && curl -O -L $GHCLIENT $browser_download_url)
(cd "$temp_archive_dir" && curl -# -O -L $GHCLIENT $browser_download_url)
mkdir -p "$target_dir"

View File

@@ -33,12 +33,14 @@ for d in a.datas:
pyz = PYZ(a.pure)
# TODO: fix universal2
target_arch = None
#if sys.platform == "darwin":
# target_arch="universal2"
#else:
# target_arch=None
if sys.platform == "darwin":
target_arch="universal2"
else:
target_arch=None
# use strip on all non-Windows platforms
strip = not sys.platform == 'win32'
exe = EXE(pyz,
a.scripts,
@@ -47,7 +49,7 @@ exe = EXE(pyz,
a.datas,
name='gam',
debug=False,
strip=None,
strip=strip,
upx=False,
target_arch=target_arch,
console=True)

View File

@@ -55,6 +55,7 @@ from gam import auth
from gam import controlflow
from gam import display
from gam import fileutils
from gam.gapi import caa as gapi_caa
from gam.gapi import calendar as gapi_calendar
from gam.gapi import cloudidentity as gapi_cloudidentity
from gam.gapi import cbcm as gapi_cbcm
@@ -64,6 +65,7 @@ from gam.gapi import chromemanagement as gapi_chromemanagement
from gam.gapi import chromepolicy as gapi_chromepolicy
from gam.gapi.cloudidentity import devices as gapi_cloudidentity_devices
from gam.gapi.cloudidentity import groups as gapi_cloudidentity_groups
from gam.gapi.cloudidentity import orgunits as gapi_cloudidentity_orgunits
from gam.gapi.cloudidentity import userinvitations as gapi_cloudidentity_userinvitations
from gam.gapi import contactdelegation as gapi_contactdelegation
from gam.gapi.directory import asps as gapi_directory_asps
@@ -80,6 +82,7 @@ from gam.gapi.directory import resource as gapi_directory_resource
from gam.gapi.directory import roles as gapi_directory_roles
from gam.gapi.directory import roleassignments as gapi_directory_roleassignments
from gam.gapi.directory import users as gapi_directory_users
from gam.gapi.drive import drives as gapi_drive_drives
from gam.gapi import licensing as gapi_licensing
from gam.gapi import siteverification as gapi_siteverification
from gam.gapi import errors as gapi_errors
@@ -848,7 +851,9 @@ def _getSvcAcctData():
controlflow.system_error_exit(6, None)
GM_Globals[GM_OAUTH2SERVICE_JSON_DATA] = json.loads(json_string)
jwt_apis = ['chat'] # APIs which can handle OAuthless JWT tokens
jwt_apis = ['chat',
'cloudresourcemanager',
'accesscontextmanager'] # APIs which can handle OAuthless JWT tokens
def getSvcAcctCredentials(scopes, act_as, api=None):
try:
_getSvcAcctData()
@@ -2730,7 +2735,7 @@ def printDriveSettings(users):
display.write_csv_file(csvRows, titles, 'User Drive Settings', todrive)
def getTeamDriveThemes(users):
def getSharedDriveThemes(users):
for user in users:
user, drive = buildDrive3GAPIObject(user)
if not drive:
@@ -7118,6 +7123,7 @@ def enableGAMProjectAPIs(GAMProjectAPIs,
f' Project: {projectId}, Enable {jcount} APIs{currentCount(i, count)}'
)
j = 0
tried_universal_tos = False
for api in apis:
service_name = f'projects/{projectId}/services/{api}'
j += 1
@@ -7128,19 +7134,26 @@ def enableGAMProjectAPIs(GAMProjectAPIs,
throw_reasons=[
gapi_errors.ErrorReason.FAILED_PRECONDITION,
gapi_errors.ErrorReason.FORBIDDEN,
gapi_errors.ErrorReason.PERMISSION_DENIED
gapi_errors.ErrorReason.PERMISSION_DENIED,
gapi_errors.ErrorReason.FOUR_O_O,
],
retry_reasons=[gapi_errors.ErrorReason.INTERNAL_SERVER_ERROR],
name=service_name)
print(f' API: {api}, Enabled{currentCount(j, jcount)}')
break
except gapi_errors.GapiFailedPreconditionError as e:
except (gapi_errors.GapiFailedPreconditionError,
googleapiclient.errors.HttpError) as e:
if hasattr(e, 'reason'):
msg = e.reason
else:
msg = str(e)
if 'terms of service' in msg.lower() and not tried_universal_tos:
msg = '''You need to agree to the Google Cloud Terms of Service at:\n\n https://console.developers.google.com'''
tried_universal_tos = True
print(
f'\nThere was an error enabling {api}. Please resolve error as described below:'
)
print()
print(f'\n{str(e)}\n')
print()
print(f'\n\n{msg}\n\n')
input(
'Press enter once resolved and we will try enabling the API again.'
)
@@ -8006,10 +8019,17 @@ def doPrintShowProjects(csvFormat):
display.write_csv_file(csvRows, titles, 'Projects', todrive)
def doGetTeamDriveInfo(users):
teamDriveId = sys.argv[5]
def getSharedDriveId(i):
driveId = sys.argv[i]
if driveId.lower() == 'name':
i += 1
driveId = gapi_drive_drives.drive_name_to_id(sys.argv[i])
return (i+1, driveId)
def doGetSharedDriveInfo(users):
i, driveId = getSharedDriveId(5)
useDomainAdminAccess = False
i = 6
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'asadmin':
@@ -8017,7 +8037,7 @@ def doGetTeamDriveInfo(users):
i += 1
else:
controlflow.invalid_argument_exit(myarg,
'gam <users> show teamdrive')
'gam <users> show shareddrive')
for user in users:
drive = buildGAPIServiceObject('drive3', user)
if not drive:
@@ -8025,13 +8045,15 @@ def doGetTeamDriveInfo(users):
continue
result = gapi.call(drive.drives(),
'get',
driveId=teamDriveId,
driveId=driveId,
useDomainAdminAccess=useDomainAdminAccess,
fields='*')
if useDomainAdminAccess and 'orgUnitId' in result:
result['orgUnit'] = gapi_directory_orgunits.orgunit_from_orgunitid(f'id:{result["orgUnitId"]}')
display.print_json(result)
def doCreateTeamDrive(users):
def doCreateSharedDrive(users):
body = {'name': sys.argv[5]}
i = 6
while i < len(sys.argv):
@@ -8041,7 +8063,7 @@ def doCreateTeamDrive(users):
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i],
'gam <users> create teamdrive')
'gam <users> create shareddrive')
for user in users:
drive = buildGAPIServiceObject('drive3', user)
if not drive:
@@ -8053,7 +8075,7 @@ def doCreateTeamDrive(users):
requestId=requestId,
body=body,
fields='id')
print(f'Created Team Drive {body["name"]} with id {result["id"]}')
print(f'Created Shared Drive {body["name"]} with id {result["id"]}')
TEAMDRIVE_RESTRICTIONS_MAP = {
@@ -8064,17 +8086,20 @@ TEAMDRIVE_RESTRICTIONS_MAP = {
}
def doUpdateTeamDrive(users):
teamDriveId = sys.argv[5]
def doUpdateSharedDrive(users):
i, driveId = getSharedDriveId(5)
body = {}
useDomainAdminAccess = False
change_hide = None
i = 6
orgUnit = None
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'name':
body['name'] = sys.argv[i + 1]
i += 2
elif myarg in ['ou', 'org', 'orgunit']:
orgUnit = sys.argv[i+1]
i += 2
elif myarg == 'theme':
body['themeId'] = sys.argv[i + 1]
i += 2
@@ -8092,9 +8117,9 @@ def doUpdateTeamDrive(users):
elif myarg == 'asadmin':
useDomainAdminAccess = True
i += 1
elif myarg in ['ou', 'org', 'orgunit']:
body['orgUnitId'] = gapi_directory_orgunits.getOrgUnitId(sys.argv[i + 1])
i += 2
# elif myarg in ['ou', 'org', 'orgunit']:
# body['orgUnitId'] = gapi_directory_orgunits.getOrgUnitId(sys.argv[i + 1])
# i += 2
elif myarg in ['hidden']:
if getBoolean(sys.argv[i+1], myarg):
change_hide = 'hide'
@@ -8109,8 +8134,8 @@ def doUpdateTeamDrive(users):
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i],
'gam <users> update teamdrive')
if not body and not change_hide:
'gam <users> update shareddrive')
if not body and not change_hide and not orgUnit:
controlflow.system_error_exit(
4, 'nothing to update. Need at least a name argument.')
for user in users:
@@ -8122,7 +8147,7 @@ def doUpdateTeamDrive(users):
'update',
useDomainAdminAccess=useDomainAdminAccess,
body=body,
driveId=teamDriveId,
driveId=driveId,
fields='id',
soft_errors=True)
if not result:
@@ -8130,15 +8155,19 @@ def doUpdateTeamDrive(users):
if change_hide:
ch_result = gapi.call(drive.drives(),
change_hide,
driveId=teamDriveId,
driveId=driveId,
fields='id',
soft_errors=True)
print(f'Updated Team Drive {teamDriveId}')
if orgUnit:
gapi_cloudidentity_orgunits.move_shared_drive(driveId,
orgUnit)
print(f'Updated Shared Drive {driveId}')
def printShowTeamDrives(users, csvFormat):
def printShowSharedDrives(users, csvFormat):
todrive = False
useDomainAdminAccess = False
q = None
get_orgunits = True
i = 5
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
@@ -8151,13 +8180,18 @@ def printShowTeamDrives(users, csvFormat):
elif myarg == 'query':
q = sys.argv[i + 1]
i += 2
elif myarg == 'noorgunits':
get_orgunits = False
i += 1
else:
controlflow.invalid_argument_exit(
myarg, f"gam {['show', 'print'][csvFormat]} teamdrives")
myarg, f"gam {['show', 'print'][csvFormat]} shareddrives")
tds = []
titles = []
if get_orgunits and useDomainAdminAccess:
ou_map = gapi_directory_orgunits.orgid_to_org_map()
for user in users:
sys.stderr.write(f'Getting Team Drives for {user}\n')
sys.stderr.write(f'Getting Shared Drives for {user}\n')
user, drive = buildDrive3GAPIObject(user)
if not drive:
continue
@@ -8172,12 +8206,16 @@ def printShowTeamDrives(users, csvFormat):
continue
for td in results:
td = utils.flatten_json(td)
if get_orgunits and useDomainAdminAccess:
td_ouid = td.get('orgUnitId')
if td_ouid:
td['orgUnit'] = ou_map.get(f'id:{td_ouid}', 'Unknown')
for key in td:
if key not in titles:
titles.append(key)
tds.append(td)
if csvFormat:
display.write_csv_file(tds, titles, 'Team Drives', todrive)
display.write_csv_file(tds, titles, 'Shared Drives', todrive)
else:
for td in tds:
name = td.pop('name')
@@ -8187,17 +8225,16 @@ def printShowTeamDrives(users, csvFormat):
print()
def doDeleteTeamDrive(users):
teamDriveId = sys.argv[5]
def doDeleteSharedDrive(users):
_, driveId = getSharedDriveId(5)
for user in users:
user, drive = buildDrive3GAPIObject(user)
if not drive:
continue
print(f'Deleting Team Drive {teamDriveId}')
print(f'Deleting Shared Drive {driveId}')
gapi.call(drive.drives(),
'delete',
driveId=teamDriveId,
driveId=driveId,
soft_errors=True)
@@ -10445,6 +10482,11 @@ OAUTH2_SCOPES = [
'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.groups'
},
{
'name': 'Cloud Identity - OrgUnits',
'subscopes': ['readonly'],
'scopes': 'https://www.googleapis.com/auth/cloud-identity.orgunits',
},
{
'name': 'Cloud Identity - User Invitations',
'subscopes': ['readonly'],
@@ -11366,6 +11408,8 @@ def ProcessGAMCommand(args):
gapi_directory_printers.create()
elif argument in ['chatmessage']:
gapi_chat.create_message()
elif argument in ['caalevel']:
gapi_caa.create_access_level()
else:
controlflow.invalid_argument_exit(argument, 'gam create')
sys.exit(0)
@@ -11430,6 +11474,8 @@ def ProcessGAMCommand(args):
gapi_directory_printers.update()
elif argument in ['chatmessage']:
gapi_chat.update_message()
elif argument in ['caalevel']:
gapi_caa.update_access_level()
else:
controlflow.invalid_argument_exit(argument, 'gam update')
sys.exit(0)
@@ -11570,6 +11616,8 @@ def ProcessGAMCommand(args):
gapi_chromepolicy.delete_policy()
elif argument == 'chatmessage':
gapi_chat.delete_message()
elif argument == 'caalevel':
gapi_caa.delete_access_level()
else:
controlflow.invalid_argument_exit(argument, 'gam delete')
sys.exit(0)
@@ -11691,6 +11739,10 @@ def ProcessGAMCommand(args):
gapi_chat.print_spaces()
elif argument in ['chatmembers']:
gapi_chat.print_members()
elif argument in ['caalevels']:
gapi_caa.printshow_access_levels(True)
elif argument in ['oushareddrives', 'orgunitshareddrives']:
gapi_cloudidentity_orgunits.printshow_orgunit_shared_drives(True)
else:
controlflow.invalid_argument_exit(argument, 'gam print')
sys.exit(0)
@@ -11721,6 +11773,10 @@ def ProcessGAMCommand(args):
gapi_chromepolicy.printshow_policies()
elif argument == 'crostelemetry':
gapi_chromemanagement.printShowCrosTelemetry('show')
elif argument in ['caalevels']:
gapi_caa.printshow_access_levels(False)
elif argument in ['oushareddrives', 'orgunitshareddrives']:
gapi_cloudidentity_orgunits.printshow_orgunit_shared_drives(False)
else:
controlflow.invalid_argument_exit(argument, 'gam show')
sys.exit(0)
@@ -11879,8 +11935,8 @@ def ProcessGAMCommand(args):
gapi_calendar.showCalSettings(users)
elif showWhat == 'drivesettings':
printDriveSettings(users)
elif showWhat == 'teamdrivethemes':
getTeamDriveThemes(users)
elif showWhat in ['teamdrivethemes', 'shareddrivethemes']:
getSharedDriveThemes(users)
elif showWhat == 'drivefileacl':
showDriveFileACL(users)
elif showWhat == 'filelist':
@@ -11923,10 +11979,10 @@ def ProcessGAMCommand(args):
printShowFilters(users, False)
elif showWhat in ['forwardingaddress', 'forwardingaddresses']:
printShowForwardingAddresses(users, False)
elif showWhat in ['teamdrive', 'teamdrives']:
printShowTeamDrives(users, False)
elif showWhat in ['teamdriveinfo']:
doGetTeamDriveInfo(users)
elif showWhat in shared_drive_values:
printShowSharedDrives(users, False)
elif showWhat in ['shareddriveinfo', 'teamdriveinfo']:
doGetSharedDriveInfo(users)
elif showWhat in ['contactdelegate', 'contactdelegates']:
gapi_contactdelegation.print_(users, False)
elif showWhat in ['holds', 'vaultholds']:
@@ -11957,8 +12013,8 @@ def ProcessGAMCommand(args):
printShowSmime(users, True)
elif printWhat in ['token', 'tokens', 'oauth', '3lo']:
printShowTokens(5, 'users', users, True)
elif printWhat in ['teamdrive', 'teamdrives']:
printShowTeamDrives(users, True)
elif printWhat in shared_drive_values:
printShowSharedDrives(users, True)
elif printWhat in ['contactdelegate', 'contactdelegates']:
gapi_contactdelegation.print_(users, True)
elif printWhat in ['labels']:
@@ -12041,8 +12097,8 @@ def ProcessGAMCommand(args):
deleteSendAs(users)
elif delWhat == 'smime':
deleteSmime(users)
elif delWhat == 'teamdrive':
doDeleteTeamDrive(users)
elif delWhat in shared_drive_values:
doDeleteSharedDrive(users)
elif delWhat == 'contactdelegate':
gapi_contactdelegation.delete(users)
else:
@@ -12075,8 +12131,8 @@ def ProcessGAMCommand(args):
addUpdateSendAs(users, 5, True)
elif addWhat == 'smime':
addSmime(users)
elif addWhat == 'teamdrive':
doCreateTeamDrive(users)
elif addWhat in shared_drive_values:
doCreateSharedDrive(users)
elif addWhat == 'contactdelegate':
gapi_contactdelegation.create(users)
else:
@@ -12117,8 +12173,8 @@ def ProcessGAMCommand(args):
addUpdateSendAs(users, 5, False)
elif updateWhat == 'smime':
updateSmime(users)
elif updateWhat == 'teamdrive':
doUpdateTeamDrive(users)
elif updateWhat in shared_drive_values:
doUpdateSharedDrive(users)
else:
controlflow.invalid_argument_exit(updateWhat,
'gam <users> update')

274
src/gam/gapi/caa.py Normal file
View File

@@ -0,0 +1,274 @@
import string
import sys
import googleapiclient.errors
import gam
from gam.var import *
from gam import controlflow
from gam import display
from gam import gapi
from gam import utils
from gam.gapi import errors as gapi_errors
from gam.gapi import cloudresourcemanager as gapi_crm
THROW_REASONS = [gapi_errors.ErrorReason.FOUR_O_THREE]
def _gen_role_error(caa):
sa_email = caa._http.credentials.signer_email
role_error = f'Please grant service account {sa_email} the Access Context Manager Editor role to your GCP organization.'
controlflow.system_error_exit(2, role_error)
def build():
return gam.buildGAPIServiceObject('accesscontextmanager',
act_as=None)
def get_access_policy(caa=None):
if not caa:
caa = build()
parent = gapi_crm.get_org_id()
if not parent:
_gen_role_error(caa)
try:
aps = gapi.get_all_pages(caa.accessPolicies(),
'list',
'accessPolicies',
throw_reasons=THROW_REASONS,
parent=parent,
fields='accessPolicies(name,title)')
except googleapiclient.errors.HttpError:
_gen_role_error(caa)
if not aps:
controlflow.system_error_exit(2, 'You don\'t seem to have any access policies. That is odd.')
elif len(aps) == 1:
return aps[0]['name']
for ap in aps:
if ap.get('title') == 'Access policy created in Cloud Identity Console':
return ap['name']
controlflow.system_error_exit(2, ' Could not find a org level access policy. That is odd.')
def printshow_access_levels(csvFormat):
caa = build()
ap_name = get_access_policy(caa)
if csvFormat:
todrive = False
csvRows = []
titles = ['name', 'title']
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower()
if csvFormat and myarg == 'todrive':
todrive = True
i += 1
else:
controlflow.invalid_argument_exit(sys.argv[i],
f"gam {['show', 'print'][csvFormat]} caalevels")
try:
levels = gapi.get_all_pages(caa.accessPolicies().accessLevels(),
'list',
'accessLevels',
throw_reasons=THROW_REASONS,
parent=ap_name,
accessLevelFormat='CEL', fields='*')
except googleapiclient.errors.HttpError:
_gen_role_error(caa)
if not csvFormat:
for level in levels:
display.print_json(level)
print()
else:
for level in levels:
display.add_row_titles_to_csv_file(
utils.flatten_json(level),
csvRows, titles)
display.write_csv_file(csvRows, titles, 'CAA Levels', todrive)
def build_os_constraints(constraints):
consts_obj = []
constraints = constraints.upper().split(',')
valid_os_types = ['DESKTOP_MAC', 'DESKTOP_WINDOWS', 'DESKTOP_LINUX',
'DESKTOP_CHROME_OS', 'VERIFIED_DESKTOP_CHROME_OS', 'ANDROID', 'IOS']
for constraint in constraints:
new_const = {}
if ':' in constraint:
new_const['osType'], new_const['minimumVersion'] = constraint.split(':')
else:
new_const['osType'] = constraint
if new_const['osType'] not in valid_os_types:
controlflow.system_error_exit(2, f'expected os type of {", ".join(valid_os_types)} got {new_const["osType"]}')
if new_const['osType'] == 'VERIFIED_DESKTOP_CHROME_OS':
new_const['osType'] = 'DESKTOP_CHROME_OS'
new_const['requireVerifiedChromeOs'] = True
consts_obj.append(new_const)
return consts_obj
def build_device_policy(i, schemas):
device_policy = {}
while True:
myarg = sys.argv[i].replace('_', '').lower()
if myarg == 'requirescreenlock':
device_policy['requireScreenLock'] = gam.getBoolean(sys.argv[i+1], myarg)
i += 2
elif myarg == 'allowedencryptionstatuses':
allowed_statuses = gapi.get_enum_values_minus_unspecified(schemas["DevicePolicy"]["properties"]["allowedEncryptionStatuses"]["items"]["enum"])
device_policy['allowedEncryptionStatuses'] = sys.argv[i+1].upper().split(',')
for status in device_policy['allowedEncryptionStatuses']:
if status not in allowed_statuses:
controlflow.system_error_exit(2, f'expected encryption status of {", ".join(allowed_statuses)} got {status}')
i += 2
elif myarg == 'osconstraints':
device_policy['osConstraints'] = build_os_constraints(sys.argv[i+1])
i += 2
elif myarg == 'alloweddevicemanagementlevels':
allowed_levels = gapi.get_enum_values_minus_unspecified(schemas["DevicePolicy"]["properties"]["allowedDeviceManagementLevels"]["items"]["enum"])
device_policy['allowedDeviceManagementLevels'] = sys.argv[i+1].upper().split(',')
for level in device_policy['allowedDeviceManagementLevels']:
if level == 'ADVANCED':
level = 'COMPLETE'
if level not in allowed_levels:
controlflow.system_error_exit(2, f'expected device management level of {", ".join(allowed_levels)} got {level}')
i += 2
elif myarg == 'requireadminapproval':
device_policy['requireAdminApproval'] = gam.getBoolean(sys.argv[i+1], myarg)
i += 2
elif myarg == 'requirecorpowned':
device_policy['requireCorpOwned'] = gam.getBoolean(sys.argv[i+1], myarg)
i += 2
elif myarg == 'enddevicepolicy':
i += 1
break
else:
controlflow.invalid_argument_exit(myarg, 'gam create/update caalevel')
return i, device_policy
def build_condition(i, schemas):
condition = {}
while True:
myarg = sys.argv[i].replace('_', '').lower()
if myarg == 'ipsubnetworks':
condition['ipSubnetworks'] = sys.argv[i+1].split(',')
i += 2
elif myarg == 'devicepolicy':
i += 1
i, condition['devicePolicy'] = build_device_policy(i, schemas)
elif myarg == 'requiredaccesslevels':
condition['requiredAccessLevels'] = sys.argv[i+1].split(',')
i += 2
elif myarg == 'negate':
condition['negate'] = gam.getBoolean(sys.argv[i+1], myarg)
i += 2
elif myarg == 'members':
condition['members'] = sys.argv[i+1].split(',')
i += 2
elif myarg == 'regions':
condition['regions'] = sys.argv[i+1].upper().split(',')
i += 2
elif myarg == 'endcondition':
i += 1
break
else:
controlflow.invalid_argument_exit(myarg, 'gam create/update caalevel')
return i, condition
def build_basic_level(i, schemas):
basic_level = {'conditions': []}
valid_functions = gapi.get_enum_values_minus_unspecified(schemas['BasicLevel']['properties']['combiningFunction']['enum'])
while i < len(sys.argv):
myarg = sys.argv[i].replace('_', '').lower()
if myarg == 'combiningfunction':
combiningFunction = sys.argv[i+1].upper()
if combiningFunction not in valid_functions:
controlflow.system_error_exit(2, f'expected combining function of {",".join(valid_functions)} got {combiningFunction}')
basic_level['combiningFunction'] = combiningFunction
i += 2
elif myarg == 'condition':
i += 1
i, condition = build_condition(i, schemas)
basic_level['conditions'].append(condition)
else:
controlflow.invalid_argument_exit(myarg, 'gam create/update caalevel')
return i, basic_level
def build_caa_level(i, caa, body):
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'basic':
schemas = caa._rootDesc['schemas']
i += 1
i, body['basic'] = build_basic_level(i, schemas)
elif myarg == 'custom':
body['custom'] = {'expr': {'expression': sys.argv[i+1], 'title': 'expr'}}
i += 2
elif myarg == 'description':
body['description'] = sys.argv[i+1]
i += 2
else:
controlflow.invalid_argument_exit(myarg, 'gam create/update caalevel')
def create_access_level():
caa = build()
ap_name = get_access_policy(caa)
title = sys.argv[3].replace(' ', '_')
allowed_title_chars = string.ascii_letters + string.digits + '_'
name = ''.join([c for c in title if c in allowed_title_chars])[:50]
name = f'{ap_name}/accessLevels/{name}'
body = {
'name': name,
'title': title,
}
build_caa_level(4, caa, body)
print(f'Creating access level {name}...')
try:
gapi.call(caa.accessPolicies().accessLevels(),
'create',
throw_reasons=THROW_REASONS,
parent=ap_name,
body=body)
except googleapiclient.errors.HttpError:
_gen_role_error(caa)
def get_access_level_name(i, caa):
name = sys.argv[i]
if not name.startswith('accessPolicies/'):
ap_name = get_access_policy(caa)
name = f'{ap_name}/accessLevels/{name}'
return name
def update_access_level():
caa = build()
name = get_access_level_name(3, caa)
body = {}
build_caa_level(4, caa, body)
updateMask = ','.join(body.keys())
print(f'Updating access level {name}...')
try:
gapi.call(caa.accessPolicies().accessLevels(),
'patch',
throw_reasons=THROW_REASONS,
name=name,
updateMask=updateMask,
body=body)
except googleapiclient.errors.HttpError:
_gen_role_error(caa)
def delete_access_level():
caa = build()
name = get_access_level_name(3, caa)
print(f'Deleting access level {name}...')
try:
gapi.call(caa.accessPolicies().accessLevels(),
'delete',
name=name)
except googleapiclient.errors.HttpError:
_gen_role_error(caa)

View File

@@ -0,0 +1,72 @@
import sys
import googleapiclient
import gam
from gam.var import * # pylint: disable=unused-wildcard-import
from gam import controlflow
from gam import display
from gam import gapi
from gam import utils
from gam.gapi import errors as gapi_errors
from gam.gapi import cloudidentity as gapi_cloudidentity
from gam.gapi.directory import orgunits as gapi_directory_orgunits
def _get_orgunit_customerid():
customer = GC_Values[GC_CUSTOMER_ID]
if customer != MY_CUSTOMER and not customer.startswith('C'):
customer = f'C{customer}'
return f'customers/{customer}'
def move_shared_drive(driveId, orgUnit):
_, orgUnitId = gapi_directory_orgunits.getOrgUnitId(orgUnit)
orgUnitId = f'orgUnits/{orgUnitId[3:]}'
name = f'orgUnits/-/memberships/shared_drive;{driveId}'
ci = gapi_cloudidentity.build('cloudidentity_beta')
body = {
'customer': _get_orgunit_customerid(),
'destinationOrgUnit': orgUnitId,
}
return gapi.call(ci.orgUnits().memberships(),
'move',
name=name,
body=body)
def printshow_orgunit_shared_drives(csvFormat):
orgunit = '/'
if csvFormat:
todrive = False
csvRows = []
titles = ['name']
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower()
if csvFormat and myarg == 'todrive':
todrive = True
i += 1
elif myarg in ['ou', 'org', 'orgunit']:
orgunit = sys.argv[i + 1]
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i],
f"gam {['show', 'print'][csvFormat]} oushareddrives")
ci = gapi_cloudidentity.build('cloudidentity_beta')
_, orgUnitId = gapi_directory_orgunits.getOrgUnitId(orgunit)
parent = f'orgUnits/{orgUnitId[3:]}'
filter_ = "type == 'shared_drive'"
sds = gapi.get_all_pages(ci.orgUnits().memberships(),
'list',
'orgMemberships',
parent=parent,
customer=_get_orgunit_customerid(),
filter=filter_)
if not csvFormat:
for sd in sds:
display.print_json(sd)
print()
else:
for sd in sds:
display.add_row_titles_to_csv_file(
utils.flatten_json(sd),
csvRows, titles)
display.write_csv_file(csvRows, titles, f'OrgUnit {orgunit} Shared Drives', todrive)

View File

@@ -0,0 +1,24 @@
import gam
from gam.var import GC_Values, GC_CUSTOMER_ID
from gam import controlflow
from gam import gapi
from gam.gapi.directory import customer as gapi_directory_customer
def build():
return gam.buildGAPIServiceObject('cloudresourcemanager',
act_as=None)
def get_org_id():
gapi_directory_customer.setTrueCustomerId()
crm = build()
query = f'directorycustomerid:{GC_Values[GC_CUSTOMER_ID]}'
orgs = gapi.get_all_pages(crm.organizations(),
'search',
'organizations',
query=query)
if len(orgs) < 1:
# return nothing and let calling API deal with it
# since caller knows what GCP role would serve best
return
return orgs[0]['name']

View File

@@ -160,42 +160,15 @@ def info(name=None, return_attrib=None):
print('')
def print_():
print_order = [
'orgUnitPath', 'orgUnitId', 'name', 'description', 'parentOrgUnitPath',
'parentOrgUnitId', 'blockInheritance'
]
cd = gapi_directory.build()
listType = 'all'
orgUnitPath = '/'
todrive = False
fields = ['orgUnitPath', 'name', 'orgUnitId', 'parentOrgUnitId']
titles = []
csvRows = []
parentOrgIds = []
def list_orgunits(listType='all', orgUnitPath=None, fields=None):
retrievedOrgIds = []
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'todrive':
todrive = True
i += 1
elif myarg == 'toplevelonly':
listType = 'children'
i += 1
elif myarg == 'fromparent':
orgUnitPath = getOrgUnitItem(sys.argv[i + 1])
i += 2
elif myarg == 'allfields':
fields = None
i += 1
elif myarg == 'fields':
fields += sys.argv[i + 1].split(',')
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i], 'gam print orgs')
gam.printGettingAllItems('Organizational Units', None)
parentOrgIds = []
cd = gapi_directory.build()
if fields:
# Always get parentOrgUnitId so we can
# find missing parents
if 'parentOrgUnitId' not in fields:
fields.append('parentOrgUnitId')
get_fields = ','.join(fields)
list_fields = f'organizationUnits({get_fields})'
else:
@@ -230,6 +203,44 @@ def print_():
orgunits.append(result)
except:
pass
return orgunits
def print_():
print_order = [
'orgUnitPath', 'orgUnitId', 'name', 'description', 'parentOrgUnitPath',
'parentOrgUnitId', 'blockInheritance'
]
listType = 'all'
orgUnitPath = '/'
todrive = False
fields = ['orgUnitPath', 'name', 'orgUnitId', 'parentOrgUnitId']
titles = []
csvRows = []
i = 3
while i < len(sys.argv):
myarg = sys.argv[i].lower().replace('_', '')
if myarg == 'todrive':
todrive = True
i += 1
elif myarg == 'toplevelonly':
listType = 'children'
i += 1
elif myarg == 'fromparent':
orgUnitPath = getOrgUnitItem(sys.argv[i + 1])
i += 2
elif myarg == 'allfields':
fields = None
i += 1
elif myarg == 'fields':
fields += sys.argv[i + 1].split(',')
i += 2
else:
controlflow.invalid_argument_exit(sys.argv[i], 'gam print orgs')
gam.printGettingAllItems('Organizational Units', None)
orgunits = list_orgunits(listType=listType,
orgUnitPath=orgUnitPath,
fields=fields)
for row in orgunits:
orgEntity = {}
for key, value in list(row.items()):
@@ -248,6 +259,11 @@ def print_():
display.write_csv_file(csvRows, titles, 'Orgs', todrive)
def orgid_to_org_map():
orgunits = list_orgunits(fields=['orgUnitPath', 'orgUnitId'])
result = {ou['orgUnitId']:ou['orgUnitPath'] for ou in orgunits}
return result
def update():
cd = gapi_directory.build()
orgUnitPath = getOrgUnitItem(sys.argv[3])

View File

@@ -0,0 +1,8 @@
import gam
def build(user=None):
if not user:
user = gam._get_admin_email()
userEmail = gam.convertUIDtoEmailAddress(user)
return (userEmail, gam.buildGAPIServiceObject('drive3', userEmail))

View File

@@ -0,0 +1,26 @@
"""Methods related to Drive API Shared Drives"""
import sys
import gam
from gam.var import GC_CUSTOMER_ID, GC_Values, MY_CUSTOMER, SORTORDER_CHOICES_MAP
from gam import controlflow
from gam import display
from gam import gapi
from gam.gapi import errors as gapi_errors
from gam.gapi import drive as gapi_drive
def drive_name_to_id(name, drive=None):
if not drive:
_, drive = gapi_drive.build()
q = f"name = '{name}'"
sds = gapi.get_all_pages(drive.drives(),
'list',
'drives',
q=q,
useDomainAdminAccess=True)
if len(sds) == 0:
controlflow.system_error_exit(3, f'Could not find shared drive named "{name}"')
elif len(sds) > 1:
controlflow.system_error_exit(3, f'Got more than one shared drive named "{name}"')
return sds[0]['id']

View File

@@ -120,6 +120,7 @@ class ErrorReason(Enum):
FAILED_PRECONDITION = 'failedPrecondition'
FORBIDDEN = 'forbidden'
FIVE_O_THREE = '503'
FIVE_O_O = '500'
FOUR_O_NINE = '409'
FOUR_O_O = '400'
FOUR_O_FOUR = '404'
@@ -159,6 +160,7 @@ DEFAULT_RETRY_REASONS = [
ErrorReason.GATEWAY_TIMEOUT,
ErrorReason.INTERNAL_ERROR,
ErrorReason.FOUR_TWO_NINE,
ErrorReason.FIVE_O_O,
ErrorReason.FIVE_O_THREE,
]
GMAIL_THROW_REASONS = [ErrorReason.SERVICE_NOT_AVAILABLE]

View File

@@ -56,7 +56,7 @@ def create(users, sku=None):
productId = sys.argv[i+1]
i += 2
for user in users:
print(f'Adding license {sku_name} from to {user}')
print(f'Adding license {sku_name} to {user}')
gapi.call(lic.licenseAssignments(),
'insert',
soft_errors=True,

View File

@@ -348,7 +348,7 @@ def print_count():
# so we keep track of which accounts we searched and can report
# zero data for them.
if search_method == 'ACCOUNT':
query_accounts = query.get('accountInfo', [])
query_accounts = query.get('accountInfo', {}).get('emails', [])
elif search_method == 'ENTIRE_ORG':
query_accounts = gam.getUsersToModify('all', 'users')
elif search_method == 'ORG_UNIT':
@@ -367,8 +367,9 @@ def print_count():
if account in query_accounts: query_accounts.remove(account)
for account in a_count.get('accountCounts', []):
email = account.get('account', {}).get('email', '')
csv_rows.append({'account': email, 'count': account.get('count')})
if email in query_accounts: query_accounts.remove(email)
if email:
csv_rows.append({'account': email, 'count': account.get('count', 0)})
if email in query_accounts: query_accounts.remove(email)
for account in query_accounts:
csv_rows.append({'account': account, 'count': 0})
titles = ['account', 'count', 'error']

View File

@@ -8,7 +8,7 @@ import platform
import re
GAM_AUTHOR = 'Jay Lee <jay0lee@gmail.com>'
GAM_VERSION = '6.16'
GAM_VERSION = '6.20'
GAM_LICENSE = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
GAM_URL = 'https://git.io/gam'
@@ -42,7 +42,7 @@ FN_EXTRA_ARGS_TXT = 'extra-args.txt'
FN_LAST_UPDATE_CHECK_TXT = 'lastupdatecheck.txt'
MY_CUSTOMER = 'my_customer'
# See https://support.google.com/drive/answer/37603
MAX_GOOGLE_SHEET_CELLS = 5000000
MAX_GOOGLE_SHEET_CELLS = 10000000
MAX_LOCAL_GOOGLE_TIME_OFFSET = 30
SKUS = {
@@ -193,6 +193,11 @@ SKUS = {
'wsentplus', 'workspaceenterpriseplus'],
'displayName': 'Workspace Enterprise Plus'
},
'1010020029': {
'product': 'Google-Apps',
'aliases': ['wes', 'workspaceenterprisestarter'],
'displayName': 'Workspace Enterprise Starter'
},
'1010020030': {
'product': 'Google-Apps',
'aliases': ['workspacefrontline', 'workspacefrontlineworker'],
@@ -301,6 +306,7 @@ API_NAME_MAPPING = {
}
API_VER_MAPPING = {
'accesscontextmanager': 'v1',
'alertcenter': 'v1beta1',
'driveactivity': 'v2',
'calendar': 'v3',
@@ -1524,6 +1530,9 @@ MESSAGE_UPDATE_GAM_TO_64BIT = 'You\'re running a 32-bit version of GAM on a' \
MESSAGE_YOUR_SYSTEM_TIME_DIFFERS_FROM_GOOGLE_BY = 'Your system time differs' \
' from %s by %s'
shared_drive_values = ['teamdrive', 'teamdrives',
'shareddrive', 'shareddrives']
USER_ADDRESS_TYPES = ['home', 'work', 'other']
USER_EMAIL_TYPES = ['home', 'work', 'other']
USER_EXTERNALID_TYPES = [

View File

@@ -1,3 +1,4 @@
accesscontextmanager.googleapis.com
admin.googleapis.com
alertcenter.googleapis.com
calendar-json.googleapis.com
@@ -6,6 +7,7 @@ chromemanagement.googleapis.com
chromepolicy.googleapis.com
classroom.googleapis.com
cloudidentity.googleapis.com
cloudresourcemanager.googleapis.com
contacts.googleapis.com
drive.googleapis.com
driveactivity.googleapis.com

View File

@@ -1,6 +1,6 @@
[metadata]
name = GAM for Google Workspace
version = 6.0.14
version = 6.0.20
description = Command line management for Google Workspaces
long_description = file: readme.md
long_description_content_type = text/markdown