I have a TCP server that tries to connect to a Couchbase database using the go-couchbase client library but I get an error saying that the bucket that I'm trying to access, named "events", doesn't exist.
When I use the official Couchbase client library for Go everything works fine.
The difference that I noticed between these two clients is the concept of "pool". I have set this pool to be "default".
What could lead to this Go client not seeing my bucket?
cb, err := couchbase.Connect("http://address:port")
if err != nil {
log.Fatalf("Error connecting: %v", err)
}
cbPool, err := cb.GetPool("default")
if err != nil {
log.Fatalf("Error getting pool: %v", err)
}
cbBucket, err := cbPool.GetBucketWithAuth("events", "username", "password")
if err != nil {
log.Fatalf("Error getting bucket: %v", err)
}
I'm assuming you're getting some kind of an authentication error. The API is a little bit confusing. GetBucketWithAuth should be called like this:
GetBucketWithAuth("events", "events", "password")
The reason is that the client wants the bucket user name and the bucket password. The bucket username is the same as the bucket name.
With that said I would highly recommend that you use gocb and not go-couchbase. gocb is the official Couchbase go client and go-couchbase is only used internally inside Couchbase. In fact many of the components that use go-couchbase will start using gocb instead since this library is much easier to use and is better organized.
https://github.com/couchbase/gocb
Related
Im using the following code which works as expected, I use from the cli gcloud auth application-default login and enter my credentials and I was able to run the code successfully from my macbook.
Now I need to run this code in my CI and we need to use different approach , what should be the approach to get the client_secret
and client_id or service account / some ENV variable, what is the way for doing it via GO code?
import "google.golang.org/api/compute/v1"
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)
}
Since you're using Jenkins you probably want to start with how to create a service account. It guides you on creating a service account and exporting a key to be set as a var in another CI/CD system.
Then refer to the docs from the client library on how to create a new client with source credential.
e.g.
client, err := storage.NewClient(ctx, option.WithCredentialsFile("path/to/keyfile.json"))
If you provided no source, it would attempt to read the credentials locally and act as the service account running the operation (not applicable in your use case).
Many CIs support the export of specific env vars. Or your script / conf can do it too.
But if you want to run in a CI why you need such configuration? Integration tests?
Some services can be used locally for unit/smoke testing. Like pubsub, there is a way to run a fake/local pubsub to perform some tests.
Or perhaps I did not understand your question, in this case can you provide an example?
I am trying to give my bucket-logs ACL access of Writer as suggested here.
gsutil acl ch -g cloud-storage-analytics#google.com:W gs://my_logs
I am using Go SDK v 1.10.0. Here is the Go code:
bucket_log := client.Bucket(logBucketName)
if err := bucket_log.ACL().Set(ctx, "cloud-storage-analytics#google.com", storage.RoleWriter); err != nil {
return fmt.Errorf("Failed to Give ACL access on Logging bucket %s.\nError: %s", logBucketName, err.Error())
}
But I am getting following error:
Error: googleapi: Error 400: Invalid Value, invalid
But if I change "cloud-storage-analytics#google.com" into storage.AllAuthenticatedUsers, then it runs fine. Can anybody point me to the right direction? Thanks in advance
Solved it, in the documentation, it was mentioned to use group-<email>. So, now the code now looks like this.
if err := bucket_log.ACL().Set(ctx, "group-cloud-storage-analytics#google.com", storage.RoleWriter); err != nil {
return fmt.Errorf("Failed to Give ACL access on Logging bucket %s.\nError: %s", logBucketName, err.Error())
}
I'm using this example provided under cloud functions to make a GET request to another GCP API:
import (
"context"
"fmt"
"io"
"google.golang.org/api/idtoken"
)
func makeGetRequest(w io.Writer, targetURL string) error {
ctx := context.Background()
client, err := idtoken.NewClient(ctx, targetURL)
if err != nil {
return fmt.Errorf("idtoken.NewClient: %v", err)
}
resp, err := client.Get(targetURL)
if err != nil {
return fmt.Errorf("client.Get: %v", err)
}
defer resp.Body.Close()
if _, err := io.Copy(w, resp.Body); err != nil {
return fmt.Errorf("io.Copy: %v", err)
}
return nil
}
but when I log the request sent I don't see any authorization header and I get the following error:
"Request
had invalid authentication credentials. Expected OAuth 2 access token, login cookie
or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\"
I have given serviceAccountTokenCreator and the target GCP API admin permissions to the service account that's used to create the cloud function.
Am I misunderstanding what the documentation is saying? It seems like the authorization header should be automatically added.
It might be easier for you to not build the request from scratch and use Client Libraries instead. It provides idiomatic, generated or hand-written code in each language, making the Cloud API simple and intuitive to use. It also handles authentication for you.
From what you're following, the client automatically adds an "Authorization" header so that shouldn't be the problem. You're also trying to follow an example that generates an Identity Token, because calling a Cloud Function endpoint that has authentication requires an Identity token. This is different on your use case, because calling GCP APIs require an OAuth 2 access token. This link explains the difference between the two.
There are ways to generate an access token programmatically such as getting them from the metadata server as I did in my other answer (it's in Python but you can also do it in Golang). However, I suggest learning more on how Client Libraries work and test it for yourself. There are many examples shown on GitHub to get you started.
In one of my services that happens to be my loadbalancer, I am getting the following error when calling the server method in one of my deployed services:
rpc error: code = Unimplemented desc = unknown service
fooService.FooService
I have a few other services set up with gRPC and they work fine. It just seems to be this one and I am wondering if that is because it is the loadbalancer?
func GetResult(w http.ResponseWriter, r *http.Request) {
conn, errOne := grpc.Dial("redis-gateway:10006", grpc.WithInsecure())
defer conn.Close()
rClient := rs.NewRedisGatewayClient(conn)
result , errTwo := rClient.GetData(context.Background(), &rs.KeyRequest{Key: "trump", Value: "trumpVal"}, grpc.WithInsecure())
fmt.Fprintf(w, "print result: %s \n", result) //prints nil
fmt.Fprintf(w, "print error one: %v \n", errOne) // prints nil
fmt.Fprintf(w, "print error two: %s \n", errTwo) // prints error
}
The error says there is no service called fooService.FooService which is true because the dns name for the service I am calling is called foo-service. However it is the exact same setup for my other services that use gRPC and work fine. Also my proto files are correctly configured so that is not an issue.
server I am calling:
func main() {
lis, err := net.Listen("tcp", ":10006")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
newServer := &RedisGatewayServer{}
rs.RegisterRedisGatewayServer(grpcServer, newServer)
if err := grpcServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
The function I am trying to access from client:
func (s *RedisGatewayServer) GetData(ctx context.Context, in *rs.KeyRequest)(*rs.KeyRequest, error) {
return in, nil
}
My docker and yaml files are all correct also with the right naming and ports.
I had this exact problem, and it was because of a very simple mistake: I had put the call to the service registration after the server start. The code looked like this:
err = s.Serve(listener)
if err != nil {
log.Fatalf("[x] serve: %v", err)
}
primepb.RegisterPrimeServiceServer(s, &server{})
Obviously, the registration should have been called before the server was ran:
primepb.RegisterPrimeServiceServer(s, &server{})
err = s.Serve(listener)
if err != nil {
log.Fatalf("[x] serve: %v", err)
}
thanks #dolan's for the comment, it solved the problem.
Basically we have to make sure, the method value should be same in both server and client (you can even copy the method name from the pb.go file generated from server side)
func (cc *ClientConn) Invoke(ctx context.Context, method string, args, reply interface{}, opts ...CallOption) error {
this invoke function will be there inside all the methods which you have implemented in gRPC service.
for me, my client was connecting to the wrong server port.
My server listens to localhost:50052
My client connects to localhost:50051
and hence I see this error.
I had the same problem - I was able to perform rpc call from Postman to the service whereas apigateway was able to connect to the service but on method call It gave error code 12 unknown service and the reason was in my proto files client was under package X whereas server was under package Y.
Quite silly but yeah making the package for both proto under apigateway and service solved my problem.
There are many scenarios in which this can happen. The underlying issue seems to be the same - the GRPC server is reachable but cannot service client requests.
The two scenarios I faced that are not documented in previous answers are:
1. Client and server are not running the same contract version
A breaking change introduced in the contract can cause this error.
In my case, the server was running the older version of the contract while the client was running the latest one.
A breaking change meant that the server could not resolve the service my client was asking for thus returning the unimplemented error.
2. The client is connecting to the wrong GRPC server
The client reached the incorrect server that doesn't implement the contract.
Consider this scenario if you're running multiple different GRPC services. You might be mistakingly dialing the wrong one.
Is there any way to create a user in Firebase using Userame, Email and Password with Golang. A user can be created with Javascript using createUserWithEmailAndPassword(email, password) But I need the same with Golang. Is there a package or function available? I am using firego to connect with Firebase.
Recently Google added Go Lang to their list of programming languages that are supported by Firebase Authentication using Firebase Admin SDK.
To create a user:
params := (&auth.UserToCreate{}).
Email("user#example.com").
EmailVerified(false).
PhoneNumber("+1234567890").
Password("secretPassword").
DisplayName("Donald Drump").
PhotoURL("http://www.example.com/12345678/photo.png").
Disabled(false)
u, err := client.CreateUser(context.Background(), params)
if err != nil {
log.Fatalf("error creating user: %v\n", err)
}
log.Printf("Successfully created user: %v\n", u)
if you want to create a user with your own user ID and don't want an automated generated ID by Firebase then:
params := (&auth.UserToCreate{}).
UID(uid).
Email("user#example.com").
PhoneNumber("+1234567890")
u, err := client.CreateUser(context.Background(), params)
if err != nil {
log.Fatalf("error creating user: %v\n", err)
}
log.Printf("User created successfully : %v\n", u)
to update a user:
params := (&auth.UserToUpdate{}).
Email("user#example.com").
EmailVerified(true).
PhoneNumber("+1234567890").
Password("newPassword").
DisplayName("Donald Drump").
PhotoURL("http://www.example.com/12345678/photo.png").
Disabled(true)
u, err := client.UpdateUser(context.Background(), uid, params)
if err != nil {
log.Fatalf("error updating user: %v\n", err)
}
log.Printf("Successfully updated user: %v\n", u)
Firebase has added an Admin SDK for Go. See Mujtaba's answer for more information: https://stackoverflow.com/a/47889860
Previous answer:
There is no Firebase SDK for Go. But certain parts of Firebase have a REST API that allows you to use those features from almost any platform/technology. The Firebase Database is one of those features and the Firego library is a wrapper around the REST API of the Firebase Database for Go developers.
Unfortunately there is no REST API for creating users in Firebase Authentication. So it won't be possible to create users through Firego or through a public REST API from your Go code.
The simplest solution would be to create a REST endpoint on a app server you control, where you then use the Firebase Admin SDK to create the user.