Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for encrypted backups/restore (#5079) #5103

Merged
merged 2 commits into from
Apr 3, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions dgraph/cmd/alpha/admin_backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ func processHttpBackupRequest(ctx context.Context, r *http.Request) error {
req.SinceTs = latestManifest.Since
if forceFull {
req.SinceTs = 0
} else {
if worker.Config.BadgerKeyFile != "" {
// If encryption turned on, latest backup should be encrypted.
if latestManifest.Type != "" && !latestManifest.Encrypted {
err = errors.Errorf("latest manifest indicates the last backup was not encrypted " +
"but this instance has encryption turned on. Try \"forceFull\" flag.")
return err
}
} else {
// If encryption turned off, latest backup should be unencrypted.
if latestManifest.Type != "" && latestManifest.Encrypted {
err = errors.Errorf("latest manifest indicates the last backup was encrypted " +
"but this instance has encryption turned off. Try \"forceFull\" flag.")
return err
}
}
}

// Update the membership state to get the latest mapping of groups to predicates.
Expand Down Expand Up @@ -160,6 +176,9 @@ func processHttpBackupRequest(ctx context.Context, r *http.Request) error {
m.BackupId = latestManifest.BackupId
m.BackupNum = latestManifest.BackupNum + 1
}
if worker.Config.BadgerKeyFile != "" {
m.Encrypted = true
}

bp := &backup.Processor{Request: &req}
return bp.CompleteBackup(ctx, &m)
Expand Down
2 changes: 2 additions & 0 deletions dgraph/cmd/alpha/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/dgraph-io/badger/v2/y"
"github.com/dgraph-io/dgo/v2/protos/api"
"github.com/dgraph-io/dgraph/edgraph"
"github.com/dgraph-io/dgraph/ee/backup"
"github.com/dgraph-io/dgraph/ee/enc"
"github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/schema"
Expand Down Expand Up @@ -520,6 +521,7 @@ func run() {
AuthToken: Alpha.Conf.GetString("auth_token"),
AllottedMemory: Alpha.Conf.GetFloat64("lru_mb"),
}
backup.BadgerKeyFile = opts.BadgerKeyFile

// OSS, non-nil key file --> crash
if !enc.EeBuild && opts.BadgerKeyFile != "" {
Expand Down
18 changes: 16 additions & 2 deletions ee/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/golang/glog"
"github.com/pkg/errors"

"github.com/dgraph-io/dgraph/ee/enc"
"github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/x"
Expand Down Expand Up @@ -77,8 +78,13 @@ type Manifest struct {
// Path is the path to the manifest file. This field is only used during
// processing and is not written to disk.
Path string `json:"-"`
// Encrypted indicates whether this backup was encrypted or not.
Encrypted bool `json:"encrypted"`
}

// BadgerKeyFile - This is copy of worker.Config.BadgerKeyFile. Need to copy because it results in import cycle.
parasssh marked this conversation as resolved.
Show resolved Hide resolved
var BadgerKeyFile string

func (m *Manifest) getPredsInGroup(gid uint32) predicateSet {
preds, ok := m.Groups[gid]
if !ok {
Expand Down Expand Up @@ -125,7 +131,13 @@ func (pr *Processor) WriteBackup(ctx context.Context) (*pb.Status, error) {
}

var maxVersion uint64
gzWriter := gzip.NewWriter(handler)

newhandler, err := enc.GetWriter(BadgerKeyFile, handler)
if err != nil {
return &emptyRes, err
}
gzWriter := gzip.NewWriter(newhandler)

stream := pr.DB.NewStreamAt(pr.Request.ReadTs)
stream.LogPrefix = "Dgraph.Backup"
stream.KeyToList = pr.toBackupList
Expand Down Expand Up @@ -168,6 +180,7 @@ func (pr *Processor) WriteBackup(ctx context.Context) (*pb.Status, error) {
glog.Errorf("While closing gzipped writer: %v", err)
return &emptyRes, err
}

if err = handler.Close(); err != nil {
glog.Errorf("While closing handler: %v", err)
return &emptyRes, err
Expand Down Expand Up @@ -209,7 +222,8 @@ func (pr *Processor) CompleteBackup(ctx context.Context, manifest *Manifest) err

// GoString implements the GoStringer interface for Manifest.
func (m *Manifest) GoString() string {
return fmt.Sprintf(`Manifest{Since: %d, Groups: %v}`, m.Since, m.Groups)
return fmt.Sprintf(`Manifest{Since: %d, Groups: %v, Encrypted: %v}`,
m.Since, m.Groups, m.Encrypted)
}

func (pr *Processor) toBackupList(key []byte, itr *badger.Iterator) (*bpb.KVList, error) {
Expand Down
10 changes: 7 additions & 3 deletions ee/backup/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ import (
bpb "github.com/dgraph-io/badger/v2/pb"
"github.com/pkg/errors"

"github.com/dgraph-io/dgraph/ee/enc"
"github.com/dgraph-io/dgraph/posting"
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/x"
)

// RunRestore calls badger.Load and tries to load data into a new DB.
func RunRestore(pdir, location, backupId string) LoadResult {
func RunRestore(pdir, location, backupId, keyfile string) LoadResult {
// Create the pdir if it doesn't exist.
if err := os.MkdirAll(pdir, 0700); err != nil {
return LoadResult{0, 0, err}
Expand All @@ -59,15 +60,18 @@ func RunRestore(pdir, location, backupId string) LoadResult {
if !pathExist(dir) {
fmt.Println("Creating new db:", dir)
}
r, err = enc.GetReader(keyfile, r)
if err != nil {
return 0, err
}
gzReader, err := gzip.NewReader(r)
if err != nil {
return 0, nil
return 0, err
}
maxUid, err := loadFromBackup(db, gzReader, preds)
if err != nil {
return 0, err
}

return maxUid, x.WriteGroupIdFile(dir, uint32(groupId))
})
}
Expand Down
10 changes: 6 additions & 4 deletions ee/backup/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ var Restore x.SubCommand
var LsBackup x.SubCommand

var opt struct {
backupId, location, pdir, zero string
backupId, location, pdir, zero, keyfile string
}

func init() {
Expand Down Expand Up @@ -104,6 +104,8 @@ $ dgraph restore -p . -l /var/backups/dgraph -z localhost:5080
flag.StringVarP(&opt.zero, "zero", "z", "", "gRPC address for Dgraph zero. ex: localhost:5080")
flag.StringVarP(&opt.backupId, "backup_id", "", "", "The ID of the backup series to "+
"restore. If empty, it will restore the latest series.")
flag.StringVarP(&opt.keyfile, "keyfile", "k", "",
"Key file to decrypt the backup")
_ = Restore.Cmd.MarkFlagRequired("postings")
_ = Restore.Cmd.MarkFlagRequired("location")
}
Expand Down Expand Up @@ -184,7 +186,7 @@ func runRestoreCmd() error {
}

start = time.Now()
result := RunRestore(opt.pdir, opt.location, opt.backupId)
result := RunRestore(opt.pdir, opt.location, opt.backupId, opt.keyfile)
if result.Err != nil {
return result.Err
}
Expand Down Expand Up @@ -225,9 +227,9 @@ func runLsbackupCmd() error {
return errors.Wrapf(err, "while listing manifests")
}

fmt.Printf("Name\tSince\tGroups\n")
fmt.Printf("Name\tSince\tGroups\tEncrypted\n")
for path, manifest := range manifests {
fmt.Printf("%v\t%v\t%v\n", path, manifest.Since, manifest.Groups)
fmt.Printf("%v\t%v\t%v\t%v\n", path, manifest.Since, manifest.Groups, manifest.Encrypted)
}

return nil
Expand Down
Loading