Repository: danvergara/dblab
Pull request #179 (2023-07-23 04:19:59)

Add support to read ssl connection params from the config file
# Support to read ssl connection params from the config file 

## Description

I didn't add the ssl conection params support to config file feature, so I did in this PR.


## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [x] This change requires a documentation update

## How Has This Been Tested?

I ran the test suite.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] I have checked my code and corrected any misspellings


Arturomtz8: Looks good to me!

Patch:
diff --git a/README.md b/README.md
index 9183c9b..36cb1cd 100644
--- a/README.md
+++ b/README.md
@@ -153,7 +153,7 @@ dblab --host  db-postgresql-nyc3-56456-do-user-foo-0.fake.db.ondigitalocean.com
 Enter previous flags every time is tedious, so `dblab` provides a couple of flags to help with it: `--config` and `--cfg-name`.
 
 `dblab` is going to look for a file called `.dblab.yaml`. For now, the only two places where you can drop a config file are $HOME ($HOME/.dblab.yaml) and the current directory where you run the command line tool.
-If you want to use this feature, `--config` is mandatory and `--cfg-name` may be omitted. The config file can store one or multiple database connection sections under the `database` field. `database` is an array, previously was an object only able to store a single connection section at a time. We strongly encourgae you to adopt the new format as of `v0.18.0`. `--cfg-name` takes the name of the desired database section to connect with. It can be omitted and its default values will be the first item on the array.
+If you want to use this feature, `--config` is mandatory and `--cfg-name` may be omitted. The config file can store one or multiple database connection sections under the `database` field. `database` is an array, previously was an object only able to store a single connection section at a time. We strongly encourgae you to adopt the new format as of `v0.18.0`. `--cfg-name` takes the name of the desired database section to connect with. It can be omitted and its default values will be the first item on the array. As of `v0.21.0`, ssl connections options are supported in the config file.
 
 ```sh
 # default: test
@@ -186,6 +186,8 @@ database:
     user: "postgres"
     schema: "public"
     driver: "postgres"
+    ssl: "require"
+    sslrootcert: "~/.postgresql/root.crt."
 # should be greater than 0, otherwise the app will error out
 limit: 50
 ```
diff --git a/docs/usage.md b/docs/usage.md
index 336e46e..275bd51 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -146,6 +146,8 @@ If you want to use this feature, `--config` is mandatory and `--cfg-name` may be
 
 We strongly encourgae you to adopt the new format as of `v0.18.0`. `--cfg-name` takes the name of the desired database section to connect with. It can be omitted and its default values will be the first item on the array.
 
+As of `v0.21.0`, ssl connections options are supported in the config file.
+
 ```{ .sh .copy } 
 dbladb --config
 ```
@@ -177,6 +179,8 @@ database:
     user: "postgres"
     schema: "public"
     driver: "postgres"
+    ssl: "require"
+    sslrootcert: "~/.postgresql/root.crt."
 # should be greater than 0, otherwise the app will error out
 limit: 50
 ```
diff --git a/pkg/config/.dblab.yaml b/pkg/config/.dblab.yaml
index a77e54e..febbdad 100644
--- a/pkg/config/.dblab.yaml
+++ b/pkg/config/.dblab.yaml
@@ -16,4 +16,6 @@ database:
     user: "postgres"
     schema: "public"
     driver: "postgres"
+    ssl: "require"
+    sslrootcert: "~/.postgresql/root.crt."
 limit: 50
diff --git a/pkg/config/config.go b/pkg/config/config.go
index cc6740c..c375d64 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -7,19 +7,17 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/danvergara/dblab/pkg/command"
-	"github.com/danvergara/dblab/pkg/drivers"
-	"github.com/kkyr/fig"
-	"github.com/spf13/cobra"
-
 	"github.com/golang-migrate/migrate/v4"
+	_ "github.com/golang-migrate/migrate/v4/database/mysql"    // mysql driver
+	_ "github.com/golang-migrate/migrate/v4/database/postgres" // postgres driver
 	"github.com/golang-migrate/migrate/v4/database/sqlite3"
 	"github.com/golang-migrate/migrate/v4/source/file"
+	"github.com/kkyr/fig"
+	"github.com/spf13/cobra"
+	_ "modernc.org/sqlite" // sqlite driver
 
-	// drivers.
-	_ "github.com/golang-migrate/migrate/v4/database/mysql"
-	_ "github.com/golang-migrate/migrate/v4/database/postgres"
-	_ "modernc.org/sqlite"
+	"github.com/danvergara/dblab/pkg/command"
+	"github.com/danvergara/dblab/pkg/drivers"
 )
 
 // Config struct is used to store the db connection data.
@@ -43,7 +41,12 @@ type Database struct {
 	Password string
 	Driver   string `validate:"required"`
 	Schema   string
-	SSL      string `default:"disable"`
+	// SSL connection params.
+	SSL         string `default:"disable"`
+	SSLCert     string `fig:"sslcert"`
+	SSLKey      string `fig:"sslkey"`
+	SSLPassword string `fig:"sslpassword"`
+	SSLRootcert string `fig:"sslrootcert"`
 }
 
 // New returns a config instance the with db connection data inplace based on the flags of a cobra command.
@@ -90,15 +93,19 @@ func Init(configName string) (command.Options, error) {
 	}
 
 	opts = command.Options{
-		Driver: db.Driver,
-		Host:   db.Host,
-		Port:   db.Port,
-		User:   db.User,
-		Pass:   db.Password,
-		DBName: db.DB,
-		SSL:    db.SSL,
-		Schema: db.Schema,
-		Limit:  cfg.Limit,
+		Driver:      db.Driver,
+		Host:        db.Host,
+		Port:        db.Port,
+		User:        db.User,
+		Pass:        db.Password,
+		DBName:      db.DB,
+		Schema:      db.Schema,
+		Limit:       cfg.Limit,
+		SSL:         db.SSL,
+		SSLCert:     db.SSLCert,
+		SSLKey:      db.SSLKey,
+		SSLPassword: db.SSLPassword,
+		SSLRootcert: db.SSLRootcert,
 	}
 
 	return opts, nil
@@ -183,9 +190,25 @@ func (c *Config) GetSQLXDBConnStr() string {
 func (c *Config) getDBConnStr(dbhost, dbname string) string {
 	switch c.Driver {
 	case drivers.Postgres:
-		return fmt.Sprintf("%s://%s:%s@%s:%s/%s?sslmode=disable", c.Driver, c.User, c.Pswd, dbhost, c.Port, dbname)
+		return fmt.Sprintf(
+			"%s://%s:%s@%s:%s/%s?sslmode=disable",
+			c.Driver,
+			c.User,
+			c.Pswd,
+			dbhost,
+			c.Port,
+			dbname,
+		)
 	case drivers.MySQL:
-		return fmt.Sprintf("%s://%s:%s@tcp(%s:%s)/%s", c.Driver, c.User, c.Pswd, dbhost, c.Port, dbname)
+		return fmt.Sprintf(
+			"%s://%s:%s@tcp(%s:%s)/%s",
+			c.Driver,
+			c.User,
+			c.Pswd,
+			dbhost,
+			c.Port,
+			dbname,
+		)
 	case drivers.SQLite:
 		return c.DBName
 	default:
@@ -197,7 +220,15 @@ func (c *Config) getDBConnStr(dbhost, dbname string) string {
 func (c *Config) getSQLXConnStr(dbhost, dbname string) string {
 	switch c.Driver {
 	case drivers.Postgres:
-		return fmt.Sprintf("%s://%s:%s@%s:%s/%s?sslmode=disable", c.Driver, c.User, c.Pswd, dbhost, c.Port, dbname)
+		return fmt.Sprintf(
+			"%s://%s:%s@%s:%s/%s?sslmode=disable",
+			c.Driver,
+			c.User,
+			c.Pswd,
+			dbhost,
+			c.Port,
+			dbname,
+		)
 	case drivers.MySQL:
 		return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", c.User, c.Pswd, dbhost, c.Port, dbname)
 	case drivers.SQLite:


Test patch:
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index cb83a31..9995871 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -3,20 +3,26 @@ package config_test
 import (
 	"testing"
 
-	"github.com/danvergara/dblab/pkg/config"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/danvergara/dblab/pkg/config"
 )
 
 func TestInit(t *testing.T) {
 	type want struct {
-		host   string
-		port   string
-		dbname string
-		user   string
-		pass   string
-		driver string
-		schema string
-		limit  uint
+		host        string
+		port        string
+		dbname      string
+		user        string
+		pass        string
+		driver      string
+		schema      string
+		limit       uint
+		ssl         string
+		sslcert     string
+		sslkey      string
+		sslpassword string
+		sslrootcert string
 	}
 	var tests = []struct {
 		name  string
@@ -34,6 +40,7 @@ func TestInit(t *testing.T) {
 				pass:   "password",
 				driver: "postgres",
 				schema: "public",
+				ssl:    "disable",
 				limit:  50,
 			},
 		},
@@ -48,6 +55,7 @@ func TestInit(t *testing.T) {
 				pass:   "password",
 				driver: "postgres",
 				schema: "public",
+				ssl:    "disable",
 				limit:  50,
 			},
 		},
@@ -55,14 +63,16 @@ func TestInit(t *testing.T) {
 			name:  "production config",
 			input: "prod",
 			want: want{
-				host:   "mydb.123456789012.us-east-1.rds.amazonaws.com",
-				port:   "5432",
-				dbname: "users",
-				user:   "postgres",
-				pass:   "password",
-				driver: "postgres",
-				schema: "public",
-				limit:  50,
+				host:        "mydb.123456789012.us-east-1.rds.amazonaws.com",
+				port:        "5432",
+				dbname:      "users",
+				user:        "postgres",
+				pass:        "password",
+				driver:      "postgres",
+				schema:      "public",
+				ssl:         "require",
+				sslrootcert: "~/.postgresql/root.crt.",
+				limit:       50,
 			},
 		},
 	}
@@ -80,6 +90,12 @@ func TestInit(t *testing.T) {
 			assert.Equal(t, tt.want.driver, opts.Driver)
 			assert.Equal(t, tt.want.schema, opts.Schema)
 			assert.Equal(t, tt.want.limit, opts.Limit)
+			assert.Equal(t, tt.want.ssl, opts.SSL)
+			assert.Equal(t, tt.want.sslcert, opts.SSLCert)
+			assert.Equal(t, tt.want.sslkey, opts.SSLKey)
+			assert.Equal(t, tt.want.sslpassword, opts.SSLPassword)
+			assert.Equal(t, tt.want.sslrootcert, opts.SSLRootcert)
+
 		})
 	}
 }