How do I programmatically download a file from a private Google Cloud Source Repository with a service account?

620 views Asked by At

I have a Google Cloud Source Repository I want my application to download files from. I have a specific use case where I want to get files from a Google Cloud Source Repository programmatically- not GCS or another location.

I want to control permissions to the repo with standard Google IAM. Can I grant a GCP service account access to read from a Cloud Source Repository?

In bitbucket you can download a file directly from a private repo with a rest call like this: curl -s -S --user username:apppassword -L -O https://bitbucket.org/<ORG_NAME>/<REPO>/src/master/<FOLDER>/file.txt

How can I use a GSA to download a file like this from a private Google Cloud Source Repository?

I am doing this in code so I do not have access to ssh or curl or the gcloud cli. I'll be using python to fetch this file.

I was also looking if the SDK supports this. I did not see anything in the docs for a python API for interacting with Google Cloud Source Repositories this way. I'm wondering how I can pull down this file with the requests library or even something like GitPython while authenticating with the GSA.

EDIT

Per the comments I tried creating a token in python and gcloud, but it does not work. The token is generated fine, but file download doesn't work.

I tried this (and via python):

curl -s -S -H "Authorization: Bearer $(gcloud auth print-access-token)" -L -O https://source.cloud.google.com/MY_GCP_PROJECT/MY_REPO/master/README.md

This downloads a huge html page that seems to be showing auth errors.

Maybe the http path is wrong? What is the correct path to the file in the source repo via http GET?

I confirmed I have permissions because this works gcloud source repos clone MY_REPO --project=MY_PROJECT

EDIT

This is where I am right now, I can't figure out what the right URL is to point to a specific branch and file:

import google.auth
import google.auth.transport.requests
import requests

# Generate a token from current security context
creds, project = google.auth.default()
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

# Set token in Authorization header of http request
headers = {'Authorization':'Bearer {}'.format(creds.token)}

# Repo URL with branch and file specified (trying to download README.md in the root of the repo)
# What is the right URL here?
url = "https://source.developers.google.com/p/<GCP PROJECT>/r/<REPO NAME>/<BRANCH NAME>/README.md"

response = requests.get(url, headers=headers)

# I get a big mess of html with auth errors
print(response.content)

If I use this URL "https://source.developers.google.com/<GCP PROJECT>/<REPO NAME>/<BRANCH NAME>/README.md" I get back a page that includes PERMISSION_DENIED: The caller does not have permission

0

There are 0 answers