MarcoW
MarcoW

Reputation: 535

Providing Google service account credentials manually in Golang

To remotely connect to a Google-cloud Mysql database via the Go Proxy library, I need to provide service account credentials. This can be done through setting the GOOGLE_APPLICATION_CREDENTIALS environment variable, but since I want the application to be able to run on different machines without having to set the environment variable everywhere, that is not an option.

As a result, I have to provide the service account credentials manually to my Golang application. The code below (without the authentication) gives this error message:

default proxy initialization failed; consider calling proxy.Init explicitly: google: could not find default credentials. See https://developers.google.com/accounts/docs/application-default-credentials for more information.

Google provides elaborate documentation on how to fix the manual authentication for a number of programming languages, but not for Go:

https://cloud.google.com/docs/authentication/production#auth-cloud-explicit-csharp

Could anyone help me out with setting authentication credentials manually in Golang?

Thanks a bunch!

package main

import (
    "database/sql"
    "fmt"
    "github.com/GoogleCloudPlatform/cloudsql-proxy/proxy/dialers/mysql"
)

var db *sql.DB

func main() {

cfg := mysql.Cfg("mysql", "********", "********") //name , username, password
cfg.DBName = "MyDBName"
db := mysql.DialCfg(cfg)
defer db.Close()

}

Upvotes: 2

Views: 3164

Answers (1)

Jofre
Jofre

Reputation: 3898

When using the cloudsql-proxy package, you're not directly connecting to your cloud SQL instance, but creating a proxy and connecting to it. It's the proxy connection where you have to provide the credentials.

In the tests for the cloud-sql package there is an example of how to init the proxy with credentials.

The proxy initializes by itself if you don't do it manually, but you can call proxy.Init with an http client, and you can create an http client with credentials.

I've not tested this, but you could try something like proxy.Init(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: <YOUR_TOKEN>})), nil, nil) before the DialCfg call.

A better example, if you provide your credentials file (so it's not hard-coded) would be something like:

func main()
  credsFile := "path/to/your/credentials.json"
  SQLScope := "https://www.googleapis.com/auth/sqlservice.admin"
  ctx := context.Background()

  creds, err := ioutil.ReadFile(credsFile)
  if err != nil {
    # handle error
  }

  cfg, err := goauth.JWTConfigFromJSON(creds, SQLScope)
  if err != nil {
    # handle error
  }

  client := cfg.Client(ctx)
  proxy.Init(client, nil, nil)

  var db *sql.DB

  cfg := mysql.Cfg("mysql", "********", "********") //name , username, password
  cfg.DBName = "MyDBName"
  db, err := mysql.DialCfg(cfg)
  if err != nil {
    # handle error
  }
  defer db.Close()

  # your calls to cloudSQL

}

(This is mainly a copy of the tests on that package.)

Upvotes: 1

Related Questions