VAULT-23553: Revert "Don't panic on unknown raft ops" (#25991)

* Revert "Don't panic on unknown raft ops (#17732)"

This reverts commit c9b4300897.

* add test for panic

* add back changelog

* add godoc for test

* log -> l

* changelog

* Apply suggestions from code review

Co-authored-by: Josh Black <raskchanky@gmail.com>

---------

Co-authored-by: Josh Black <raskchanky@gmail.com>
This commit is contained in:
miagilepner
2024-03-19 17:21:07 +01:00
committed by GitHub
parent ab59f8fa56
commit b01ba81339
3 changed files with 48 additions and 17 deletions

3
changelog/25991.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
storage/raft: panic on unknown Raft operations
```

View File

@@ -179,7 +179,6 @@ type FSM struct {
localID string localID string
desiredSuffrage string desiredSuffrage string
unknownOpTypes sync.Map
} }
// NewFSM constructs a FSM using the given directory // NewFSM constructs a FSM using the given directory
@@ -763,10 +762,7 @@ func (f *FSM) ApplyBatch(logs []*raft.Log) []interface{} {
go f.restoreCb(context.Background()) go f.restoreCb(context.Background())
} }
default: default:
if _, ok := f.unknownOpTypes.Load(op.OpType); !ok { return fmt.Errorf("%q is not a supported transaction operation", op.OpType)
f.logger.Error("unsupported transaction operation", "op", op.OpType)
f.unknownOpTypes.Store(op.OpType, struct{}{})
}
} }
if err != nil { if err != nil {
return err return err

View File

@@ -6,9 +6,7 @@ package raft
import ( import (
"context" "context"
"fmt" "fmt"
"io/ioutil"
"math/rand" "math/rand"
"os"
"sort" "sort"
"testing" "testing"
@@ -17,13 +15,11 @@ import (
"github.com/hashicorp/go-hclog" "github.com/hashicorp/go-hclog"
"github.com/hashicorp/raft" "github.com/hashicorp/raft"
"github.com/hashicorp/vault/sdk/physical" "github.com/hashicorp/vault/sdk/physical"
"github.com/stretchr/testify/require"
) )
func getFSM(t testing.TB) (*FSM, string) { func getFSM(t testing.TB) *FSM {
raftDir, err := ioutil.TempDir("", "vault-raft-") raftDir := t.TempDir()
if err != nil {
t.Fatal(err)
}
t.Logf("raft dir: %s", raftDir) t.Logf("raft dir: %s", raftDir)
logger := hclog.New(&hclog.LoggerOptions{ logger := hclog.New(&hclog.LoggerOptions{
@@ -36,12 +32,11 @@ func getFSM(t testing.TB) (*FSM, string) {
t.Fatal(err) t.Fatal(err)
} }
return fsm, raftDir return fsm
} }
func TestFSM_Batching(t *testing.T) { func TestFSM_Batching(t *testing.T) {
fsm, dir := getFSM(t) fsm := getFSM(t)
defer func() { _ = os.RemoveAll(dir) }()
var index uint64 var index uint64
var term uint64 = 1 var term uint64 = 1
@@ -133,8 +128,7 @@ func TestFSM_Batching(t *testing.T) {
} }
func TestFSM_List(t *testing.T) { func TestFSM_List(t *testing.T) {
fsm, dir := getFSM(t) fsm := getFSM(t)
defer func() { _ = os.RemoveAll(dir) }()
ctx := context.Background() ctx := context.Background()
count := 100 count := 100
@@ -162,3 +156,41 @@ func TestFSM_List(t *testing.T) {
t.Fatal(diff) t.Fatal(diff)
} }
} }
// TestFSM_UnknownOperation calls ApplyBatch with a batch that has an unknown
// command operation type. The test verifies that the call panics
func TestFSM_UnknownOperation(t *testing.T) {
fsm := getFSM(t)
command := &LogData{
Operations: make([]*LogOperation, 5),
}
for i := range command.Operations {
op := putOp
if i == 4 {
// the last operation has an invalid op type
op = 0
}
command.Operations[i] = &LogOperation{
OpType: op,
Key: fmt.Sprintf("key-%d", i),
Value: []byte(fmt.Sprintf("value-%d", i)),
}
}
commandBytes, err := proto.Marshal(command)
require.NoError(t, err)
defer func() {
r := recover()
require.NotNil(t, r)
require.Contains(t, r, "failed to store data")
}()
fsm.ApplyBatch([]*raft.Log{{
Index: 0,
Term: 1,
Type: raft.LogCommand,
Data: commandBytes,
}})
require.Fail(t, "failed to panic")
}