aboutsummaryrefslogtreecommitdiff
path: root/server/store
diff options
context:
space:
mode:
authorNiall Sheridan <nsheridan@gmail.com>2016-10-08 00:57:10 -0500
committerNiall Sheridan <nsheridan@gmail.com>2016-10-11 16:54:47 -0500
commitd6d54ed0bcf3b583fe681db790740cef137401d3 (patch)
tree2da8de7005c14706f83edc8a58360fa435425c92 /server/store
parentbaf7141d1dd0f99d561a2197a909c66dd389809d (diff)
Replace the 'datastore' option with a 'database' option
The 'datastore' string option is deprecated and will be removed in a future version. The new 'database' map option is preferred.
Diffstat (limited to 'server/store')
-rw-r--r--server/store/config_test.go70
-rw-r--r--server/store/mongo.go26
-rw-r--r--server/store/sqldb.go52
-rw-r--r--server/store/store.go14
-rw-r--r--server/store/store_test.go24
5 files changed, 66 insertions, 120 deletions
diff --git a/server/store/config_test.go b/server/store/config_test.go
deleted file mode 100644
index 9a77027..0000000
--- a/server/store/config_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package store
-
-import (
- "reflect"
- "testing"
- "time"
-
- mgo "gopkg.in/mgo.v2"
-)
-
-func TestMySQLConfig(t *testing.T) {
- t.Parallel()
- var tests = []struct {
- in string
- out []string
- }{
- {"mysql:user:passwd:localhost", []string{"mysql", "user:passwd@tcp(localhost:3306)/certs?parseTime=true"}},
- {"mysql:user:passwd:localhost:13306", []string{"mysql", "user:passwd@tcp(localhost:13306)/certs?parseTime=true"}},
- {"mysql:root::localhost", []string{"mysql", "root@tcp(localhost:3306)/certs?parseTime=true"}},
- }
- for _, tt := range tests {
- result := parse(tt.in)
- if !reflect.DeepEqual(result, tt.out) {
- t.Errorf("want %s, got %s", tt.out, result)
- }
- }
-}
-
-func TestMongoConfig(t *testing.T) {
- t.Parallel()
- var tests = []struct {
- in string
- out *mgo.DialInfo
- }{
- {"mongo:user:passwd:host", &mgo.DialInfo{
- Username: "user",
- Password: "passwd",
- Addrs: []string{"host"},
- Database: "certs",
- Timeout: 5 * time.Second,
- }},
- {"mongo:user:passwd:host1,host2", &mgo.DialInfo{
- Username: "user",
- Password: "passwd",
- Addrs: []string{"host1", "host2"},
- Database: "certs",
- Timeout: 5 * time.Second,
- }},
- {"mongo:user:passwd:host1:27017,host2:27017", &mgo.DialInfo{
- Username: "user",
- Password: "passwd",
- Addrs: []string{"host1:27017", "host2:27017"},
- Database: "certs",
- Timeout: 5 * time.Second,
- }},
- {"mongo:user:passwd:host1,host2:27017", &mgo.DialInfo{
- Username: "user",
- Password: "passwd",
- Addrs: []string{"host1", "host2:27017"},
- Database: "certs",
- Timeout: 5 * time.Second,
- }},
- }
- for _, tt := range tests {
- result := parseMongoConfig(tt.in)
- if !reflect.DeepEqual(result, tt.out) {
- t.Errorf("want:\n%+v\ngot:\n%+v", tt.out, result)
- }
- }
-}
diff --git a/server/store/mongo.go b/server/store/mongo.go
index 1b13d7a..fc4131f 100644
--- a/server/store/mongo.go
+++ b/server/store/mongo.go
@@ -4,6 +4,8 @@ import (
"strings"
"time"
+ "github.com/nsheridan/cashier/server/config"
+
"golang.org/x/crypto/ssh"
mgo "gopkg.in/mgo.v2"
@@ -15,26 +17,20 @@ var (
issuedTable = "issued_certs"
)
-func parseMongoConfig(config string) *mgo.DialInfo {
- s := strings.SplitN(config, ":", 4)
- _, user, passwd, hosts := s[0], s[1], s[2], s[3]
- d := &mgo.DialInfo{
- Addrs: strings.Split(hosts, ","),
- Username: user,
- Password: passwd,
- Database: certsDB,
- Timeout: time.Second * 5,
- }
- return d
-}
-
func collection(session *mgo.Session) *mgo.Collection {
return session.DB(certsDB).C(issuedTable)
}
// NewMongoStore returns a MongoDB CertStorer.
-func NewMongoStore(config string) (CertStorer, error) {
- session, err := mgo.DialWithInfo(parseMongoConfig(config))
+func NewMongoStore(c config.Database) (CertStorer, error) {
+ m := &mgo.DialInfo{
+ Addrs: strings.Split(c["address"], ","),
+ Username: c["username"],
+ Password: c["password"],
+ Database: certsDB,
+ Timeout: time.Second * 5,
+ }
+ session, err := mgo.DialWithInfo(m)
if err != nil {
return nil, err
}
diff --git a/server/store/sqldb.go b/server/store/sqldb.go
index f65f601..6c1be0e 100644
--- a/server/store/sqldb.go
+++ b/server/store/sqldb.go
@@ -4,13 +4,14 @@ import (
"database/sql"
"encoding/json"
"fmt"
- "strings"
+ "net"
"time"
"golang.org/x/crypto/ssh"
"github.com/go-sql-driver/mysql"
_ "github.com/mattn/go-sqlite3" // required by sql driver
+ "github.com/nsheridan/cashier/server/config"
)
type sqldb struct {
@@ -24,31 +25,32 @@ type sqldb struct {
revoked *sql.Stmt
}
-func parse(config string) []string {
- s := strings.Split(config, ":")
- if s[0] == "sqlite" {
- s[0] = "sqlite3"
- return s
- }
- if len(s) == 4 {
- s = append(s, "3306")
- }
- _, user, passwd, host, port := s[0], s[1], s[2], s[3], s[4]
- c := &mysql.Config{
- User: user,
- Passwd: passwd,
- Net: "tcp",
- Addr: fmt.Sprintf("%s:%s", host, port),
- DBName: "certs",
- ParseTime: true,
- }
- return []string{"mysql", c.FormatDSN()}
-}
-
// NewSQLStore returns a *sql.DB CertStorer.
-func NewSQLStore(config string) (CertStorer, error) {
- parsed := parse(config)
- conn, err := sql.Open(parsed[0], parsed[1])
+func NewSQLStore(c config.Database) (CertStorer, error) {
+ var driver string
+ var dsn string
+ switch c["type"] {
+ case "mysql":
+ driver = "mysql"
+ address := c["address"]
+ _, _, err := net.SplitHostPort(address)
+ if err != nil {
+ address = address + ":3306"
+ }
+ m := &mysql.Config{
+ User: c["username"],
+ Passwd: c["password"],
+ Net: "tcp",
+ Addr: address,
+ DBName: "certs",
+ ParseTime: true,
+ }
+ dsn = m.FormatDSN()
+ case "sqlite":
+ driver = "sqlite3"
+ dsn = c["filename"]
+ }
+ conn, err := sql.Open(driver, dsn)
if err != nil {
return nil, fmt.Errorf("sqldb: could not get a connection: %v", err)
}
diff --git a/server/store/store.go b/server/store/store.go
index c039d3c..a447e72 100644
--- a/server/store/store.go
+++ b/server/store/store.go
@@ -5,9 +5,23 @@ import (
"golang.org/x/crypto/ssh"
+ "github.com/nsheridan/cashier/server/config"
"github.com/nsheridan/cashier/server/util"
)
+// New returns a new configured database.
+func New(c config.Database) (CertStorer, error) {
+ switch c["type"] {
+ case "mongo":
+ return NewMongoStore(c)
+ case "mysql", "sqlite":
+ return NewSQLStore(c)
+ case "mem":
+ return NewMemoryStore(), nil
+ }
+ return NewMemoryStore(), nil
+}
+
// CertStorer records issued certs in a persistent store for audit and
// revocation purposes.
type CertStorer interface {
diff --git a/server/store/store_test.go b/server/store/store_test.go
index 594da37..dbe2d95 100644
--- a/server/store/store_test.go
+++ b/server/store/store_test.go
@@ -3,7 +3,6 @@ package store
import (
"crypto/rand"
"crypto/rsa"
- "fmt"
"io/ioutil"
"os"
"os/exec"
@@ -16,6 +15,10 @@ import (
"golang.org/x/crypto/ssh"
)
+var (
+ dbConfig = map[string]string{"username": "user", "password": "passwd", "address": "localhost"}
+)
+
func TestParseCertificate(t *testing.T) {
t.Parallel()
a := assert.New(t)
@@ -87,11 +90,11 @@ func TestMemoryStore(t *testing.T) {
func TestMySQLStore(t *testing.T) {
t.Parallel()
- config := os.Getenv("MYSQL_TEST_CONFIG")
- if config == "" {
- t.Skip("No MYSQL_TEST_CONFIG environment variable")
+ if os.Getenv("MYSQL_TEST") == "" {
+ t.Skip("No MYSQL_TEST environment variable")
}
- db, err := NewSQLStore(config)
+ dbConfig["type"] = "mysql"
+ db, err := NewSQLStore(dbConfig)
if err != nil {
t.Error(err)
}
@@ -100,11 +103,11 @@ func TestMySQLStore(t *testing.T) {
func TestMongoStore(t *testing.T) {
t.Parallel()
- config := os.Getenv("MONGO_TEST_CONFIG")
- if config == "" {
- t.Skip("No MONGO_TEST_CONFIG environment variable")
+ if os.Getenv("MONGO_TEST") == "" {
+ t.Skip("No MONGO_TEST environment variable")
}
- db, err := NewMongoStore(config)
+ dbConfig["type"] = "mongo"
+ db, err := NewMongoStore(dbConfig)
if err != nil {
t.Error(err)
}
@@ -123,7 +126,8 @@ func TestSQLiteStore(t *testing.T) {
if err := exec.Command("go", args...).Run(); err != nil {
t.Error(err)
}
- db, err := NewSQLStore(fmt.Sprintf("sqlite:%s", f.Name()))
+ config := map[string]string{"type": "sqlite", "filename": f.Name()}
+ db, err := NewSQLStore(config)
if err != nil {
t.Error(err)
}