Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/clusterfuzz/_internal/base/modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,50 @@ def _patch_appengine_modules_for_bots():
pass


def _patch_google_auth_for_bots() -> None:
"""Patch google.auth.default to use explicit credentials via GCE metadata.

This is required for Swarming bots to authenticate with GCP services
since they do not always have application default credentials configured
in their environment.
"""
if not os.getenv('SWARMING_BOT'):
# Only applicable when explicitly deployed as a Swarming task worker.
return

try:
import google.auth
from google.auth import compute_engine
import requests

def patched_default_credentials(
*args, **kwargs) -> tuple[compute_engine.Credentials, str] | None:
# pylint: disable=unused-argument
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: We have the args and kwargs in the method signature because otherwise if we call the default() method with any args an exception would be thrown because the patch didn't matched the expected signature.

Copy link
Copy Markdown
Collaborator

@jardondiego jardondiego Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the function signature to this should fix it without having this pylint directive.

def patched_default_credentials(*_args, **_kwargs) -> tuple[compute_engine.Credentials, str] | None:

url = f"http://{os.environ['GCE_METADATA_HOST']}/computeMetadata/v1/" \
"project/project-id"
project_id = os.environ.get('GOOGLE_CLOUD_PROJECT') or os.environ.get(
'APPLICATION_ID')
if not project_id and os.environ.get('GCE_METADATA_HOST'):
try:
project_id = requests.get(
url, headers={
"Metadata-Flavor": "Google"
}, timeout=2).text.strip()
except Exception:
pass

if not project_id:
print('''[Swarming] [Error] Failed to patch google.auth.default.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be logged into swarming only, not GCP, since when this executes we still haven't setup GCP logging

Reason: failed to get project ID''')
return None

return compute_engine.Credentials(), project_id

google.auth.default = patched_default_credentials
except ImportError as e:
print(f'[Swarming] [Error] Failed to patch google.auth.default. {e.msg}')


def fix_module_search_paths():
"""Add directories that we must be able to import from to path."""
root_directory = os.environ['ROOT_DIR']
Expand Down Expand Up @@ -75,3 +119,4 @@ def fix_module_search_paths():

# TODO(ochang): Remove this once SDK is removed from images.
_patch_appengine_modules_for_bots()
_patch_google_auth_for_bots()
Loading