How to connect PostgreSQL database using Gorm - postgresql

I am unable to connect to PostgreSQL.
var db *gorm.DB
var err error
func main() {
router := mux.NewRouter()
var err error
db, err = gorm.Open("postgres", "host=localhost port=5432 user=postgres dbname=dvdrental password=12345")
if err != nil {
panic("failed to connect database")
}
I am expecting database to be connected and fetching api.

This is the best way I found to connect to postgres.
import _ "github.com/jinzhu/gorm/dialects/postgres"
dsn := url.URL{
User: url.UserPassword(conf.User, conf.Password),
Scheme: "postgres",
Host: fmt.Sprintf("%s:%d", conf.Host, conf.Port),
Path: conf.DBName,
RawQuery: (&url.Values{"sslmode": []string{"disable"}}).Encode(),
}
db, err := gorm.Open("postgres", dsn.String())

Followed the official docs and it worked for me,
Visit https://gorm.io/docs/connecting_to_the_database.html
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
I just had to remove the host variable and enter rest of the details and it works.

First of all, the question keeps spaces for imagination.
Anyway, here're the possible use-cases why you're not able to connect gorm to postgres:
Make sure your postgres is well running in the host you have specified (in this case: localhost)
If it's alright, make sure your user and password is alright
If everything is ok, you can check in the CLI:
$ sudo -i -u postgres
$ psql
If it's successful, that means something else in the code. As far as I can see, you did not show the import section. Did you silently import the postgres gorm dialects?
import _ "github.com/jinzhu/gorm/dialects/postgres"

Related

unable to authenticate with mongodb golang driver

I'm using mongodb community version 4.2.13 and go driver version 1.5.
My go application is running on the same host as db, but getting the following error when trying to make a connection:
connection() error occured during connection handshake: auth error:
sasl conversation error: unable to authenticate using mechanism
"SCRAM-SHA-256": (AuthenticationFailed) Authentication failed.
Here is how I created the admin account:
use admin
db.createUser({
user: "admin1",
pwd: "passwd12#$",
roles: ["root"],
mechanisms: ["SCRAM-SHA-256"]
})
db.system.users.update(
{ _id: "admin.admin1", "db": "admin" },
{
$addToSet: {
authenticationRestrictions: { clientSource: ["127.0.0.1"] }
}
}
)
Go app code snippet
package main
import (
"context"
"fmt"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
uri := fmt.Sprintf(
"mongodb://%s:%s#%s:%d/admin?authSource=admin&authMechanism=SCRAM-SHA-256",
"admin1",
"passwd12#$",
"127.0.0.1",
27017,
)
// Prints "mongodb://admin1:passwd12#$#127.0.0.1:27017/admin?authSource=admin&authMechanism=SCRAM-SHA-256"
fmt.Println(uri)
ctx, cancel := context.WithTimeout(context.Background(), 10 * time.Second)
defer cancel()
client, err := mongo.Connect(
ctx,
options.Client().ApplyURI(uri),
)
if err != nil {
panic(err)
}
defer func() {
err = client.Disconnect(ctx)
if err != nil {
panic(err)
}
}()
err = client.Ping(ctx, nil)
if err != nil {
panic(err)
}
fmt.Println("pinged")
}
I tried the following, but all of them didn't work:
Encoding username and password using url.QueryEscape
Trying "localhost" instead of "127.0.0.1"
Removing "authMechanism=SCRAM-SHA-256" in uri
As a side note, connecting to the Mongo shell with the exact same uri, and that worked.
Add ssl=false to your uri. Worked for me
Based on MongoDB documentation for the authentication process, there is a parameter to identify which database is used for authentication besides the target database on the URI.
While in mongoshell you can use this line
mongo "mongodb://Admin:${DBPASSWORD}#<host>:<port>/admin?authSource=admin"
I used that information to add ?authSource=admin to my CONNECTION_URL
CONNECTION_URL=mongodb://root:example#mongo:27017/my_database?retryWrites=true&w=majority&authSource=admin
That worked for me. Hope it does for you too.
For detailed information please review https://www.mongodb.com/features/mongodb-authentication
You could try using 'options.Credential' to pass the authentication settings.
Seems like a cleaner way than formatting an URI that needs to be parsed later on.
https://docs.mongodb.com/drivers/go/current/fundamentals/auth/
clientOpts := options.Client().SetHosts(
[]string{"localhost:27017"},
).SetAuth(
options.Credential{
AuthSource: "<authenticationDb>",
AuthMechanism: "SCRAM-SHA-256",
Username: "<username>",
Password: "<password>",
}
)
client, err := mongo.Connect(context.TODO(), clientOpts)

Cannot connect to AWS RDS PostgreSQL with Golang using Helm Charts

I am unable to connect to AWS RDS PostgeSQL when running Helm Chart for a Go App (GORM). All credentials are stored in a kubernetes secret, and the secret is being used in the helm chart.
Few Points:
Able to connect locally just fine.
The PostgreSQL database is already created in RDS, and made sure that the kubernetes secret as matches with the same creds.
Docker image is pushed and pulled from Gitlab without any errors.
Command "helm ls" displays the deployment status as "DEPLOYED"
When taking "kubectl get pod", I get STATUS as "CrashLoopBackoff"
When taking "kubectl describe pod", I get back MESSAGE "Back-off restarting failed container"
I then take "kubectl logs pod_name" to track the error, and get back the following:
failed to connect to the database
dial tcp 127.0.0.1:5432: connect: connection refused
(Not sure why it is still specifying "127.0.0.1" when i have the secret mounted)
Unable to exec into the pod because it is not running.
I have tried:
Secure a connection in the same cluster from a different pod using psql to ensure that the creds in the secret are in sync with what was set up in RDS PostgreSQL
Changing the api from DB_HOST, to host=%s
Tried connecting using fmt.Sprintf, as well as os.Getenv
"Versions"
GO version:
go1.11.1 darwin/amd64
DOCKER version:
Client:
Version: 18.06.1-ce
API version: 1.38
API.GO (file)
package controllers
import (
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
_ "gitlab.torq.trans.apps.ge.com/503081542/torq-auth-api/models"
)
var err error
type API struct {
Database *gorm.DB
Router *mux.Router
}
func (api *API) Initialize(opts string) {
// Initialize DB
dbinfo := os.Getenv("DB_HOST, DB_USER, DB_PASSWORD, DB_NAME,
DB_PORT sslmode=disable")
// dbinfo := os.Getenv("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable")
api.Database, err = gorm.Open("postgres", dbinfo)
if err != nil {
log.Print("failed to connect to the database")
log.Fatal(err)
}
// Bind to a port and pass our router in
// log.Fatal(http.ListenAndServe(":8000", handlers.CORS() .
(api.Router)))
fmt.Println("Connection established")
log.Printf("Postgres started at %s PORT", config.DB_PORT)
// MODELS
type application struct {
ID string `json:"id" gorm:"primary_key"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
Name string `json:"name"`
Ci string `json:"ci"`
}
type Cloud struct {
ID string `json:"id" gorm:"primary_key"`
Name string `json:"name"`
}
fmt.Println("Tables are created")
// Enable this line for DB logging
api.Database.LogMode(true)}
// Initialize Router
api.Router = mux.NewRouter()
api.Router.HandleFunc("/api/v1/applications",
api.HandleApplications)
api.Router.HandleFunc("/api/v1/application/{id}",
api.HandleApplication)
api.Router.HandleFunc("/api/v1/clusters", api.handleClusters)
}
I am not exactly sure where the issue could be here, this is a learning experience for myself. Any ideas would be appreciated.
Thanks in advance!
I think your database initialization code is not doing what you want. Try something like this
var driver = "postgres"
var name = os.Getenv("DB_NAME")
var host = os.Getenv("DB_HOST")
var user = os.Getenv("DB_USER")
var pass = os.Getenv("DB_PASSWORD")
var conn = fmt.Sprintf("host=%v user=%v password=%v dbname=%v sslmode=disable", host, user, pass, name)
api.Database, err := gorm.Open(driver, conn)

server returned error on SASL authentication step: Authentication failed

The following is my MongoDB connection dial from GoLang. But it's returning a panic "server returned error on SASL authentication step: Authentication failed.". My username, password, hostAddrs and dbName are correct. What am I missing here?
dbName: = os.Getenv("ENV_DBNAME")
userName: = os.Getenv("ENV_DBUSER")
password: = os.Getenv("ENV_DBPASS")
dbHost: = os.Getenv("ENV_DBHOST")
mongoDialInfo: = & mgo.DialInfo {
Addrs: [] string {
dbHost
},
Database: dbName,
Username: userName,
Password: password,
Timeout: 60 * time.Second,
}
sess, err: = mgo.DialWithInfo(mongoDialInfo)
if (err != nil) {
panic(err)
}
I faced similar error and added --authenticationDatabase parameter and it worked while we connecting to a remote MongoDB
Use the similar below format in your code :
$mongorestore --host databasehost:98761 --username restoreuser
--password restorepwd --authenticationDatabase admin --db targetdb ./path/to/dump/
Often we confused with parameter in the mongoexport command with "Log-In" user.
The command expects "Database Username" not Log-in username.
This is one possibility to input wrong user name.
"Database Username" can be found in "Users" tab for a database
I got my answer from this link: https://newbiedba.wordpress.com/2016/11/21/mongodb-3-2-server-returned-error-on-sasl-authentication-step-authentication-failed/
Except for all answers above, the only unmentioned reason is that my password has a special character '$' in it. I think this is a very common practice to have special characters and this may trip many without this simple tip:
When using command line mongo/mongostat/etc.. Single quote your username or password that has special characters!
mgo returns this error if username, password or database are wrong. Check your credentials twice. There are no other situations when you can see Authentication failed error message.
The error you report seem the cause of the authentication fail is caused by a nil pointer, you should check the data before using them to create the connection
I got this error while using a connection string from a Heroku app by means of the --uri flag. What solved it in my case was adding the database name with -d:
mongodb_uri="$(heroku config:get MONGODB_URI -a myapp)"
mongorestore --uri=$mongodb_uri -d heroku_7m41q4xs db/
In my case specifying auth database and auth mechanism in uri did help
./mongoimport --uri="mongodb://root:root#localhost:27017/labelDb?authSource=admin&authMechanism=SCRAM-SHA-1" --collection=repo_item --file=/tmp/repo_item.json
I had the same error when using with dokku mongo:import . In my case I included dot(period) in my db name
You shouldn't include dot in your mongodb name when 'dokku mongo:create '
I've changed it to seunghunlee instead of seunghunlee.net
now this command works
dokku mongo:import seunghunlee < seunghunlee.net.dump.gz
Hope it helps!
In my case, I was missing both --authenticationDatabase & --ssl, so here goes the full syntax for importing a json file into a Mongodb collection over an Atlas cluster (into the primary shard):
./mongoimport --host mycluster-shard-00-02.d0b2r.mongodb.net:27017 --authenticationDatabase admin --username TestUser --db Test --collection Messages --type json --file RAW.json --ssl
If you are trying to connect your MongoDB Atlas to the Golang Application, the Connection function would be like this:
func getSession() *mgo.Session {
tlsConfig := &tls.Config{}
dialInfo := &mgo.DialInfo{
Addrs: []string{<add your MongoDB shards as string array> }
Username: "<MongoDB username>",
Password: "<MongoDB password",
}
dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
return conn, err
}
session, err := mgo.DialWithInfo(dialInfo)
if err != nil {
panic(err)
} else {
fmt.Printf("DB connected")
}
return session
}

Can't connect with Mlab database but I can to my local mongo with mgo golang

I am trying to connect to a mlab mongo database in my Golang application but I always get 'auth failed'.
If I use my local mongo, I have no problems (my local doesn't have authentication)
EDIT: I do have created a database user in mLab and I can log in with that user in RoboMongo
My database package looks like this:
package database
import (
"os"
"fmt"
"sync"
"labix.org/v2/mgo"
"time"
)
type DB struct {
Database *mgo.Database
}
const (
MongoDBHosts = "mlabHost:mlabPort"
AuthDatabase = "mydatabase"
AuthUserName = "mlabUser"
AuthPassword = "mlabPassword"
)
var _init_ctx sync.Once
var _instance *DB
func New() *mgo.Database {
_init_ctx.Do(func() {
_instance = new(DB)
mongoDBDialInfo := &mgo.DialInfo{
Addrs: []string{MongoDBHosts},
Timeout: 600 * time.Second,
Database: AuthDatabase,
Username: AuthUserName,
Password: AuthPassword,
}
// Create a session which maintains a pool of socket connections
// to our MongoDB.
session, err := mgo.DialWithInfo(mongoDBDialInfo)
if err != nil {
fmt.Printf("Error en mongo: %+v\n", err)
os.Exit(1)
}
_instance.Database = session.DB(AuthDatabase)
})
return _instance.Database
}
With that code, I always get 'auth failed', but if I change the const values to connect to my local like this:
const (
MongoDBHosts = "localhost:27017"
AuthDatabase = "mydatabase"
AuthUserName = ""
AuthPassword = ""
)
Everything is good.
I can even connect to my mLab database through RoboMongo, but one thing I noticed was that trying to connect from the command line like this:
mongo mLabHost:mLabPort/mydatabase -u mLabUser -p mLabPassword
The prompt asks again for the password and then I get (mypassword = mLabPassword I enter):
2016-06-25T16:07:10.822-0500 E - [main] file [mypassword] doesn't exist
failed to load: mypassword
I tried connecting to mLab in several different ways, but I can't find what is my problem.
Thanks
Found the problem
I was importing the wrong go module.
I had:
labix.org/v2/mgo
instead of:
gopkg.in/mgo.v2
After importing gopkg.in/mgo.v2 it made the connection

Connection refused with Go + Postgres on Heroku

I am trying to connect to Heroku's Postgres using a Go. All is working fine locally.
The error I am receiving on Heroku is dial tcp 127.0.0.1:5432: connection refused.
I've confirmed my ability to connect to the database via psql on heroku's command line, and have confirmed that the database url config is correct. The code is clear enough, so I wonder if there is a lower-level problem.
The code is straightforward enough:
import (
"database/sql"
"github.com/coopernurse/gorp"
_ "github.com/lib/pq"
"os"
)
func openDb() *sql.DB {
connection := os.Getenv("DATABASE_URL")
db, err := sql.Open("postgres", connection)
if err != nil {
log.Println(err)
}
return db
}
...and am importing github.com/lib/pq. Go version is 1.1.2.
Heroku + Go is pretty particular about the connection strings. The URL-style doesn't seem to allow specification of sslmode=require, which Heroku insists upon.
The modified version uses pq to parse the URL into a traditional Postgres connection string, and appends the parameter:
import (
"database/sql"
"github.com/lib/pq"
"os"
)
func openDb() *sql.DB {
url := os.Getenv("DATABASE_URL")
connection, _ := pq.ParseURL(url)
connection += " sslmode=require"
db, err := sql.Open("postgres", connection)
if err != nil {
log.Println(err)
}
return db
}