forked from moby/swarmkit
/
common.go
110 lines (96 loc) · 2.7 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"golang.org/x/net/context"
"github.com/coreos/etcd/pkg/fileutil"
"github.com/coreos/etcd/wal/walpb"
"github.com/docker/swarmkit/ca"
"github.com/docker/swarmkit/manager"
"github.com/docker/swarmkit/manager/encryption"
"github.com/docker/swarmkit/manager/state/raft/storage"
)
func certPaths(swarmdir string) *ca.SecurityConfigPaths {
return ca.NewConfigPaths(filepath.Join(swarmdir, "certificates"))
}
func getDEKData(krw *ca.KeyReadWriter) (manager.RaftDEKData, error) {
h, _ := krw.GetCurrentState()
dekData, ok := h.(manager.RaftDEKData)
if !ok {
return manager.RaftDEKData{}, errors.New("cannot read raft dek headers in TLS key")
}
if dekData.CurrentDEK == nil {
return manager.RaftDEKData{}, errors.New("no raft DEKs available")
}
return dekData, nil
}
func getKRW(swarmdir, unlockKey string) (*ca.KeyReadWriter, error) {
var (
kek []byte
err error
)
if unlockKey != "" {
kek, err = encryption.ParseHumanReadableKey(unlockKey)
if err != nil {
return nil, err
}
}
krw := ca.NewKeyReadWriter(certPaths(swarmdir).Node, kek, manager.RaftDEKData{})
_, _, err = krw.Read() // loads all the key data into the KRW object
if err != nil {
return nil, err
}
return krw, nil
}
func moveDirAside(dirname string) error {
if fileutil.Exist(dirname) {
tempdir, err := ioutil.TempDir(filepath.Dir(dirname), filepath.Base(dirname))
if err != nil {
return err
}
return os.Rename(dirname, tempdir)
}
return nil
}
func decryptRaftData(swarmdir, outdir, unlockKey string) error {
krw, err := getKRW(swarmdir, unlockKey)
if err != nil {
return err
}
deks, err := getDEKData(krw)
if err != nil {
return err
}
_, d := encryption.Defaults(deks.CurrentDEK)
if deks.PendingDEK == nil {
_, d2 := encryption.Defaults(deks.PendingDEK)
d = storage.MultiDecrypter{d, d2}
}
snapDir := filepath.Join(outdir, "snap-decrypted")
if err := moveDirAside(snapDir); err != nil {
return err
}
if err := storage.MigrateSnapshot(
filepath.Join(swarmdir, "raft", "snap-v3-encrypted"), snapDir,
storage.NewSnapFactory(encryption.NoopCrypter, d), storage.OriginalSnap); err != nil {
return err
}
var walsnap walpb.Snapshot
snap, err := storage.OriginalSnap.New(snapDir).Load()
if err != nil && !os.IsNotExist(err) {
return err
}
if snap != nil {
walsnap.Index = snap.Metadata.Index
walsnap.Term = snap.Metadata.Term
}
walDir := filepath.Join(outdir, "wal-decrypted")
if err := moveDirAside(walDir); err != nil {
return err
}
return storage.MigrateWALs(context.Background(),
filepath.Join(swarmdir, "raft", "wal-v3-encrypted"), walDir,
storage.NewWALFactory(encryption.NoopCrypter, d), storage.OriginalWAL, walsnap)
}