go-cloud
go-cloud copied to clipboard
Be able to OpenPostgresURL with a provided Credential JSON rather than forced to use files
Hi!
I have a use case where i would like to be able to Open a PostgresURL connection via the gcppostgres package using a google credential (JSON) of my choice. Currently I am limited to OpenPostgresURL which searches for the the credential in google's default environment variable file locations, see:
https://github.com/google/go-cloud/blob/e6b94a04072fec4c7106c8301a56436b6fa4135d/postgres/gcppostgres/gcppostgres.go#L66
I would instead benefit from the option of suggesting the JSON directly to a function or having an environment variable which could contain the pure JSON (not a location on disk where the json is stored).
This is useful for any event where one is unable to generate a file on a machine but can dictate the environment variables on them (e.g i would be able to read the credentials i want from a (secret) json environmental variable).
My 1st suggestion here would be to introduce a different environmental variable (e.g GOOGLE_APPLICATION_CREDENTIALS_JSON) that takes precedence over the file environmental variable (GOOGLE_APPLICATION_CREDENTIALS) searched by google.FindDefaultCredentials function here:
https://github.com/google/go-cloud/blob/e6b94a04072fec4c7106c8301a56436b6fa4135d/gcp/gcp.go#L80
and instead call google.CredentialsFromJSON on GOOGLE_APPLICATION_CREDENTIALS_JSON before proceeding to call
google.FindDefaultCredentials:
https://github.com/google/go-cloud/blob/e6b94a04072fec4c7106c8301a56436b6fa4135d/gcp/gcp.go#L80
I could draft a PR to introduce the proposed behaviour if it is reasonable
Suggestion:
// DefaultCredentials obtains the default GCP credentials with Cloud Platform
// scope.
func DefaultCredentials(ctx context.Context) (*google.Credentials, error) {
// First, try the GOOGLE_APPLICATION_CREDENTIALS_JSON environment variable.
var adc *google.Credentials
const envVar = "GOOGLE_APPLICATION_CREDENTIALS_JSON"
if jsonCredentials := os.Getenv(envVar); jsonCredentials != "" {
bytes, err := json.Marshal(jsonCredentials)
if err != nil {
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
}
adc, err = google.CredentialsFromJSON(ctx, bytes, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return nil, err
}
return adc, nil
}
adc, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return nil, err
}
return adc, nil
}
Can you create your own URLOpener?
https://github.com/google/go-cloud/blob/e6b94a04072fec4c7106c8301a56436b6fa4135d/postgres/gcppostgres/gcppostgres.go#L89
Or write the JSON to a temp file and use GOOGLE_APPLICATION_CREDENTIALS?
I would prefer not to add custom auth mechanisms to this library if possible.
Unfortunately for my usecase i can not write the JSON into a temp file but i do understand the need to not customize the auth mechanism. I'll look into setting up my own URLOpener
Let's leave the feature request open to see if other people have the same request. If it's a relatively common use case I don't mind your suggestion, but if it's just you I think it makes more sense to have you create your own URLOpener.