rpc: Generate node identities with node RPC handlers when needed. (#26165)

When a Nomad client register or re-registers, the RPC handler will
generate and return a node identity if required. When an identity
is generated, the signing key ID will be stored within the node
object, to ensure a root key is not deleted until it is not used.

During normal client operation it will periodically heartbeat to
the Nomad servers to indicate aliveness. The RPC handler that
is used for this action has also been updated to conditionally
perform identity generation. Performing it here means no extra RPC
handlers are required and we inherit the jitter in identity
generation from the heartbeat mechanism.

The identity generation check methods are performed from the RPC
request arguments, so they a scoped to the required behaviour and
can handle the nuance of each RPC. Failure to generate an identity
is considered terminal to the RPC call. The client will include
behaviour to retry this error which is always caused by the
encrypter not being ready unless the servers keyring has been
corrupted.
This commit is contained in:
James Rasell
2025-07-01 17:07:21 +02:00
committed by GitHub
parent 4393c0e76b
commit d5b2d5078b
25 changed files with 1344 additions and 103 deletions

View File

@@ -703,6 +703,7 @@ func TestClient_SaveRestoreState(t *testing.T) {
s1, _, cleanupS1 := testServer(t, nil)
t.Cleanup(cleanupS1)
testutil.WaitForLeader(t, s1.RPC)
testutil.WaitForKeyring(t, s1.RPC, s1.Region())
c1, cleanupC1 := TestClient(t, func(c *config.Config) {
c.DevMode = false

View File

@@ -29,6 +29,7 @@ func TestClient_SelfDrainConfig(t *testing.T) {
srv, _, cleanupSRV := testServer(t, nil)
defer cleanupSRV()
testutil.WaitForLeader(t, srv.RPC)
testutil.WaitForKeyring(t, srv.RPC, srv.Region())
c1, cleanupC1 := TestClient(t, func(c *config.Config) {
c.RPCHandler = srv
@@ -81,6 +82,7 @@ func TestClient_SelfDrain_FailLocal(t *testing.T) {
srv, _, cleanupSRV := testServer(t, nil)
defer cleanupSRV()
testutil.WaitForLeader(t, srv.RPC)
testutil.WaitForKeyring(t, srv.RPC, srv.Region())
c1, cleanupC1 := TestClient(t, func(c *config.Config) {
c.RPCHandler = srv