mirror of https://github.com/status-im/consul.git
agent/consul: support updating intentions
This commit is contained in:
parent
0d96cdc0a5
commit
771b1737e3
|
@ -2,6 +2,7 @@ package consul
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
|
@ -58,6 +59,18 @@ func (s *Intention) Apply(
|
|||
}
|
||||
*reply = args.Intention.ID
|
||||
|
||||
// If this is not a create, then we have to verify the ID.
|
||||
if args.Op != structs.IntentionOpCreate {
|
||||
state := s.srv.fsm.State()
|
||||
_, ixn, err := state.IntentionGet(nil, args.Intention.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Intention lookup failed: %v", err)
|
||||
}
|
||||
if ixn == nil {
|
||||
return fmt.Errorf("Cannot modify non-existent intention: '%s'", args.Intention.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Commit
|
||||
resp, err := s.srv.raftApply(structs.IntentionRequestType, args)
|
||||
if err != nil {
|
||||
|
|
|
@ -3,6 +3,7 @@ package consul
|
|||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/consul/agent/structs"
|
||||
|
@ -10,6 +11,7 @@ import (
|
|||
"github.com/hashicorp/net-rpc-msgpackrpc"
|
||||
)
|
||||
|
||||
// Test basic creation
|
||||
func TestIntentionApply_new(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir1, s1 := testServer(t)
|
||||
|
@ -63,6 +65,94 @@ func TestIntentionApply_new(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test basic updating
|
||||
func TestIntentionApply_updateGood(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir1, s1 := testServer(t)
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
defer codec.Close()
|
||||
|
||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||
|
||||
// Setup a basic record to create
|
||||
ixn := structs.IntentionRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.IntentionOpCreate,
|
||||
Intention: &structs.Intention{
|
||||
SourceName: "test",
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
|
||||
// Create
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if reply == "" {
|
||||
t.Fatal("reply should be non-empty")
|
||||
}
|
||||
|
||||
// Update
|
||||
ixn.Op = structs.IntentionOpUpdate
|
||||
ixn.Intention.ID = reply
|
||||
ixn.Intention.SourceName = "bar"
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Read
|
||||
ixn.Intention.ID = reply
|
||||
{
|
||||
req := &structs.IntentionQueryRequest{
|
||||
Datacenter: "dc1",
|
||||
IntentionID: ixn.Intention.ID,
|
||||
}
|
||||
var resp structs.IndexedIntentions
|
||||
if err := msgpackrpc.CallWithCodec(codec, "Intention.Get", req, &resp); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if len(resp.Intentions) != 1 {
|
||||
t.Fatalf("bad: %v", resp)
|
||||
}
|
||||
actual := resp.Intentions[0]
|
||||
actual.CreateIndex, actual.ModifyIndex = 0, 0
|
||||
if !reflect.DeepEqual(actual, ixn.Intention) {
|
||||
t.Fatalf("bad: %v", actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shouldn't be able to update a non-existent intention
|
||||
func TestIntentionApply_updateNonExist(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir1, s1 := testServer(t)
|
||||
defer os.RemoveAll(dir1)
|
||||
defer s1.Shutdown()
|
||||
codec := rpcClient(t, s1)
|
||||
defer codec.Close()
|
||||
|
||||
testrpc.WaitForLeader(t, s1.RPC, "dc1")
|
||||
|
||||
// Setup a basic record to create
|
||||
ixn := structs.IntentionRequest{
|
||||
Datacenter: "dc1",
|
||||
Op: structs.IntentionOpUpdate,
|
||||
Intention: &structs.Intention{
|
||||
ID: generateUUID(),
|
||||
SourceName: "test",
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
|
||||
// Create
|
||||
err := msgpackrpc.CallWithCodec(codec, "Intention.Apply", &ixn, &reply)
|
||||
if err == nil || !strings.Contains(err.Error(), "Cannot modify non-existent intention") {
|
||||
t.Fatalf("bad: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntentionList(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir1, s1 := testServer(t)
|
||||
|
|
Loading…
Reference in New Issue