Skip to content

Conversation

@PauloVLB
Copy link
Member

This PR introduces casp.utils.gcloud module, designed to handle Google Cloud authentication for the upcoming init command.

Key Changes:

  • Interactive Credential Discovery: The get_credentials_path function orchestrates the authentication process:
    1. It first checks the default gcloud ADC path for valid credentials.
    2. If credentials are not found or are invalid, it prompts the user to run gcloud auth application-default login.
    3. If the user declines or the login fails, it provides a final option to enter a custom path to a credentials file.
  • Unit testing.

@PauloVLB PauloVLB marked this pull request as ready for review October 22, 2025 18:37
Runs the gcloud login command and returns True on success.
"""
try:
subprocess.run(
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't there a way to do it through gcloud sdk?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Another option is to ask the user to run the gcloud login command if the credentials are missing instead of having to deal with running the gcloud from the CLI

Copy link
Member Author

Choose a reason for hiding this comment

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

I've done some AI-research and here's the outcome:

While the Google Cloud Python libraries (like google-auth-oauthlib) provide ways to perform a user authentication flow programmatically, there isn't a direct SDK function that replicates the specific behavior of gcloud auth application-default login.
The key distinction is that gcloud is a trusted, first-party application with its own registered OAuth 2.0 client ID. The subprocess call leverages that existing, trusted application to create the default credentials file (application_default_credentials.json) in the exact way users are familiar with.
The alternative, using the Python SDK directly, would require our casp tool to be registered as its own application in the Cloud Console. We would have to generate, manage, and distribute our own client_secrets.json file.

Given that the target users are very likely to have gcloud installed, using the subprocess is the most pragmatic approach. I can also add a message guiding the user to run the command if the subprocess call fails, what do you guys think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think I'm ok with using the subprocess call, even though this can be something not very necessary we will need to maintain, for instance if gcloud ever changes how this should be called.

# limitations under the License.
"""Tests for the gcloud utility functions.

For running all the tests, use (from the root of the project):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe add this to the init instead of this specific gcloud test module?

Copy link
Member Author

Choose a reason for hiding this comment

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

My intention here was to follow go/pystyle#test-docs.

The linter required a docstring, and according to the guide, it should contain useful information.
That said, should I add specific instructions on how to run this particular test?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. I guess we do not follow this style in the remaining codebase, but we definitely should!

It's up to you, IMO it might make more sense to have the general "how to run tests" in the init or readme, and the particular how to for each test module.

try:
credentials.Credentials.from_authorized_user_file(path)
return True
except (auth_exceptions.DefaultCredentialsError, ValueError, KeyError):
Copy link
Collaborator

@ViniciustCosta ViniciustCosta Oct 27, 2025

Choose a reason for hiding this comment

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

Maybe log the exception so the user has visibility on why the credential was not valid?

Copy link
Member Author

Choose a reason for hiding this comment

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

I reviewed the exception handling, and ValueError is the only exception that can be raised here. I've now added specific logging for it and updated the tests accordingly.

Runs the gcloud login command and returns True on success.
"""
try:
subprocess.run(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another option is to ask the user to run the gcloud login command if the credentials are missing instead of having to deal with running the gcloud from the CLI

# limitations under the License.
"""Tests for the gcloud utility functions.

For running all the tests, use (from the root of the project):
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see. I guess we do not follow this style in the remaining codebase, but we definitely should!

It's up to you, IMO it might make more sense to have the general "how to run tests" in the init or readme, and the particular how to for each test module.

credentials.Credentials.from_authorized_user_file(path)
return True
except ValueError as e:
click.secho(f'Error: {e}', fg='red')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: A little more specific would be nice "Error when checking for valid credentials: {e}"

Runs the gcloud login command and returns True on success.
"""
try:
subprocess.run(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think I'm ok with using the subprocess call, even though this can be something not very necessary we will need to maintain, for instance if gcloud ever changes how this should be called.

@PauloVLB PauloVLB merged commit 117a70f into master Nov 3, 2025
10 checks passed
@PauloVLB PauloVLB deleted the cli-gcloud-module branch November 3, 2025 14:01
@PauloVLB PauloVLB changed the title Add gcloud utility module [CLI] Add gcloud utility module Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants