Reputation: 65
I'm trying to learn Go by managing Google Cloud Platform. I didn't understand how to use related functions about Compute. The goal is listing instances with some go code.
This is https://godoc.org/google.golang.org/api/compute/v1#InstancesService.List the related function.
func (r *InstancesService) List(project string, zone string) *InstancesListCall
There are two structs, InstancesService and InstancesListCall
As far as i understand i should define these structs but it's not clear the things should be defined in the structs. I've searched for examples but many of them using rest calls instead of golang api. Have any idea how to list instances with go?
Upvotes: 0
Views: 4385
Reputation: 83
You can also use AggregatedList and cloud cred in golang and can retrieve all instance information
package main
import (
"context"
"flag"
"fmt"
"log"
"github.com/binxio/gcloudconfig"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
"google.golang.org/api/option"
)
func main() {
//gcp session
var credentials *google.Credentials
name := flag.String("configuration", "", "`kunets` of the configuration to use")
project := flag.String("project", "", "`kunets` of the project to query")
flag.Parse()
credentials, _ = gcloudconfig.GetCredentials(*name)
if project == nil || *project == "" {
project = &credentials.ProjectID
}
if *project == "" {
log.Printf("%v", credentials)
log.Fatal("no -project specified")
}
computeService, err := compute.NewService(context.Background(), option.WithCredentials(credentials))
if err != nil {
log.Fatal(err)
}
token := ""
var list *compute.InstanceAggregatedList
if list, err = computeService.Instances.AggregatedList(*project).PageToken(token).Do(); err != nil {
log.Fatal(err)
}
for _, instances := range list.Items {
for _, instance := range instances.Instances {
EXTERNAL_IP := instance.NetworkInterfaces[0].AccessConfigs[0].NatIP
fmt.Printf("%s \n", EXTERNAL_IP)
INTERNAL_IP := instance.NetworkInterfaces[0].NetworkIP
fmt.Printf("%s \n", INTERNAL_IP)
fmt.Printf("%s \n", instance.Name)
}
}
}
Upvotes: 0
Reputation: 6189
You can also use Aggregated List which will search every zone for you. This saves you having to do nested loops or figuring out what the zones are.
https://pkg.go.dev/cloud.google.com/go/compute/apiv1#InstancesClient.AggregatedList
The below assumes you have logged into gcloud and set your ADC.
$ gcloud init
$ gcloud auth application-default login
Using a service account key is also possible but not demonstrated below.
package main
import (
"context"
"fmt"
"log"
compute "cloud.google.com/go/compute/apiv1"
"google.golang.org/api/iterator"
protobuf "google.golang.org/genproto/googleapis/cloud/compute/v1"
)
func main() {
ctx := context.Background()
c, err := compute.NewInstancesRESTClient(ctx)
if err != nil {
log.Fatalln(err)
}
defer c.Close()
project := "my-project"
req := &protobuf.AggregatedListInstancesRequest{
Project: project,
}
it := c.client.AggregatedList(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatalln(err)
}
fmt.Println(resp)
}
}
Upvotes: 1
Reputation: 32169
i had to write something like this today and googling for examples turned up surprisingly little. i've written up what i learned below, however, i'm quite new to golang so maybe smarter people can suggest improvements.
my work in progress is at: https://github.com/grenade/rubberneck
if you want to run your go program from a development pc that is not on the google compute platform:
GOOGLE_APPLICATION_CREDENTIALS
environment variable to the path of your local key filepackage main
import (
"golang.org/x/net/context"
"google.golang.org/api/compute/v1"
"golang.org/x/oauth2/google"
"fmt"
"strings"
)
func main() {
projects := [...]string{
"my-project-one",
"my-project-two",
}
filters := [...]string{
"status = RUNNING",
"name != my-uninteresting-instance-one",
"name != my-uninteresting-instance-two",
}
ctx := context.Background()
client, err := google.DefaultClient(ctx,compute.ComputeScope)
if err != nil {
fmt.Println(err)
}
computeService, err := compute.New(client)
for _, project := range projects {
zoneListCall := computeService.Zones.List(project)
zoneList, err := zoneListCall.Do()
if err != nil {
fmt.Println("Error", err)
} else {
for _, zone := range zoneList.Items {
instanceListCall := computeService.Instances.List(project, zone.Name)
instanceListCall.Filter(strings.Join(filters[:], " "))
instanceList, err := instanceListCall.Do()
if err != nil {
fmt.Println("Error", err)
} else {
for _, instance := range instanceList.Items {
if workerType, isWorker := instance.Labels["worker-type"]; isWorker {
m := strings.Split(instance.MachineType, "/")
fmt.Printf("cloud: gcp, zone: %v, name: %v, instance id: %v, machine type: %v, worker type: %v, launch time: %v\n",
zone.Name,
instance.Name,
instance.Id,
m[len(m)-1],
workerType,
instance.CreationTimestamp)
}
}
}
}
}
}
}
Upvotes: 4