Allow dialer to re-establish terminated peering (#16776)
Currently, if an acceptor peer deletes a peering the dialer's peering will eventually get to a "terminated" state. If the two clusters need to be re-peered the acceptor will re-generate the token but the dialer will encounter this error on the call to establish: "failed to get addresses to dial peer: failed to refresh peer server addresses, will continue to use initial addresses: there is no active peering for "<<<ID>>>"" This is because in `exchangeSecret().GetDialAddresses()` we will get an error if fetching addresses for an inactive peering. The peering shows up as inactive at this point because of the existing terminated state. Rather than checking whether a peering is active we can instead check whether it was deleted. This way users do not need to delete terminated peerings in the dialing cluster before re-establishing them.
This commit is contained in:
parent
bef1aafbf9
commit
04e6e79b09
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
peering: allow re-establishing terminated peering from new token without deleting existing peering first.
|
||||||
|
```
|
|
@ -472,6 +472,30 @@ func TestLeader_PeeringSync_Lifecycle_ServerDeletion(t *testing.T) {
|
||||||
require.NoError(r, err)
|
require.NoError(r, err)
|
||||||
require.Equal(r, pbpeering.PeeringState_TERMINATED, peering.State)
|
require.Equal(r, pbpeering.PeeringState_TERMINATED, peering.State)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Re-establishing a peering terminated by the acceptor should be possible
|
||||||
|
// without needing to delete the terminated peering first.
|
||||||
|
ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
t.Cleanup(cancel)
|
||||||
|
|
||||||
|
req = pbpeering.GenerateTokenRequest{
|
||||||
|
PeerName: "my-peer-dialer",
|
||||||
|
}
|
||||||
|
resp, err = peeringClient.GenerateToken(ctx, &req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
tokenJSON, err = base64.StdEncoding.DecodeString(resp.PeeringToken)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
token = structs.PeeringToken{}
|
||||||
|
require.NoError(t, json.Unmarshal(tokenJSON, &token))
|
||||||
|
|
||||||
|
establishReq = pbpeering.EstablishRequest{
|
||||||
|
PeerName: "my-peer-acceptor",
|
||||||
|
PeeringToken: resp.PeeringToken,
|
||||||
|
}
|
||||||
|
_, err = dialerClient.Establish(ctx, &establishReq)
|
||||||
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLeader_PeeringSync_FailsForTLSError(t *testing.T) {
|
func TestLeader_PeeringSync_FailsForTLSError(t *testing.T) {
|
||||||
|
|
|
@ -150,8 +150,11 @@ func (b *PeeringBackend) fetchPeerServerAddresses(ws memdb.WatchSet, peerID stri
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to fetch peer %q: %w", peerID, err)
|
return nil, fmt.Errorf("failed to fetch peer %q: %w", peerID, err)
|
||||||
}
|
}
|
||||||
if !peering.IsActive() {
|
if peering == nil {
|
||||||
return nil, fmt.Errorf("there is no active peering for %q", peerID)
|
return nil, fmt.Errorf("unknown peering %q", peerID)
|
||||||
|
}
|
||||||
|
if peering.DeletedAt != nil && !structs.IsZeroProtoTime(peering.DeletedAt) {
|
||||||
|
return nil, fmt.Errorf("peering %q was deleted", peerID)
|
||||||
}
|
}
|
||||||
return bufferFromAddresses(peering.GetAddressesToDial())
|
return bufferFromAddresses(peering.GetAddressesToDial())
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,7 +256,7 @@ func TestPeeringBackend_GetDialAddresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
peerID: acceptorPeerID,
|
peerID: acceptorPeerID,
|
||||||
expect: expectation{
|
expect: expectation{
|
||||||
err: fmt.Sprintf(`there is no active peering for %q`, acceptorPeerID),
|
err: fmt.Sprintf(`unknown peering %q`, acceptorPeerID),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -387,6 +387,25 @@ func TestPeeringBackend_GetDialAddresses(t *testing.T) {
|
||||||
gatewayAddrs: []string{"5.6.7.8:8443", "6.7.8.9:8443"},
|
gatewayAddrs: []string{"5.6.7.8:8443", "6.7.8.9:8443"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "addresses are returned if the peering is marked as terminated",
|
||||||
|
setup: func(store *state.Store) {
|
||||||
|
require.NoError(t, store.PeeringWrite(5, &pbpeering.PeeringWriteRequest{
|
||||||
|
Peering: &pbpeering.Peering{
|
||||||
|
Name: "dialer",
|
||||||
|
ID: dialerPeerID,
|
||||||
|
PeerServerAddresses: []string{"1.2.3.4:8502", "2.3.4.5:8503"},
|
||||||
|
State: pbpeering.PeeringState_TERMINATED,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
peerID: dialerPeerID,
|
||||||
|
expect: expectation{
|
||||||
|
// Gateways come first, and we use their LAN addresses since this is for outbound communication.
|
||||||
|
addrs: []string{"5.6.7.8:8443", "6.7.8.9:8443", "1.2.3.4:8502", "2.3.4.5:8503"},
|
||||||
|
gatewayAddrs: []string{"5.6.7.8:8443", "6.7.8.9:8443"},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "addresses are not returned if the peering is deleted",
|
name: "addresses are not returned if the peering is deleted",
|
||||||
setup: func(store *state.Store) {
|
setup: func(store *state.Store) {
|
||||||
|
@ -404,7 +423,7 @@ func TestPeeringBackend_GetDialAddresses(t *testing.T) {
|
||||||
},
|
},
|
||||||
peerID: dialerPeerID,
|
peerID: dialerPeerID,
|
||||||
expect: expectation{
|
expect: expectation{
|
||||||
err: fmt.Sprintf(`there is no active peering for %q`, dialerPeerID),
|
err: fmt.Sprintf(`peering %q was deleted`, dialerPeerID),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue