Update nosql integration

* shutdown and reload database on SIGHUP
This commit is contained in:
max furman 2019-04-24 17:42:14 -07:00
parent b4137053cf
commit cbeca9383b
4 changed files with 120 additions and 41 deletions

88
Gopkg.lock generated
View file

@ -1,6 +1,14 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
digest = "1:6716c9fe6333591128e72848f246fc01dc72240e1e64185d8b4e124e7280b35d"
name = "github.com/AndreasBriese/bbloom"
packages = ["."]
pruneopts = "UT"
revision = "e2d15f34fcf99d5dbb871c820ec73f710fca9815"
[[projects]] [[projects]]
digest = "1:304cb78c285eaf02ab529ad02a257cad9b4845022915e6c82f87860ac53222d8" digest = "1:304cb78c285eaf02ab529ad02a257cad9b4845022915e6c82f87860ac53222d8"
name = "github.com/alecthomas/gometalinter" name = "github.com/alecthomas/gometalinter"
@ -35,6 +43,29 @@
revision = "b90dc15cfd220ecf8bbc9043ecb928cef381f011" revision = "b90dc15cfd220ecf8bbc9043ecb928cef381f011"
version = "v0.3.4" version = "v0.3.4"
[[projects]]
digest = "1:21ac9938fb1098b3a7b0dd909fb30878d33231177fac11a2821114eb9c1088ff"
name = "github.com/dgraph-io/badger"
packages = [
".",
"options",
"protos",
"skl",
"table",
"y",
]
pruneopts = "UT"
revision = "391b6d3b93e6014fe8c2971fcc0c1266e47dbbd9"
version = "v1.5.3"
[[projects]]
branch = "master"
digest = "1:6e8109ce247a59ab1eeb5330166c12735f6590de99c9647b6162d11518d32c9a"
name = "github.com/dgryski/go-farm"
packages = ["."]
pruneopts = "UT"
revision = "6a90982ecee230ff6cba02d5bd386acc030be9d3"
[[projects]] [[projects]]
digest = "1:2cd7915ab26ede7d95b8749e6b1f933f1c6d5398030684e6505940a10f31cfda" digest = "1:2cd7915ab26ede7d95b8749e6b1f933f1c6d5398030684e6505940a10f31cfda"
name = "github.com/ghodss/yaml" name = "github.com/ghodss/yaml"
@ -51,6 +82,14 @@
pruneopts = "UT" pruneopts = "UT"
revision = "0ebf7795c516423a110473652e9ba3a59a504863" revision = "0ebf7795c516423a110473652e9ba3a59a504863"
[[projects]]
digest = "1:ec6f9bf5e274c833c911923c9193867f3f18788c461f76f05f62bb1510e0ae65"
name = "github.com/go-sql-driver/mysql"
packages = ["."]
pruneopts = "UT"
revision = "72cd26f257d44c1114970e19afddcd812016007e"
version = "v1.4.1"
[[projects]] [[projects]]
digest = "1:b402bb9a24d108a9405a6f34675091b036c8b056aac843bf6ef2389a65c5cf48" digest = "1:b402bb9a24d108a9405a6f34675091b036c8b056aac843bf6ef2389a65c5cf48"
name = "github.com/gogo/protobuf" name = "github.com/gogo/protobuf"
@ -174,6 +213,28 @@
revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
version = "v0.0.4" version = "v0.0.4"
[[projects]]
branch = "master"
digest = "1:ae08d850ba158ea3ba4a7bb90f8372608172d8920644e5a6693b940a1f4e5d01"
name = "github.com/mmcloughlin/avo"
packages = [
"attr",
"build",
"buildtags",
"gotypes",
"internal/prnt",
"internal/stack",
"ir",
"operand",
"pass",
"printer",
"reg",
"src",
"x86",
]
pruneopts = "UT"
revision = "2e7d06bc7ada2979f17ccf8ebf486dba23b84fc7"
[[projects]] [[projects]]
digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563" digest = "1:33422d238f147d247752996a26574ac48dcf472976eda7f5134015f06bf16563"
name = "github.com/modern-go/concurrent" name = "github.com/modern-go/concurrent"
@ -302,11 +363,17 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:fd8d9eb07509d8ef47fc82c99646f0b2203b2ba3c240ba77d8c457bb6109836d" digest = "1:f1f1df1e19d55a1ef1f0a63633191e7d2a99993c0a17f945c0b9ebd16b17871b"
name = "github.com/smallstep/nosql" name = "github.com/smallstep/nosql"
packages = ["."] packages = [
".",
"badger",
"bolt",
"database",
"mysql",
]
pruneopts = "UT" pruneopts = "UT"
revision = "d8f68d14f9ae04e0991dce06b44768f2d38dccf8" revision = "5a355c598075a346d9ca9b50ec10e3f86ac66148"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -402,17 +469,30 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:384310e8a567edf6d5406d93318f9460c2d8db1a07ff5b6fece95b224343e7f1" digest = "1:6b4a1c844969280f4d3e36ef4b0762e3522e701c015f688b68ef91c2ea6b5ac7"
name = "golang.org/x/tools" name = "golang.org/x/tools"
packages = [ packages = [
"go/ast/astutil", "go/ast/astutil",
"go/gcexportdata", "go/gcexportdata",
"go/internal/cgo",
"go/internal/gcimporter", "go/internal/gcimporter",
"go/packages",
"go/types/typeutil", "go/types/typeutil",
"internal/fastwalk",
"internal/gopathwalk",
"internal/semver",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "3a10b9bf0a52df7e992a8c3eb712a86d3c896c75" revision = "3a10b9bf0a52df7e992a8c3eb712a86d3c896c75"
[[projects]]
digest = "1:c25289f43ac4a68d88b02245742347c94f1e108c534dda442188015ff80669b3"
name = "google.golang.org/appengine"
packages = ["cloudsql"]
pruneopts = "UT"
revision = "54a98f90d1c46b7731eb8fb305d2a321c30ef610"
version = "v1.5.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c" digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c"

View file

@ -131,6 +131,9 @@ func (ca *CA) Stop() error {
// Reload reloads the configuration of the CA and calls to the server Reload // Reload reloads the configuration of the CA and calls to the server Reload
// method. // method.
func (ca *CA) Reload() error { func (ca *CA) Reload() error {
if err := ca.auth.Shutdown(); err != nil {
return err
}
if ca.opts.configFile == "" { if ca.opts.configFile == "" {
return errors.New("error reloading ca: configuration file is not set") return errors.New("error reloading ca: configuration file is not set")
} }

View file

@ -3,7 +3,6 @@ package db
import ( import (
"crypto/x509" "crypto/x509"
"encoding/json" "encoding/json"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -21,8 +20,10 @@ var ErrAlreadyExists = errors.New("already exists")
// Config represents the JSON attributes used for configuring a step-ca DB. // Config represents the JSON attributes used for configuring a step-ca DB.
type Config struct { type Config struct {
Type string `json:"type"` Type string `json:"type"`
Path string `json:"path"` DataSource string `json:"dataSource"`
ValueDir string `json:"valueDir"`
Database string `json:"database"`
} }
// AuthDB is an interface over an Authority DB client that implements a nosql.DB interface. // AuthDB is an interface over an Authority DB client that implements a nosql.DB interface.
@ -44,15 +45,10 @@ func New(c *Config) (AuthDB, error) {
return new(NoopDB), nil return new(NoopDB), nil
} }
var db nosql.DB db, err := nosql.New(c.Type, c.DataSource, nosql.WithDatabase(c.Database),
switch strings.ToLower(c.Type) { nosql.WithValueDir(c.ValueDir))
case "bbolt": if err != nil {
db = &nosql.BoltDB{} return nil, errors.Wrapf(err, "Error opening database of Type %s with source %s", c.Type, c.DataSource)
if err := db.Open(c.Path); err != nil {
return nil, err
}
default:
return nil, errors.Errorf("unsupported db.type '%s'", c.Type)
} }
tables := [][]byte{revokedCertsTable, certsTable} tables := [][]byte{revokedCertsTable, certsTable}

View file

@ -5,24 +5,24 @@ import (
"testing" "testing"
"github.com/smallstep/assert" "github.com/smallstep/assert"
"github.com/smallstep/nosql" "github.com/smallstep/nosql/database"
) )
type MockNoSQLDB struct { type MockdatabaseDB struct {
err error err error
ret1, ret2 interface{} ret1, ret2 interface{}
get func(bucket, key []byte) ([]byte, error) get func(bucket, key []byte) ([]byte, error)
set func(bucket, key, value []byte) error set func(bucket, key, value []byte) error
open func(path string) error open func(dataSourceName string, opt ...database.Option) error
close func() error close func() error
createTable func(bucket []byte) error createTable func(bucket []byte) error
deleteTable func(bucket []byte) error deleteTable func(bucket []byte) error
del func(bucket, key []byte) error del func(bucket, key []byte) error
list func(bucket []byte) ([]*nosql.Entry, error) list func(bucket []byte) ([]*database.Entry, error)
update func(tx *nosql.Tx) error update func(tx *database.Tx) error
} }
func (m *MockNoSQLDB) Get(bucket, key []byte) ([]byte, error) { func (m *MockdatabaseDB) Get(bucket, key []byte) ([]byte, error) {
if m.get != nil { if m.get != nil {
return m.get(bucket, key) return m.get(bucket, key)
} }
@ -32,56 +32,56 @@ func (m *MockNoSQLDB) Get(bucket, key []byte) ([]byte, error) {
return m.ret1.([]byte), m.err return m.ret1.([]byte), m.err
} }
func (m *MockNoSQLDB) Set(bucket, key, value []byte) error { func (m *MockdatabaseDB) Set(bucket, key, value []byte) error {
if m.set != nil { if m.set != nil {
return m.set(bucket, key, value) return m.set(bucket, key, value)
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) Open(path string) error { func (m *MockdatabaseDB) Open(dataSourceName string, opt ...database.Option) error {
if m.open != nil { if m.open != nil {
return m.open(path) return m.open(dataSourceName, opt...)
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) Close() error { func (m *MockdatabaseDB) Close() error {
if m.close != nil { if m.close != nil {
return m.close() return m.close()
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) CreateTable(bucket []byte) error { func (m *MockdatabaseDB) CreateTable(bucket []byte) error {
if m.createTable != nil { if m.createTable != nil {
return m.createTable(bucket) return m.createTable(bucket)
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) DeleteTable(bucket []byte) error { func (m *MockdatabaseDB) DeleteTable(bucket []byte) error {
if m.deleteTable != nil { if m.deleteTable != nil {
return m.deleteTable(bucket) return m.deleteTable(bucket)
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) Del(bucket, key []byte) error { func (m *MockdatabaseDB) Del(bucket, key []byte) error {
if m.del != nil { if m.del != nil {
return m.del(bucket, key) return m.del(bucket, key)
} }
return m.err return m.err
} }
func (m *MockNoSQLDB) List(bucket []byte) ([]*nosql.Entry, error) { func (m *MockdatabaseDB) List(bucket []byte) ([]*database.Entry, error) {
if m.list != nil { if m.list != nil {
return m.list(bucket) return m.list(bucket)
} }
return m.ret1.([]*nosql.Entry), m.err return m.ret1.([]*database.Entry), m.err
} }
func (m *MockNoSQLDB) Update(tx *nosql.Tx) error { func (m *MockdatabaseDB) Update(tx *database.Tx) error {
if m.update != nil { if m.update != nil {
return m.update(tx) return m.update(tx)
} }
@ -100,16 +100,16 @@ func TestIsRevoked(t *testing.T) {
}, },
"false/ErrNotFound": { "false/ErrNotFound": {
key: "sn", key: "sn",
db: &DB{&MockNoSQLDB{err: nosql.ErrNotFound, ret1: nil}}, db: &DB{&MockdatabaseDB{err: database.ErrNotFound, ret1: nil}},
}, },
"error/checking bucket": { "error/checking bucket": {
key: "sn", key: "sn",
db: &DB{&MockNoSQLDB{err: errors.New("force"), ret1: nil}}, db: &DB{&MockdatabaseDB{err: errors.New("force"), ret1: nil}},
err: errors.New("error checking revocation bucket: force"), err: errors.New("error checking revocation bucket: force"),
}, },
"true": { "true": {
key: "sn", key: "sn",
db: &DB{&MockNoSQLDB{ret1: []byte("value")}}, db: &DB{&MockdatabaseDB{ret1: []byte("value")}},
isRevoked: true, isRevoked: true,
}, },
} }
@ -136,7 +136,7 @@ func TestRevoke(t *testing.T) {
}{ }{
"error/force isRevoked": { "error/force isRevoked": {
rci: &RevokedCertificateInfo{Serial: "sn"}, rci: &RevokedCertificateInfo{Serial: "sn"},
db: &DB{&MockNoSQLDB{ db: &DB{&MockdatabaseDB{
get: func(bucket []byte, sn []byte) ([]byte, error) { get: func(bucket []byte, sn []byte) ([]byte, error) {
return nil, errors.New("force IsRevoked") return nil, errors.New("force IsRevoked")
}, },
@ -145,7 +145,7 @@ func TestRevoke(t *testing.T) {
}, },
"error/was already revoked": { "error/was already revoked": {
rci: &RevokedCertificateInfo{Serial: "sn"}, rci: &RevokedCertificateInfo{Serial: "sn"},
db: &DB{&MockNoSQLDB{ db: &DB{&MockdatabaseDB{
get: func(bucket []byte, sn []byte) ([]byte, error) { get: func(bucket []byte, sn []byte) ([]byte, error) {
return nil, nil return nil, nil
}, },
@ -154,9 +154,9 @@ func TestRevoke(t *testing.T) {
}, },
"error/database set": { "error/database set": {
rci: &RevokedCertificateInfo{Serial: "sn"}, rci: &RevokedCertificateInfo{Serial: "sn"},
db: &DB{&MockNoSQLDB{ db: &DB{&MockdatabaseDB{
get: func(bucket []byte, sn []byte) ([]byte, error) { get: func(bucket []byte, sn []byte) ([]byte, error) {
return nil, nosql.ErrNotFound return nil, database.ErrNotFound
}, },
set: func(bucket []byte, key []byte, value []byte) error { set: func(bucket []byte, key []byte, value []byte) error {
return errors.New("force") return errors.New("force")
@ -166,9 +166,9 @@ func TestRevoke(t *testing.T) {
}, },
"ok": { "ok": {
rci: &RevokedCertificateInfo{Serial: "sn"}, rci: &RevokedCertificateInfo{Serial: "sn"},
db: &DB{&MockNoSQLDB{ db: &DB{&MockdatabaseDB{
get: func(bucket []byte, sn []byte) ([]byte, error) { get: func(bucket []byte, sn []byte) ([]byte, error) {
return nil, nosql.ErrNotFound return nil, database.ErrNotFound
}, },
set: func(bucket []byte, key []byte, value []byte) error { set: func(bucket []byte, key []byte, value []byte) error {
return nil return nil