Update gsutil.py to use luci-auth for authentication

The change updates gsutil.py to internally use luci-auth for
authentication. It redirects `gsutil.py config` to `luci-auth login` and
wraps gsutil.py calls using `luci-auth context`.

The change is mainly done to ensure users have a way to authenticate once OOB authentication flow is deprecated. This patch falls back to using the .boto file when that is provided.

Design Document: go/gsutil-oauth-issue-resolved

Bug: 959170, 1359383
Change-Id: Icc6df1d8b93424ac0f6e2df84afdebc869763ede
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4109192
Commit-Queue: Aravind Vasudevan <aravindvasudev@google.com>
Reviewed-by: Joanna Wang <jojwang@chromium.org>
Reviewed-by: Vadim Shtayura <vadimsh@chromium.org>
changes/92/4109192/12
Aravind Vasudevan 3 years ago committed by LUCI CQ
parent dcb79c7080
commit 7af6169852

@ -5,6 +5,7 @@
"""Run a pinned gsutil."""
from __future__ import print_function
import argparse
import base64
@ -36,6 +37,15 @@ IS_WINDOWS = os.name == 'nt'
VERSION = '4.68'
# Environment variable to enable LUCI auth feature.
GSUTIL_ENABLE_LUCI_AUTH = 'GSUTIL_ENABLE_LUCI_AUTH'
# Google OAuth Context required by gsutil.
LUCI_AUTH_SCOPES = [
'https://www.googleapis.com/auth/devstorage.full_control',
'https://www.googleapis.com/auth/userinfo.email',
]
class InvalidGsutilError(Exception):
pass
@ -138,7 +148,54 @@ def ensure_gsutil(version, target, clean):
return gsutil_bin
def _is_luci_context():
"""Returns True if the script is run within luci-context"""
luci_context_env = os.getenv('LUCI_CONTEXT')
if not luci_context_env:
return False
try:
with open(luci_context_env) as f:
luci_context_json = json.load(f)
return 'local_auth' in luci_context_json
except (ValueError, FileNotFoundError):
return False
def luci_context(cmd):
"""Helper to call`luci-auth context`."""
return _luci_auth_cmd('context', wrapped_cmds=cmd)
def luci_login():
"""Helper to run `luci-auth login`."""
_luci_auth_cmd('login')
def _luci_auth_cmd(luci_cmd, wrapped_cmds=None):
"""Helper to call luci-auth command."""
print('WARNING: OOB authentication flow has been deprecated.')
print('Using luci-auth login instead.')
print('Override luci-auth by setting `BOTO_CONFIG` or '
'`AWS_CREDENTIAL_FILE` in your env.\n')
cmd = ['luci-auth', luci_cmd, '-scopes', ' '.join(LUCI_AUTH_SCOPES)]
if wrapped_cmds:
cmd += ['--'] + wrapped_cmds
return _run_subprocess(cmd)
def _run_subprocess(cmd):
"""Wrapper to run the given command within a subprocess."""
return subprocess.call(cmd, shell=IS_WINDOWS)
def run_gsutil(target, args, clean=False):
# Redirect gsutil config calls to luci-auth.
if os.getenv(GSUTIL_ENABLE_LUCI_AUTH) == '1' and 'config' in args:
return luci_login()
gsutil_bin = ensure_gsutil(VERSION, target, clean)
args_opt = ['-o', 'GSUtil:software_update_check_period=0']
@ -167,7 +224,14 @@ def run_gsutil(target, args, clean=False):
'--',
gsutil_bin
] + args_opt + args
return subprocess.call(cmd, shell=IS_WINDOWS)
# Bypass luci-auth when run within a bot or .boto file is set.
if (os.getenv(GSUTIL_ENABLE_LUCI_AUTH) != '1' or _is_luci_context()
or os.getenv('SWARMING_HEADLESS') == '1' or os.getenv('BOTO_CONFIG')
or os.getenv('AWS_CREDENTIAL_FILE')):
return _run_subprocess(cmd)
return luci_context(cmd)
def parse_args():

Loading…
Cancel
Save