github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarm-rafttool/common_test.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "testing" 9 10 "github.com/coreos/etcd/pkg/fileutil" 11 "github.com/coreos/etcd/raft/raftpb" 12 "github.com/coreos/etcd/wal/walpb" 13 "github.com/docker/swarmkit/ca" 14 "github.com/docker/swarmkit/ca/testutils" 15 "github.com/docker/swarmkit/manager" 16 "github.com/docker/swarmkit/manager/encryption" 17 "github.com/docker/swarmkit/manager/state/raft" 18 "github.com/docker/swarmkit/manager/state/raft/storage" 19 "github.com/stretchr/testify/require" 20 ) 21 22 // writeFakeRaftData writes the given snapshot and some generated WAL data to given "snap" and "wal" directories 23 func writeFakeRaftData(t *testing.T, stateDir string, snapshot *raftpb.Snapshot, wf storage.WALFactory, sf storage.SnapFactory) { 24 snapDir := filepath.Join(stateDir, "raft", "snap-v3-encrypted") 25 walDir := filepath.Join(stateDir, "raft", "wal-v3-encrypted") 26 require.NoError(t, os.MkdirAll(snapDir, 0755)) 27 28 wsn := walpb.Snapshot{} 29 if snapshot != nil { 30 require.NoError(t, sf.New(snapDir).SaveSnap(*snapshot)) 31 32 wsn.Index = snapshot.Metadata.Index 33 wsn.Term = snapshot.Metadata.Term 34 } 35 36 var entries []raftpb.Entry 37 for i := wsn.Index + 1; i < wsn.Index+6; i++ { 38 entries = append(entries, raftpb.Entry{ 39 Term: wsn.Term + 1, 40 Index: i, 41 Data: []byte(fmt.Sprintf("v3Entry %d", i)), 42 }) 43 } 44 45 walWriter, err := wf.Create(walDir, []byte("v3metadata")) 46 require.NoError(t, err) 47 require.NoError(t, walWriter.SaveSnapshot(wsn)) 48 require.NoError(t, walWriter.Save(raftpb.HardState{}, entries)) 49 require.NoError(t, walWriter.Close()) 50 } 51 52 func TestDecrypt(t *testing.T) { 53 tempdir, err := ioutil.TempDir("", "rafttool") 54 require.NoError(t, err) 55 defer os.RemoveAll(tempdir) 56 57 kek := []byte("kek") 58 dek := []byte("dek") 59 unlockKey := encryption.HumanReadableKey(kek) 60 61 // write a key to disk, else we won't be able to decrypt anything 62 paths := certPaths(tempdir) 63 krw := ca.NewKeyReadWriter(paths.Node, kek, 64 manager.RaftDEKData{EncryptionKeys: raft.EncryptionKeys{CurrentDEK: dek}}) 65 cert, key, err := testutils.CreateRootCertAndKey("not really a root, just need cert and key") 66 require.NoError(t, err) 67 require.NoError(t, krw.Write(cert, key, nil)) 68 69 // create the encrypted v3 directory 70 origSnapshot := raftpb.Snapshot{ 71 Data: []byte("snapshot"), 72 Metadata: raftpb.SnapshotMetadata{ 73 Index: 1, 74 Term: 1, 75 }, 76 } 77 e, d := encryption.Defaults(dek, false) 78 writeFakeRaftData(t, tempdir, &origSnapshot, storage.NewWALFactory(e, d), storage.NewSnapFactory(e, d)) 79 80 outdir := filepath.Join(tempdir, "outdir") 81 // if we use the wrong unlock key, we can't actually decrypt anything. The output directory won't get created. 82 err = decryptRaftData(tempdir, outdir, "") 83 require.IsType(t, ca.ErrInvalidKEK{}, err) 84 require.False(t, fileutil.Exist(outdir)) 85 86 // Using the right unlock key, we produce data that is unencrypted 87 require.NoError(t, decryptRaftData(tempdir, outdir, unlockKey)) 88 require.True(t, fileutil.Exist(outdir)) 89 90 // The snapshot directory is readable by the regular snapshotter 91 snapshot, err := storage.OriginalSnap.New(filepath.Join(outdir, "snap-decrypted")).Load() 92 require.NoError(t, err) 93 require.NotNil(t, snapshot) 94 require.Equal(t, origSnapshot, *snapshot) 95 96 // The wals are readable by the regular wal 97 walreader, err := storage.OriginalWAL.Open(filepath.Join(outdir, "wal-decrypted"), walpb.Snapshot{Index: 1, Term: 1}) 98 require.NoError(t, err) 99 metadata, _, entries, err := walreader.ReadAll() 100 require.NoError(t, err) 101 require.Equal(t, []byte("v3metadata"), metadata) 102 require.Len(t, entries, 5) 103 }