import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"server/config"
"gorm.io/plugin/dbresolver"
)
func DB(config *config.Config) {
var err error
config.DB, err = gorm.Open("mysql", config.DBDSN)
if err != nil {
panic(err)
}
if !config.IsDev {
config.DB.Use(dbresolver.Register(dbresolver.Config{
Replicas: []gorm.Dialector{mysql.Open("mysql", config.DBDSN2)},
}))
}
}
I am trying to use GORM's DBresolver to make use of my cloud SQL instance's read replica. I think there is some versioning issue with the GORM package that I use and the DBresolver plugin. When I run the code above I get the following error:
config.DB.Use undefined (type *"github.com/jinzhu/gorm".DB has no
field or method Use)
undefined: "github.com/jinzhu/gorm".Dialect
I could not find any reason for this online and there are very few online resources on GORM's advanced functionalities. I can easily get the replica to work if I create a separate connection to it, but that way I need to specify the DB every-time I interact with the database.
I used the following to implement the code above: https://gorm.io/docs/dbresolver.html
You are using the v1 import path for gorm, but DBResolver is a V2 feature.
You'll want instead to use:
"gorm.io/gorm" for the main import package
"gorm.io/driver/mysql" for the driver import
gorm.Open with mysql.Open for creating the connections.
V2 is mostly backwards compatible, but you'll need to make sure any old code is tested to work on the new version.
import (
"gorm.io/gorm"
"gorm.io/driver/mysql"
"gorm.io/plugin/dbresolver"
"server/config"
)
func DB(config *config.Config) {
var err error
config.DB, err := gorm.Open(mysql.Open(config.DBDSN), &gorm.Config{})
if err != nil {
panic(err)
}
if !config.IsDev {
config.DB.Use(dbresolver.Register(dbresolver.Config{
Replicas: []gorm.Dialector{mysql.Open("mysql", config.DBDSN2)},
}))
}
}
Related
how to get the list of the empty namespaces in kubernetes through go?
I want to write a code in golng by which I can find empty namespaces in kubernetes
You can use a Kubernetes golang client to connect to your namespace and get all resources you want e.g. Pods and Deployments. So you can check if there is any resources or not.
For example, this code checks if there is a Deployment or not:
package main
import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
)
func main() {
ctx := context.Background()
config := ctrl.GetConfigOrDie()
clientset := kubernetes.NewForConfigOrDie(config)
namespace := "namespace"
list, err := clientset.AppsV1().Deployments(namespace).List(ctx, metav1.ListOptions{})
if err != nil {
return
}
fmt.Printf("Namespace has %d Deployments", len(list.Items))
}
You can check the count of other resources as well.
I am very new at Golang AWS SDK V2, I had similar code work without AWS results, but this one is getting me issues since the types are different. Also, I have search and none of the examples is with the code pipeline aws-sdk-v2 with the type of JSON I have to unmarshal.
I hope some of you can help me.
— This below is main.go I have the structs in another file called un-marshal.go that I created with the result of getting the same output I need from awscli tool and passing it by https://mholt.github.io/json-to-go/
package main
import (
"context"
"fmt"
"log"
"encoding/json"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/codepipeline"
)
func main() {
pipeline_name := "frontend"
// Load the Shared AWS Configuration (~/.aws/config)
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("eu-central-1"))
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatalf("unable to load SDK config, %v", err)
}
client := codepipeline.NewFromConfig(cfg)
pipeJson, err := client.GetPipelineState(context.TODO(), &codepipeline.GetPipelineStateInput{
Name: &pipeline_name,
})
if err != nil {
log.Println("Error getting Pipeline")
}
var cookie PipeLineResult
json.Unmarshal(pipeJson, &cookie)
fmt.Println("The name of the pipeline is: %s",cookie.PipelineName)
}
The error I am getting is:
/main.go:39:17: cannot use pipeJson (variable of type *codepipeline.GetPipelineStateOutput) as type []byte in argument to json.Unmarshal
Here I am lost because it is a new type, and not sure if I should convert, how to convert or work with the native type etc.
Thanks in advance.
I am new to golang, and coming from java background. I am looking for some best practices for configuring the application.
I can simply load the configuration to viper and then just import to any packages and access the value using viper.Get, as the lib uses the pointer to viper so that It will always be accessing the same instance.
An alternative is to create a new viper instance cfg:=viper.New() and load the configuration then pass the cfg to all the package that needs it.
I found it cumbersome to pass the config to all the dependencies. I also have the same question for logrus, can i use the same pattern or I need to create a new instance and pass it along to all the dependencies.
Here are the code to illustrate my questions (viper seems to have all the configuration value across the packages)
main.go ($PROJECTHOME/cmd/main.go)
func main() {
loadConfig()
fmt.Printf("in main package %s", viper.Get("clientConfig"))
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
routes.AddUserResource(r, cfg)
http.ListenAndServe(":"+port, r)
}
func loadConfig() {
viper.SetConfigType("yaml")
viper.SetConfigName("config.local")
viper.AddConfigPath("config")
viper.AddConfigPath("../config")
err := viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("fatal error config file: %w", err))
}
}
other package ($PROJECTHOME/api/client/userClient.go)
package client
....
func RetrieveUser(config domain.ServicConfig, id string) (domain.User, bool) {
fmt.Printf("in http client package %s", viper.Get("clientConfig"))
for _, user := range users {
if user.Id == id {
return user, true
}
}
return domain.User{}, false
}
I've recently shifted from python to golang. I had been using python to work with GCP.
I used to pass in the scopes and mention the discovery client I wanted to create like this :
def get_client(scopes, api, version="v1"):
service_account_json = os.environ.get("SERVICE_ACCOUNT_KEY_JSON", None)
if service_account_json is None:
sys.exit("Exiting !!! No SSH_KEY_SERVICE_ACCOUNT env var found.")
credentials = service_account.Credentials.from_service_account_info(
json.loads(b64decode(service_account_json)), scopes=scopes
)
return discovery.build(api, version, credentials=credentials, cache_discovery=False)
And this would create my desired discovery client, whether it be compute engine service or sqladmin
However in go I don't seem to find this.
I found this : https://pkg.go.dev/google.golang.org/api/discovery/v1
For any client that I want to create I would've to import that and then create that, like this :
https://cloud.google.com/resource-manager/reference/rest/v1/projects/list#examples
package main
import (
"fmt"
"log"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
"google.golang.org/api/cloudresourcemanager/v1"
)
func main() {
ctx := context.Background()
c, err := google.DefaultClient(ctx, cloudresourcemanager.CloudPlatformScope)
if err != nil {
log.Fatal(err)
}
cloudresourcemanagerService, err := cloudresourcemanager.New(c)
if err != nil {
log.Fatal(err)
}
req := cloudresourcemanagerService.Projects.List()
if err := req.Pages(ctx, func(page *cloudresourcemanager.ListProjectsResponse) error {
for _, project := range page.Projects {
// TODO: Change code below to process each `project` resource:
fmt.Printf("%#v\n", project)
}
return nil
}); err != nil {
log.Fatal(err)
}
}
So I've to import each client library to get the client for that.
"google.golang.org/api/cloudresourcemanager/v1"
There's no dynamic creation of it.
Is it even possible, cause go is strict type checking 🤔
Thanks.
No, this is not possible with the Golang Google Cloud library.
You've nailed the point on the strict type checking, as it would definitely defeat the benefits of compile time type checking. It would also be a bad Golang practice to return different objects with different signatures, as we don't do duck typing and instead we rely on interface contracts.
Golang is boring and verbose, and it's like that by design :)
I want to use gorm in my code but when I run go run *.go, I see this Error, unfortunately.
/var/www/html/src/gorm.io/gorm/utils/utils.go:46:30: reflect.ValueOf(val).IsZero undefined (type reflect.Value has no field or method IsZero)
this is my code:
package main
import (
"gorm.io/gorm"
"gorm.io/driver/sqlite"
)
type Product struct {
gorm.Model
Code string
Price uint
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
db.AutoMigrate(&Product{})
// Create
db.Create(&Product{Code: "D42", Price: 100})
}
The Value.IsZero() method was added in Go 1.13. You have to use Go 1.13 or a later version if your code relies on this "feature".
You can check your go version by running go version.