peering: prevent peering in same partition (#13851)

Co-authored-by: Chris S. Kim <ckim@hashicorp.com>
This commit is contained in:
alex 2022-07-25 18:00:48 -07:00 committed by GitHub
parent 3548a396ad
commit 437a28d18a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 0 deletions

View File

@ -346,6 +346,11 @@ func (s *Server) Establish(
return nil, err return nil, err
} }
// we don't want to default req.Partition unlike because partitions are empty in OSS
if err := s.validatePeeringInPartition(tok.PeerID, req.Partition); err != nil {
return nil, err
}
var id string var id string
if peering == nil { if peering == nil {
id, err = lib.GenerateUUID(s.Backend.CheckPeeringUUID) id, err = lib.GenerateUUID(s.Backend.CheckPeeringUUID)
@ -395,6 +400,22 @@ func (s *Server) Establish(
return resp, nil return resp, nil
} }
// validatePeeringInPartition makes sure that we don't create a peering in the same partition. We validate by looking at
// the remotePeerID from the PeeringToken and looking up for a peering in the partition. If there is one and the
// request partition is the same, then we are attempting to peer within the partition, which we shouldn't.
func (s *Server) validatePeeringInPartition(remotePeerID, partition string) error {
_, peering, err := s.Backend.Store().PeeringReadByID(nil, remotePeerID)
if err != nil {
return fmt.Errorf("cannot read peering by ID: %w", err)
}
if peering != nil && peering.Partition == partition {
return fmt.Errorf("cannot create a peering within the same partition (ENT) or cluster (OSS)")
}
return nil
}
// OPTIMIZE: Handle blocking queries // OPTIMIZE: Handle blocking queries
func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequest) (*pbpeering.PeeringReadResponse, error) { func (s *Server) PeeringRead(ctx context.Context, req *pbpeering.PeeringReadRequest) (*pbpeering.PeeringReadResponse, error) {
if !s.Config.PeeringEnabled { if !s.Config.PeeringEnabled {

View File

@ -314,6 +314,30 @@ func TestPeeringService_Establish(t *testing.T) {
} }
} }
// We define a valid peering by a peering that does not occur over the same server addresses
func TestPeeringService_Establish_validPeeringInPartition(t *testing.T) {
// TODO(peering): see note on newTestServer, refactor to not use this
s := newTestServer(t, nil)
client := pbpeering.NewPeeringServiceClient(s.ClientConn(t))
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
t.Cleanup(cancel)
req := pbpeering.GenerateTokenRequest{PeerName: "peerOne"}
resp, err := client.GenerateToken(ctx, &req)
require.NoError(t, err)
require.NotEmpty(t, resp)
establishReq := &pbpeering.EstablishRequest{
PeerName: "peerTwo",
PeeringToken: resp.PeeringToken}
respE, errE := client.Establish(ctx, establishReq)
require.Error(t, errE)
require.Contains(t, errE.Error(), "cannot create a peering within the same partition (ENT) or cluster (OSS)")
require.Nil(t, respE)
}
func TestPeeringService_Establish_ACLEnforcement(t *testing.T) { func TestPeeringService_Establish_ACLEnforcement(t *testing.T) {
validToken := peering.TestPeeringToken("83474a06-cca4-4ff4-99a4-4152929c8160") validToken := peering.TestPeeringToken("83474a06-cca4-4ff4-99a4-4152929c8160")
validTokenJSON, _ := json.Marshal(&validToken) validTokenJSON, _ := json.Marshal(&validToken)