mirror of https://github.com/mitchell/selfpass.git
Add 2 migrations for ids and boltdb; minor refactor to creds service
This commit is contained in:
parent
cf90993d4e
commit
a67be14fcb
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/go-kit/kit/endpoint"
|
"github.com/go-kit/kit/endpoint"
|
||||||
|
|
||||||
"github.com/mitchell/selfpass/services/credentials/types"
|
"github.com/mitchell/selfpass/services/credentials/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -48,10 +49,6 @@ func MakeUpdateEndpoint(svc types.Service) endpoint.Endpoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type DumpResponse struct {
|
|
||||||
Contents []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type IDRequest struct {
|
type IDRequest struct {
|
||||||
ID string
|
ID string
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
|
|
||||||
"github.com/mitchell/selfpass/services/credentials/types"
|
"github.com/mitchell/selfpass/services/credentials/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -97,18 +98,3 @@ func (svc ServiceLogger) Delete(ctx context.Context, id string) (err error) {
|
||||||
err = svc.next.Delete(ctx, id)
|
err = svc.next.Delete(ctx, id)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc ServiceLogger) DumpDB(ctx context.Context) (output []byte, err error) {
|
|
||||||
defer func(begin time.Time) {
|
|
||||||
_ = svc.l.Log(
|
|
||||||
"service", "Credentials",
|
|
||||||
"method", "Dump",
|
|
||||||
"output", output,
|
|
||||||
"err", err,
|
|
||||||
"took", time.Since(begin),
|
|
||||||
)
|
|
||||||
}(time.Now())
|
|
||||||
|
|
||||||
output, err = svc.next.DumpDB(ctx)
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/mediocregopher/radix/v3"
|
"github.com/mediocregopher/radix/v3"
|
||||||
|
|
||||||
"github.com/mitchell/selfpass/services/credentials/types"
|
"github.com/mitchell/selfpass/services/credentials/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ func (conn RedisConn) GetAllMetadata(ctx context.Context, sourceHost string, err
|
||||||
defer close(mdch)
|
defer close(mdch)
|
||||||
|
|
||||||
var key string
|
var key string
|
||||||
scr := radix.NewScanner(conn.p, radix.ScanOpts{Command: scan, Pattern: types.TypePrefixCred + dash + sourceHost + star})
|
scr := radix.NewScanner(conn.p, radix.ScanAllKeys)
|
||||||
|
|
||||||
for scr.Next(&key) {
|
for scr.Next(&key) {
|
||||||
select {
|
select {
|
||||||
|
@ -39,8 +40,10 @@ func (conn RedisConn) GetAllMetadata(ctx context.Context, sourceHost string, err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sourceHost == "" || sourceHost == md.SourceHost {
|
||||||
mdch <- md
|
mdch <- md
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return mdch
|
return mdch
|
||||||
|
@ -61,20 +64,7 @@ func (conn RedisConn) Delete(ctx context.Context, id string) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conn RedisConn) DumpDB(ctx context.Context) (bs []byte, err error) {
|
|
||||||
bs = []byte{}
|
|
||||||
|
|
||||||
if err := conn.p.Do(radix.Cmd(&bs, "DUMP")); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
dash = "-"
|
|
||||||
star = "*"
|
|
||||||
scan = "SCAN"
|
|
||||||
hGetAll = "HGETALL"
|
hGetAll = "HGETALL"
|
||||||
hMSet = "HMSET"
|
hMSet = "HMSET"
|
||||||
del = "DEL"
|
del = "DEL"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mitchell/selfpass/services/credentials/types"
|
"github.com/mitchell/selfpass/services/credentials/types"
|
||||||
|
@ -37,10 +38,12 @@ func (svc Credentials) Create(ctx context.Context, ci types.CredentialInput) (ou
|
||||||
return output, err
|
return output, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
var c types.Credential
|
var c types.Credential
|
||||||
c.ID = generateID(ci)
|
c.ID = generateID()
|
||||||
c.CreatedAt = time.Now()
|
c.CreatedAt = now
|
||||||
c.UpdatedAt = time.Now()
|
c.UpdatedAt = now
|
||||||
c.Primary = ci.Primary
|
c.Primary = ci.Primary
|
||||||
c.LoginURL = ci.LoginURL
|
c.LoginURL = ci.LoginURL
|
||||||
c.SourceHost = ci.SourceHost
|
c.SourceHost = ci.SourceHost
|
||||||
|
@ -78,15 +81,19 @@ func validateCredentialInput(c types.CredentialInput) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateID(ci types.CredentialInput) string {
|
func generateID() string {
|
||||||
idFormat := types.TypePrefixCred + "-%s-%s"
|
const idLen = 8
|
||||||
|
const alphanumerics = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789"
|
||||||
|
const alphaLen = len(alphanumerics)
|
||||||
|
|
||||||
if ci.Tag != "" {
|
rand.Seed(time.Now().UnixNano())
|
||||||
idFormat += "-%s"
|
id := make([]byte, idLen)
|
||||||
return fmt.Sprintf(idFormat, ci.SourceHost, ci.Primary, ci.Tag)
|
|
||||||
|
for index := range id {
|
||||||
|
id[index] = alphanumerics[rand.Int63()%int64(alphaLen)]
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf(idFormat, ci.SourceHost, ci.Primary)
|
return fmt.Sprintf("%s-%s", types.KeyCredential, string(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc Credentials) Update(ctx context.Context, id string, ci types.CredentialInput) (output types.Credential, err error) {
|
func (svc Credentials) Update(ctx context.Context, id string, ci types.CredentialInput) (output types.Credential, err error) {
|
||||||
|
@ -103,7 +110,6 @@ func (svc Credentials) Update(ctx context.Context, id string, ci types.Credentia
|
||||||
return output, err
|
return output, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.ID = generateID(ci)
|
|
||||||
c.UpdatedAt = time.Now()
|
c.UpdatedAt = time.Now()
|
||||||
c.Primary = ci.Primary
|
c.Primary = ci.Primary
|
||||||
c.LoginURL = ci.LoginURL
|
c.LoginURL = ci.LoginURL
|
||||||
|
@ -114,12 +120,6 @@ func (svc Credentials) Update(ctx context.Context, id string, ci types.Credentia
|
||||||
c.Username = ci.Username
|
c.Username = ci.Username
|
||||||
c.Tag = ci.Tag
|
c.Tag = ci.Tag
|
||||||
|
|
||||||
if c.ID != id {
|
|
||||||
if err = svc.repo.Delete(ctx, id); err != nil {
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return c, svc.repo.Put(ctx, c)
|
return c, svc.repo.Put(ctx, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,3 @@ func (svc Credentials) Delete(ctx context.Context, id string) (err error) {
|
||||||
}
|
}
|
||||||
return svc.repo.Delete(ctx, id)
|
return svc.repo.Delete(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc Credentials) DumpDB(ctx context.Context) (bs []byte, err error) {
|
|
||||||
return svc.repo.DumpDB(ctx)
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const TypePrefixCred = "cred"
|
const KeyCredential = "cred"
|
||||||
|
|
||||||
type Credential struct {
|
type Credential struct {
|
||||||
Metadata
|
Metadata
|
||||||
|
|
|
@ -8,7 +8,6 @@ type Service interface {
|
||||||
Create(ctx context.Context, ci CredentialInput) (output Credential, err error)
|
Create(ctx context.Context, ci CredentialInput) (output Credential, err error)
|
||||||
Update(ctx context.Context, id string, ci CredentialInput) (output Credential, err error)
|
Update(ctx context.Context, id string, ci CredentialInput) (output Credential, err error)
|
||||||
Delete(ctx context.Context, id string) (err error)
|
Delete(ctx context.Context, id string) (err error)
|
||||||
DumpDB(ctx context.Context) (bs []byte, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CredentialsRepo interface {
|
type CredentialsRepo interface {
|
||||||
|
@ -16,7 +15,6 @@ type CredentialsRepo interface {
|
||||||
Get(ctx context.Context, id string) (output Credential, err error)
|
Get(ctx context.Context, id string) (output Credential, err error)
|
||||||
Put(ctx context.Context, c Credential) (err error)
|
Put(ctx context.Context, c Credential) (err error)
|
||||||
Delete(ctx context.Context, id string) (err error)
|
Delete(ctx context.Context, id string) (err error)
|
||||||
DumpDB(ctx context.Context) (bs []byte, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CredentialsClientInit func(ctx context.Context, target, ca, cert, key string) (c CredentialsClient, err error)
|
type CredentialsClientInit func(ctx context.Context, target, ca, cert, key string) (c CredentialsClient, err error)
|
||||||
|
|
|
@ -4,7 +4,7 @@ cert=$(cat ./certs/server.pem)
|
||||||
key=$(cat ./certs/server-key.pem)
|
key=$(cat ./certs/server-key.pem)
|
||||||
|
|
||||||
cat << EOM
|
cat << EOM
|
||||||
// Code generated by inject-certs.sh, DO NOT EDIT.
|
// Code generated by gen_certs_go.sh, DO NOT EDIT.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
const ca = \`${ca}\`
|
const ca = \`${ca}\`
|
||||||
|
|
|
@ -3,12 +3,15 @@ module github.com/mitchell/selfpass/services
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/etcd-io/bbolt v1.3.3
|
||||||
github.com/go-kit/kit v0.9.0
|
github.com/go-kit/kit v0.9.0
|
||||||
github.com/go-logfmt/logfmt v0.4.0 // indirect
|
github.com/go-logfmt/logfmt v0.4.0 // indirect
|
||||||
github.com/go-stack/stack v1.8.0 // indirect
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
github.com/golang/protobuf v1.3.2
|
github.com/golang/protobuf v1.3.2
|
||||||
github.com/mediocregopher/radix/v3 v3.3.0
|
github.com/mediocregopher/radix/v3 v3.3.0
|
||||||
github.com/mitchell/selfpass/protobuf/go v0.0.0-00010101000000-000000000000
|
github.com/mitchell/selfpass/protobuf/go v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/spf13/pflag v1.0.3
|
||||||
|
go.etcd.io/bbolt v1.3.3 // indirect
|
||||||
google.golang.org/grpc v1.22.0
|
google.golang.org/grpc v1.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
|
||||||
|
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||||
|
@ -25,8 +27,12 @@ github.com/mediocregopher/radix/v3 v3.3.0 h1:oacPXPKHJg0hcngVVrdtTnfGJiS+PtwoQwT
|
||||||
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
|
github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||||
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||||
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
|
|
|
@ -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))
|
||||||
|
}
|
|
@ -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.")
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
|
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
@ -224,6 +225,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY=
|
github.com/yunify/qingstor-sdk-go v2.2.15+incompatible/go.mod h1:w6wqLDQ5bBTzxGJ55581UrSwLrsTAsdo9N6yX/8d9RY=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
|
|
Loading…
Reference in New Issue