Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue-189 : Allow connecting to bookmarked server from CLI #201

Merged
merged 8 commits into from Nov 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/bookmark.toml
@@ -1,5 +1,5 @@
host = "localhost"
port = "5432"
port = 5432
user = "postgres"
database = "mydatabase"
ssl = "disable"
5 changes: 0 additions & 5 deletions data/invalid_port.toml

This file was deleted.

41 changes: 37 additions & 4 deletions main.go
Expand Up @@ -10,9 +10,11 @@ import (
"github.com/jessevdk/go-flags"

"github.com/sosedoff/pgweb/pkg/api"
"github.com/sosedoff/pgweb/pkg/bookmarks"
"github.com/sosedoff/pgweb/pkg/client"
"github.com/sosedoff/pgweb/pkg/command"
"github.com/sosedoff/pgweb/pkg/connection"
"github.com/sosedoff/pgweb/pkg/shared"
"github.com/sosedoff/pgweb/pkg/util"
)

Expand All @@ -23,14 +25,45 @@ func exitWithMessage(message string) {
os.Exit(1)
}

func initClientUsingBookmark(bookmarkPath, bookmarkName string) (*client.Client, error) {
bookmark, err := bookmarks.GetBookmark(bookmarkPath, bookmarkName)
if err != nil {
return nil, err
}
opt := bookmark.ConvertToOptions()
var connStr string
if opt.Url != "" { // if the bookmark has url set, use it
connStr = opt.Url
} else {
connStr, err = connection.BuildString(opt)
if err != nil {
return nil, fmt.Errorf("error building connection string: %v", err)
}
}
var ssh *shared.SSHInfo
if !bookmark.SSHInfoIsEmpty() {
ssh = &bookmark.Ssh
}
return client.NewFromUrl(connStr, ssh)
}

func initClient() {
if connection.IsBlank(command.Opts) {
if connection.IsBlank(command.Opts) && options.Bookmark == "" {
return
}

cl, err := client.New()
if err != nil {
exitWithMessage(err.Error())
var cl *client.Client
var err error
if options.Bookmark != "" {
cl, err = initClientUsingBookmark(bookmarks.Path(), options.Bookmark)
if err != nil {
exitWithMessage(err.Error())
}
} else {
cl, err = client.New()
if err != nil {
exitWithMessage(err.Error())
}
}

if command.Opts.Debug {
Expand Down
32 changes: 31 additions & 1 deletion pkg/bookmarks/bookmarks.go
Expand Up @@ -9,20 +9,37 @@ import (
"github.com/BurntSushi/toml"
"github.com/mitchellh/go-homedir"

"github.com/sosedoff/pgweb/pkg/command"
"github.com/sosedoff/pgweb/pkg/shared"
)

type Bookmark struct {
Url string `json:"url"` // Postgres connection URL
Host string `json:"host"` // Server hostname
Port string `json:"port"` // Server port
Port int `json:"port"` // Server port
User string `json:"user"` // Database user
Password string `json:"password"` // User password
Database string `json:"database"` // Database name
Ssl string `json:"ssl"` // Connection SSL mode
Ssh shared.SSHInfo `json:"ssh"` // SSH tunnel config
}

func (b Bookmark) SSHInfoIsEmpty() bool {
return b.Ssh.User == "" && b.Ssh.Host == "" && b.Ssh.Port == ""
}

func (b Bookmark) ConvertToOptions() command.Options {
return command.Options{
Url: b.Url,
Host: b.Host,
Port: b.Port,
User: b.User,
Pass: b.Password,
DbName: b.Database,
Ssl: b.Ssl,
}
}

func readServerConfig(path string) (Bookmark, error) {
bookmark := Bookmark{}

Expand Down Expand Up @@ -72,3 +89,16 @@ func ReadAll(path string) (map[string]Bookmark, error) {

return results, nil
}

func GetBookmark(bookmarkPath string, bookmarkName string) (Bookmark, error) {
bookmarks, err := ReadAll(bookmarkPath)
if err != nil {
return Bookmark{}, err
}
bookmark, ok := bookmarks[bookmarkName]
if !ok {
return Bookmark{}, fmt.Errorf("couldn't find a bookmark with name %s", bookmarkName)
}
return bookmark, nil

}
76 changes: 70 additions & 6 deletions pkg/bookmarks/bookmarks_test.go
Expand Up @@ -3,6 +3,8 @@ package bookmarks
import (
"testing"

"github.com/sosedoff/pgweb/pkg/command"
"github.com/sosedoff/pgweb/pkg/shared"
"github.com/stretchr/testify/assert"
)

Expand All @@ -13,18 +15,14 @@ func Test_Invalid_Bookmark_Files(t *testing.T) {
_, err = readServerConfig("../../data/invalid.toml")
assert.Error(t, err)
assert.Equal(t, "Near line 1, key 'invalid encoding': Near line 2: Expected key separator '=', but got '\\n' instead.", err.Error())

_, err = readServerConfig("../../data/invalid_port.toml")
assert.Error(t, err)
assert.Equal(t, "Type mismatch for 'bookmarks.Bookmark.Port': Expected string but found 'int64'.", err.Error())
}

func Test_Bookmark(t *testing.T) {
bookmark, err := readServerConfig("../../data/bookmark.toml")

assert.Equal(t, nil, err)
assert.Equal(t, "localhost", bookmark.Host)
assert.Equal(t, "5432", bookmark.Port)
assert.Equal(t, 5432, bookmark.Port)
assert.Equal(t, "postgres", bookmark.User)
assert.Equal(t, "mydatabase", bookmark.Database)
assert.Equal(t, "disable", bookmark.Ssl)
Expand All @@ -38,7 +36,7 @@ func Test_Bookmark_URL(t *testing.T) {
assert.Equal(t, nil, err)
assert.Equal(t, "postgres://username:password@host:port/database?sslmode=disable", bookmark.Url)
assert.Equal(t, "", bookmark.Host)
assert.Equal(t, "", bookmark.Port)
assert.Equal(t, 0, bookmark.Port)
assert.Equal(t, "", bookmark.User)
assert.Equal(t, "", bookmark.Database)
assert.Equal(t, "", bookmark.Ssl)
Expand Down Expand Up @@ -69,3 +67,69 @@ func Test_ReadBookmarks(t *testing.T) {
assert.Equal(t, nil, err)
assert.Equal(t, 2, len(bookmarks))
}

func Test_GetBookmark(t *testing.T) {
expBookmark := Bookmark{

Host: "localhost",
Port: 5432,
User: "postgres",
Password: "",
Database: "mydatabase",
Ssl: "disable",
}
b, err := GetBookmark("../../data", "bookmark")
if assert.NoError(t, err) {
assert.Equal(t, expBookmark, b)
}

_, err = GetBookmark("../../data", "bar")
expErrStr := "couldn't find a bookmark with name bar"
assert.Equal(t, expErrStr, err.Error())

_, err = GetBookmark("foo", "bookmark")
assert.Error(t, err)
}

func Test_Bookmark_SSHInfoIsEmpty(t *testing.T) {
emptySSH := shared.SSHInfo{
Host: "",
Port: "",
User: "",
}
populatedSSH := shared.SSHInfo{
Host: "localhost",
Port: "8080",
User: "postgres",
}

b := Bookmark{Ssh: emptySSH}
assert.True(t, b.SSHInfoIsEmpty())

b.Ssh = populatedSSH
assert.False(t, b.SSHInfoIsEmpty())
}

func Test_ConvertToOptions(t *testing.T) {
b := Bookmark{
Url: "postgres://username:password@host:port/database?sslmode=disable",
Host: "localhost",
Port: 5432,
User: "postgres",
Password: "password",
Database: "mydatabase",
Ssl: "disable",
}

expOpt := command.Options{
Url: "postgres://username:password@host:port/database?sslmode=disable",
Host: "localhost",
Port: 5432,
User: "postgres",
Pass: "password",
DbName: "mydatabase",
Ssl: "disable",
}
opt := b.ConvertToOptions()
assert.Equal(t, expOpt, opt)
}
1 change: 1 addition & 0 deletions pkg/command/options.go
Expand Up @@ -27,6 +27,7 @@ type Options struct {
Prefix string `long:"prefix" description:"Add a url prefix"`
ReadOnly bool `long:"readonly" description:"Run database connection in readonly mode"`
LockSession bool `long:"lock-session" description:"Lock session to a single database connection" default:"false"`
Bookmark string `short:"b" long:"bookmark" description:"Bookmark to use for connection. Bookmark files are stored under $HOME/.pgweb/bookmarks/*.toml" default:""`
}

var Opts Options
Expand Down
427 changes: 176 additions & 251 deletions pkg/data/bindata.go

Large diffs are not rendered by default.