mirror of
https://github.com/mitchell/selfpass.git
synced 2025-12-14 13:27:21 +00:00
Add 2 migrations for ids and boltdb; minor refactor to creds service
This commit is contained in:
parent
cf90993d4e
commit
a67be14fcb
13 changed files with 203 additions and 58 deletions
71
services/migrations/201907190_redis_new_id.go
Normal file
71
services/migrations/201907190_redis_new_id.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/mediocregopher/radix/v3"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/mitchell/selfpass/services/credentials/types"
|
||||
"github.com/mitchell/selfpass/services/migrations/migration"
|
||||
)
|
||||
|
||||
func main() {
|
||||
redisHost := pflag.StringP("redis-host", "r", "127.0.0.1:6379", "specify the redis host to target")
|
||||
help := pflag.BoolP("help", "h", false, "see help")
|
||||
pflag.Parse()
|
||||
|
||||
if *help {
|
||||
pflag.PrintDefaults()
|
||||
return
|
||||
}
|
||||
|
||||
pool, err := radix.NewPool("tcp", *redisHost, 10)
|
||||
migration.Check(err)
|
||||
|
||||
fmt.Println("Beginning migration...")
|
||||
|
||||
var pipeCmds []radix.CmdAction
|
||||
var creds []*types.Credential
|
||||
scanner := radix.NewScanner(pool, radix.ScanAllKeys)
|
||||
|
||||
for key := ""; scanner.Next(&key); {
|
||||
var cred types.Credential
|
||||
pipeCmds = append(pipeCmds, radix.Cmd(&cred, "HGETALL", key))
|
||||
pipeCmds = append(pipeCmds, radix.Cmd(nil, "DEL", key))
|
||||
creds = append(creds, &cred)
|
||||
}
|
||||
|
||||
migration.Check(pool.Do(radix.Pipeline(pipeCmds...)))
|
||||
pipeCmds = nil
|
||||
|
||||
for _, cred := range creds {
|
||||
tcred := *cred
|
||||
tcred.ID = generateID()
|
||||
|
||||
fmt.Printf("Migrating %s to %s.\n", cred.ID, tcred.ID)
|
||||
|
||||
pipeCmds = append(pipeCmds, radix.FlatCmd(nil, "HMSET", tcred.ID, tcred))
|
||||
}
|
||||
|
||||
migration.Check(pool.Do(radix.Pipeline(pipeCmds...)))
|
||||
|
||||
fmt.Println("Done migrating.")
|
||||
}
|
||||
|
||||
func generateID() string {
|
||||
const idLen = 8
|
||||
const alphanumerics = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789"
|
||||
const alphaLen = len(alphanumerics)
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
id := make([]byte, idLen)
|
||||
|
||||
for index := range id {
|
||||
id[index] = alphanumerics[rand.Int63()%int64(alphaLen)]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s-%s", types.KeyCredential, string(id))
|
||||
}
|
||||
77
services/migrations/201907191_redis_to_bolt.go
Normal file
77
services/migrations/201907191_redis_to_bolt.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/etcd-io/bbolt"
|
||||
"github.com/mediocregopher/radix/v3"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/mitchell/selfpass/services/credentials/types"
|
||||
"github.com/mitchell/selfpass/services/migrations/migration"
|
||||
)
|
||||
|
||||
const keyCredentials = "credentials"
|
||||
|
||||
func main() {
|
||||
redisHost := pflag.StringP("redis-host", "r", "127.0.0.1:6379", "specify the redis host")
|
||||
boltFile := pflag.StringP("bolt-file", "b", "./data/bolt.db", "specify the bolt DB file")
|
||||
help := pflag.BoolP("help", "h", false, "see help")
|
||||
pflag.Parse()
|
||||
|
||||
if *help {
|
||||
pflag.PrintDefaults()
|
||||
return
|
||||
}
|
||||
|
||||
pool, err := radix.NewPool("tcp", *redisHost, 10)
|
||||
migration.Check(err)
|
||||
|
||||
db, err := bbolt.Open(*boltFile, 0600, nil)
|
||||
migration.Check(err)
|
||||
|
||||
defer func() { migration.Check(db.Close()); migration.Check(pool.Close()) }()
|
||||
|
||||
fmt.Println("Beginning migration...")
|
||||
|
||||
var wg sync.WaitGroup
|
||||
scanner := radix.NewScanner(pool, radix.ScanOpts{Command: "SCAN"})
|
||||
|
||||
for key := ""; scanner.Next(&key); {
|
||||
wg.Add(1)
|
||||
go func(key string) {
|
||||
defer wg.Done()
|
||||
|
||||
var cred types.Credential
|
||||
migration.Check(pool.Do(radix.Cmd(&cred, "HGETALL", key)))
|
||||
|
||||
fmt.Printf("Migrating %s.\n", cred.ID)
|
||||
|
||||
migration.Check(db.Batch(func(tx *bbolt.Tx) error {
|
||||
credBkt, err := tx.CreateBucketIfNotExists([]byte(keyCredentials))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
err = gob.NewEncoder(buf).Encode(cred)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = credBkt.Put([]byte(cred.ID), buf.Bytes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}))
|
||||
}(key)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
fmt.Println("Done migrating.")
|
||||
}
|
||||
19
services/migrations/migration/migration.go
Normal file
19
services/migrations/migration/migration.go
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package migration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func Check(err error) {
|
||||
if err != nil {
|
||||
_, _, line, ok := runtime.Caller(1)
|
||||
if ok {
|
||||
fmt.Printf("%v: %s\n", line, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue