Skip to content

Commit

Permalink
Merge pull request #560 from azdagron/removed-soft-delete-support
Browse files Browse the repository at this point in the history
remove soft-delete support + migration
  • Loading branch information
azdagron authored Aug 20, 2018
2 parents 5795105 + 3bbfce3 commit 3181fdf
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 52 deletions.
133 changes: 133 additions & 0 deletions pkg/server/plugin/datastore/sql/migration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package sql

import (
"fmt"

"github.com/jinzhu/gorm"
"github.com/sirupsen/logrus"
)

const (
// version of the database in the code
codeVersion = 1
)

func migrateDB(db *gorm.DB) (err error) {
isNew := !db.HasTable(&Bundle{})
if err := db.Error; err != nil {
return err
}

if isNew {
return initDB(db)
}

if err := db.AutoMigrate(&Migration{}).Error; err != nil {
return err
}

migration := new(Migration)
if err := db.Assign(Migration{}).FirstOrCreate(migration).Error; err != nil {
return err
}
version := migration.Version

if version > codeVersion {
err = fmt.Errorf("backwards migration not supported! (current=%d, code=%d)", version, codeVersion)
logrus.Error(err)
return err
}

if version == codeVersion {
return nil
}

logrus.Infof("running migrations...")
for version < codeVersion {
tx := db.Begin()
if err := tx.Error; err != nil {
return err
}
version, err = migrateVersion(tx, version)
if err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
}

logrus.Infof("done running migrations.")
return nil
}

func initDB(db *gorm.DB) (err error) {
logrus.Infof("initializing database.")
tx := db.Begin()
if err := tx.Error; err != nil {
return err
}

if err := tx.AutoMigrate(&Bundle{}, &CACert{}, &AttestedNodeEntry{},
&NodeResolverMapEntry{}, &RegisteredEntry{}, &JoinToken{},
&Selector{}, &Migration{}).Error; err != nil {
tx.Rollback()
return err
}

if err := tx.Assign(Migration{Version: codeVersion}).FirstOrCreate(&Migration{}).Error; err != nil {
tx.Rollback()
return err
}

return tx.Commit().Error
}

func migrateVersion(tx *gorm.DB, version int) (versionOut int, err error) {
logrus.Infof("migrating from version %d", version)

// When a new version is added an entry must be included here that knows
// how to bring the previous version up. The migrations are run
// sequentially, each in its own transaction, to move from one version to
// the next.
switch version {
case 0:
err = migrateToV1(tx)
default:
err = fmt.Errorf("no migration support for version %d", version)
}
if err != nil {
return version, err
}

nextVersion := version + 1
if err := tx.Model(&Migration{}).Updates(Migration{Version: nextVersion}).Error; err != nil {
return version, err
}

return nextVersion, nil
}

func migrateToV1(tx *gorm.DB) error {
v0tables := []string{
"ca_certs",
"bundles",
"attested_node_entries",
"join_tokens",
"node_resolver_map_entries",
"selectors",
"registered_entries",
}

// soft-delete support is being removed. drop all of the records that have
// been soft-deleted. unfortunately the "deleted_at" column cannot dropped
// easily because that operation is not supported by all dialects (thanks,
// sqlite3).
for _, table := range v0tables {
if err := tx.Exec(fmt.Sprintf("DELETE FROM %s WHERE deleted_at IS NOT NULL;", table)).Error; err != nil {
return err
}
}
return nil
}
32 changes: 18 additions & 14 deletions pkg/server/plugin/datastore/sql/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package sql

import (
"time"

"github.com/jinzhu/gorm"
)

// Using our own model struct to remove DeletedAt. We don't want soft-delete support.
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
}

type CACert struct {
gorm.Model
Model

Cert []byte `gorm:"not null"`
Expiry time.Time `gorm:"not null;index"`
Expand All @@ -16,14 +21,14 @@ type CACert struct {
}

type Bundle struct {
gorm.Model
Model

TrustDomain string `gorm:"not null;unique_index"`
CACerts []CACert
}

type AttestedNodeEntry struct {
gorm.Model
Model

SpiffeID string `gorm:"unique_index"`
DataType string
Expand All @@ -32,15 +37,15 @@ type AttestedNodeEntry struct {
}

type NodeResolverMapEntry struct {
gorm.Model
Model

SpiffeID string `gorm:"unique_index:idx_node_resolver_map"`
Type string `gorm:"unique_index:idx_node_resolver_map"`
Value string `gorm:"unique_index:idx_node_resolver_map"`
}

type RegisteredEntry struct {
gorm.Model
Model

EntryID string `gorm:"unique_index"`
SpiffeID string
Expand All @@ -52,24 +57,23 @@ type RegisteredEntry struct {

// Keep time simple and easily comparable with UNIX time
type JoinToken struct {
gorm.Model
Model

Token string `gorm:"unique_index"`
Expiry int64
}

type Selector struct {
gorm.Model
Model

RegisteredEntryID uint `gorm:"unique_index:idx_selector_entry"`
Type string `gorm:"unique_index:idx_selector_entry"`
Value string `gorm:"unique_index:idx_selector_entry"`
}

func migrateDB(db *gorm.DB) {
db.AutoMigrate(&Bundle{}, &CACert{}, &AttestedNodeEntry{},
&NodeResolverMapEntry{}, &RegisteredEntry{}, &JoinToken{},
&Selector{})
type Migration struct {
Model

return
// Database version
Version int
}
30 changes: 7 additions & 23 deletions pkg/server/plugin/datastore/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,47 +1133,31 @@ func (ds *sqlPlugin) restart() error {
default:
return fmt.Errorf("unsupported database_type: %v", ds.DatabaseType)
}

if err != nil {
return err
}

if err := migrateDB(db); err != nil {
db.Close()
return err
}

if ds.db != nil {
ds.db.Close()
}

migrateDB(db)
ds.db = db
return nil
}

func newPlugin() *sqlPlugin {
p := &sqlPlugin{
mutex: new(sync.Mutex),
ConnectionString: ":memory:",
DatabaseType: "sqlite3",
return &sqlPlugin{
mutex: new(sync.Mutex),
}

return p
}

// New creates a new sql plugin struct. Configure must be called
// in order to start the db.
func New() datastore.Plugin {
return newPlugin()
}

// NewTemp create a new plugin with a temporal database, allowing new
// connections to receive a fresh copy. Primarily meant for testing.
func NewTemp() (datastore.Plugin, error) {
p := newPlugin()

// Call restart() to start the db - normally triggered by call to Configure
err := p.restart()
if err != nil {
return nil, fmt.Errorf("start database: %v", err)
}

p.db.LogMode(true)
return p, nil
}
Loading

0 comments on commit 3181fdf

Please sign in to comment.