Unable to list folders in GCP using go client library - go

I am going through the documentation of cloudresourcemanager package and trying to build a simple example to list the folders of my GCP project.
The following example however fails
package main
import (
"context"
"fmt"
"log"
cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v2"
)
func main() {
ctx := context.Background()
svc, err := cloudresourcemanager.NewService(ctx)
if err != nil {
log.Fatal(err)
}
foldersService := cloudresourcemanager.NewFoldersService(svc)
fmt.Println(foldersService)
foldersListCall := foldersService.List()
resp, err := foldersListCall.Do()
if err != nil {
fmt.Println("Here")
log.Fatal(err)
}
for _, fld := range resp.Folders {
fmt.Println(fld.Name)
}
}
It fails in
resp, err := foldersListCall.Do()
and the error is
googleapi: Error 400: Request contains an invalid argument., badRequest
I have the following environment variables set
GOOGLE_CLOUD_PROJECT=my-project-id
GOOGLE_APPLICATION_CREDENTIALS=/path/to/application_default_credentials.json
and gcloud cli works fine.
Any suggestions what I might be missing?

The error message is not helpful at all...
The problem is I was not setting the Parent parameter in the request, i.e. the organization (switching to v3 helped a bit)
package main
import (
"context"
"fmt"
"log"
cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v3"
)
func main() {
ctx := context.Background()
svc, err := cloudresourcemanager.NewService(ctx)
if err != nil {
log.Fatal(err)
}
foldersService := cloudresourcemanager.NewFoldersService(svc)
foldersListCall := foldersService.List()
foldersListCall.Parent("organizations/12345678910")
resp, err := foldersListCall.Do()
if err != nil {
log.Fatal(err)
}
for _, fld := range resp.Folders {
fmt.Println(fld.DisplayName)
}
}

Related

Setting labels on GCP Compute Instances using Golang

I was looking for ways to set or update instance Labels on GCP Compute Instance and labelFingerprint confused me.
then I figure it out and I'm putting the code in the answer section.
I used this simple code to add new labels to GCP instances.
package main
import (
"context"
"log"
"os"
"golang.org/x/oauth2/google"
"google.golang.org/api/compute/v1"
)
func main() {
addLabelToGCPInstances()
}
func addLabelToGCPInstances() error {
// You can pass these as args
project := "Your GCP Project ID"
zone := "europe-west2-a"
instance := "milad-test-instance"
prodLablesMap := map[string]string{
"production": "true",
"environment": "production",
}
ctx := context.Background()
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "gke.json")
c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
if err != nil {
return err
}
computeService, err := compute.New(c)
if err != nil {
return err
}
respInstance, err := computeService.Instances.Get(project, zone, instance).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
rb := &compute.InstancesSetLabelsRequest{
Labels: prodLablesMap,
LabelFingerprint: respInstance.LabelFingerprint,
}
respLabels, err := computeService.Instances.SetLabels(project, zone, instance, rb).Context(ctx).Do()
if err != nil {
log.Fatal(err)
}
_ = respLabels
return err
}
This is just an example you can work around and do more error handling and etc.

GCP - get project NAT GW's

We have account on GCP which contain valid cloud Nat, now we want to get those values via
GCP sdk, I've tried the following and get empty response (maybe I use the wrong API and it not ListExternalVpnGatewaysRequest)
package main
import (
"context"
"fmt"
compute "cloud.google.com/go/compute/apiv1"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)
func main() {
ctx := context.Background()
c, err := compute.NewExternalVpnGatewaysRESTClient(ctx)
if err != nil {
fmt.Println(err)
}
defer c.Close()
proj := "dev-proj"
req := &computepb.ListExternalVpnGatewaysRequest{
//Filter: new(string),
//MaxResults: new(uint32),
//OrderBy: new(string),
//PageToken: new(string),
Project: proj,
//ReturnPartialSuccess: new(bool),
}
it := c.List(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
fmt.Println(err)
}
// TODO: Use resp.
_ = resp
fmt.Println(resp)
}
}
I need to get the following values using GCP GO SDK
update
I tried the following as-is and I got error
package main
import (
"context"
"fmt"
"google.golang.org/api/compute/v1"
"log"
)
func main() {
project := "my-proj"
region := "my-region"
ctx := context.Background()
computeService, err := compute.New(ctx)
if err != nil {
log.Fatal(err)
}
req := computeService.Routers.List(project, region)
if err := req.Pages(ctx, func(page *compute.RouterList) error {
for _, router := range page.Items {
// process each `router` resource:
fmt.Printf("%#v\n", router)
// NAT Gateways are found in router.nats
}
return nil
}); err != nil {
log.Fatal(err)
}
}
Error is: ./main.go:16:36: cannot use ctx (type context.Context) as type *http.Client in argument to compute.New
A VPN Gateway is not the same as a NAT Gateway.
Use this code to list routers. Within the list of routers, is the NAT Gateways
import "google.golang.org/api/compute/v1"
// Replace with valid values for your project
project := "my-project"
region := "my-region"
ctx := context.Background()
c, err := google.DefaultClient(ctx, compute.CloudPlatformScope)
if err != nil {
log.Fatal(err)
}
computeService, err := compute.New(c)
if err != nil {
log.Fatal(err)
}
req := computeService.Routers.List(project, region)
if err := req.Pages(ctx, func(page *compute.RouterList) error {
for _, router := range page.Items {
// process each `router` resource:
fmt.Printf("%#v\n", router)
// NAT Gateways are found in router.nats
}
return nil
}); err != nil {
log.Fatal(err)
}
SDK Documentation

Not getting response from HTTP Get Method

Implemented an logic in go to fetch the information from given URL,The problem is response of net/http is empty.
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://azure.microsoft.com/en-us/")
if err != nil {
// handle error
}
body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
fmt.Print(bodyString)
fmt.Printf("%v %v", body, err)
}
Output: its returning empty slice instead of returning HTML content
[]byte{} <nil>
I'm using Go version 1.14.3.
It seems that's working when you set the User-Agent header :
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", "https://azure.microsoft.com/en-us/", nil)
req.Header.Add("User-Agent", "Mozilla")
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
fmt.Print(bodyString)
}

Can't find a public file from url in go

I am trying to get the content of a publicly available file using ioutil.ReadFile() but it doesn't find the file: panic: open http://www.pdf995.com/samples/pdf.pdf: No such file or directory
Here's my code:
// Reading and writing files are basic tasks needed for
// many Go programs. First we'll look at some examples of
// reading files.
package main
import (
"fmt"
"io/ioutil"
)
// Reading files requires checking most calls for errors.
// This helper will streamline our error checks below.
func check(e error) {
if e != nil {
panic(e)
}
}
func main() {
fileInUrl, err := ioutil.ReadFile("http://www.pdf995.com/samples/pdf.pdf")
if err != nil {
panic(err)
}
fmt.Printf("HERE --- fileInUrl: %+v", fileInUrl)
}
Here's a go playground example
ioutil.ReadFile() does not support http.
If you look at the source code(https://golang.org/src/io/ioutil/ioutil.go?s=1503:1549#L42), open the file using os.Open.
I think I can do this coding.
package main
import (
"io"
"net/http"
"os"
)
func main() {
fileUrl := "http://www.pdf995.com/samples/pdf.pdf"
if err := DownloadFile("example.pdf", fileUrl); err != nil {
panic(err)
}
}
func DownloadFile(filepath string, url string) error {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
but, go playgound not protocol(go error dial tcp: Protocol not available).
so, You have to do it PC.

How can I create a simple client app with the Kubernetes Go library?

I'm struggling with the Kubernetes Go library. The docs--at least the ones I found--appear out-of-date with the library itself. The example provided does not build because of issues with the imports. I'm just trying to do something simple: get a Service object by name and print some attributes (like nodePort). I just need a simple example of library usage to get me going.
I could easily do this using the RESTful API but that feels like re-inventing the wheel.
So after a little experimentation and a hint from the k8s Slack channel, I have this example. Perhaps someone can update the example with a proper import path.
package main
import (
"fmt"
"log"
"github.com/kubernetes/kubernetes/pkg/api"
client "github.com/kubernetes/kubernetes/pkg/client/unversioned"
)
func main() {
config := client.Config{
Host: "http://my-kube-api-server.me:8080",
}
c, err := client.New(&config)
if err != nil {
log.Fatalln("Can't connect to Kubernetes API:", err)
}
s, err := c.Services(api.NamespaceDefault).Get("some-service-name")
if err != nil {
log.Fatalln("Can't get service:", err)
}
fmt.Println("Name:", s.Name)
for p, _ := range s.Spec.Ports {
fmt.Println("Port:", s.Spec.Ports[p].Port)
fmt.Println("NodePort:", s.Spec.Ports[p].NodePort)
}
}
Here's how to do it with the latest Go client.
If you're inside the k8s cluster:
package main
import (
"fmt"
"k8s.io/client-go/1.5/kubernetes"
"k8s.io/client-go/1.5/pkg/api/v1"
"k8s.io/client-go/1.5/rest"
)
func main() {
config, err = rest.InClusterConfig()
if err != nil {
return nil, err
}
c, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
// Get Pod by name
pod, err := c.Pods(v1.NamespaceDefault).Get("my-pod")
if err != nil {
fmt.Println(err)
return
}
// Print its creation time
fmt.Println(pod.GetCreationTimestamp())
}
And if you're outside of the cluster:
package main
import (
"fmt"
"k8s.io/client-go/1.5/kubernetes"
"k8s.io/client-go/1.5/pkg/api/v1"
"k8s.io/client-go/1.5/tools/clientcmd"
)
func main() {
config, err := clientcmd.BuildConfigFromFlags("", <kube-config-path>)
if err != nil {
return nil, err
}
c, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, err
}
// Get Pod by name
pod, err := c.Pods(v1.NamespaceDefault).Get("my-pod")
if err != nil {
fmt.Println(err)
return
}
// Print its creation time
fmt.Println(pod.GetCreationTimestamp())
}
I have gone into more detail on this in a blog post.
With kubernetes go client, it could be done this way:
package main
import (
"flag"
"fmt"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/clientcmd"
)
var (
kubeconfig = flag.String("kubeconfig", "./config", "absolute path to the kubeconfig file")
)
func main() {
flag.Parse()
// uses the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
// creates the clientset
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
services, err := clientset.Core().Services("").List(v1.ListOptions{})
if err != nil {
panic(err.Error())
}
fmt.Printf("There are %d pods in the cluster\n", len(services.Items))
for _, s := range services.Items {
for p, _ := range s.Spec.Ports {
fmt.Println("Port:", s.Spec.Ports[p].Port)
fmt.Println("NodePort:", s.Spec.Ports[p].NodePort)
}
}
}

Resources