如何使用GCE Go客户端oauth2身份验证实现自动身份验证

如何使用GCE Go客户端oauth2身份验证实现自动身份验证

问题描述:

This code is on the basis of golang.org/x/oauth2 example test. I am trying to get instance information from Google Compute Engine using Go client. Do I have to use oauth2 authentication? There is a generated link after Visit the URL for the auth dialog:

https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=xxx&redirect_uri=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute&state=state

and it redirect to https://www.googleapis.com/auth/compute which shows a 'compute'. How do I achieve automatic authentication?

package main

import (
    "context"
    "fmt"
    "log"

    "golang.org/x/oauth2"
    "google.golang.org/api/compute/v1"
)

type GCE struct {
    *compute.Service
}

var ctx = context.Background()

func initGCE() *GCE {
    conf := &oauth2.Config{
        ClientID:     "xxx",
        ClientSecret: "xxx",
        Scopes:       []string{compute.ComputeScope},
        Endpoint: oauth2.Endpoint{
            AuthURL:  "https://accounts.google.com/o/oauth2/auth",
            TokenURL: "https://accounts.google.com/o/oauth2/auth",
        },
        RedirectURL: "https://www.googleapis.com/auth/compute",

    }
    url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline)
    fmt.Printf("Visit the URL for the auth dialog: %v", url)
    var code string
    if _, err := fmt.Scan(&code); err != nil {
        log.Fatal(err)
    }
    tok, err := conf.Exchange(ctx, code)
    if err != nil {
        log.Fatal(err)
    }
    service, err := compute.New(conf.Client(ctx, tok))
    if err != nil {
        log.Fatal(err)
    }
    return &GCE{service}
}

func (g *GCE) Instance() {
    project := "arctic-cyclist-189707"
    zone := "us-east1-b"
    instance := "centos7"
    resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
    if err != nil {
        fmt.Println(err)
        return
    } else {
        fmt.Printf("%#v
", resp)

    }
}

Solved by using code example

https://cloud.google.com/compute/docs/reference/latest/instances/get#examples

just set "GOOGLE_APPLICATION_CREDENTIALS" environment varibles as google.DefaultClient() requires.
package main

import (
    "context"
    "fmt"
    "log"

    "golang.org/x/oauth2/google"
    "google.golang.org/api/compute/v1"
)

type GCE struct {
    *compute.Service
}

var ctx = context.Background()

func initGCE() *GCE {
    c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
    if err != nil {
        log.Fatal(err)
    }

    computeService, err := compute.New(c)
    if err != nil {
        log.Fatal(err)
    }
    return &GCE{computeService}
}

func (g *GCE) Instance(project, zone, instance string) {
    resp, err := g.Instances.Get(project, zone, instance).Context(ctx).Do()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%#v
", resp)
}

Thanks for your reply.